1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 09:27:29 +08:00

Replace BeatmapCollection with RealmBeatmapCollection

This commit is contained in:
Dean Herbert 2022-07-27 16:46:23 +09:00
parent 9c543fef48
commit 41393616d8
18 changed files with 158 additions and 180 deletions

View File

@ -12,7 +12,7 @@ using NUnit.Framework;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Collections;
using osu.Game.Database;
using osu.Game.Tests.Resources;
@ -34,7 +34,7 @@ namespace osu.Game.Tests.Collections.IO
osu.Realm.Run(realm =>
{
var collections = realm.All<RealmBeatmapCollection>().ToList();
var collections = realm.All<BeatmapCollection>().ToList();
Assert.That(collections.Count, Is.Zero);
});
}
@ -58,7 +58,7 @@ namespace osu.Game.Tests.Collections.IO
osu.Realm.Run(realm =>
{
var collections = realm.All<RealmBeatmapCollection>().ToList();
var collections = realm.All<BeatmapCollection>().ToList();
Assert.That(collections.Count, Is.EqualTo(2));
// Even with no beatmaps imported, collections are tracking the hashes and will continue to.
@ -93,7 +93,7 @@ namespace osu.Game.Tests.Collections.IO
osu.Realm.Run(realm =>
{
var collections = realm.All<RealmBeatmapCollection>().ToList();
var collections = realm.All<BeatmapCollection>().ToList();
Assert.That(collections.Count, Is.EqualTo(2));
@ -141,7 +141,7 @@ namespace osu.Game.Tests.Collections.IO
Assert.That(exceptionThrown, Is.False);
osu.Realm.Run(realm =>
{
var collections = realm.All<RealmBeatmapCollection>().ToList();
var collections = realm.All<BeatmapCollection>().ToList();
Assert.That(collections.Count, Is.EqualTo(0));
});
}
@ -171,7 +171,7 @@ namespace osu.Game.Tests.Collections.IO
// ReSharper disable once MethodHasAsyncOverload
osu.Realm.Write(realm =>
{
var collections = realm.All<RealmBeatmapCollection>().ToList();
var collections = realm.All<BeatmapCollection>().ToList();
// Move first beatmap from second collection into the first.
collections[0].BeatmapMD5Hashes.Add(collections[1].BeatmapMD5Hashes[0]);
@ -196,7 +196,7 @@ namespace osu.Game.Tests.Collections.IO
osu.Realm.Run(realm =>
{
var collections = realm.All<RealmBeatmapCollection>().ToList();
var collections = realm.All<BeatmapCollection>().ToList();
Assert.That(collections.Count, Is.EqualTo(2));
Assert.That(collections[0].Name, Is.EqualTo("First"));

View File

@ -51,7 +51,7 @@ namespace osu.Game.Tests.Visual.Collections
[SetUp]
public void SetUp() => Schedule(() =>
{
Realm.Write(r => r.RemoveAll<RealmBeatmapCollection>());
Realm.Write(r => r.RemoveAll<BeatmapCollection>());
Child = dialog = new ManageCollectionsDialog();
});
@ -77,11 +77,11 @@ namespace osu.Game.Tests.Visual.Collections
[Test]
public void TestAddCollectionExternal()
{
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "First collection"))));
AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "First collection"))));
assertCollectionCount(1);
assertCollectionName(0, "First collection");
AddStep("add another collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "Second collection"))));
AddStep("add another collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "Second collection"))));
assertCollectionCount(2);
assertCollectionName(1, "Second collection");
}
@ -110,7 +110,7 @@ namespace osu.Game.Tests.Visual.Collections
});
// Done directly via the collection since InputManager methods cannot add text to textbox...
AddStep("change collection name", () => placeholderItem.Model.Name = "a");
AddStep("change collection name", () => placeholderItem.Model.PerformWrite(c => c.Name = "a"));
assertCollectionCount(1);
AddAssert("collection now exists", () => placeholderItem.Model.IsManaged);
@ -120,7 +120,7 @@ namespace osu.Game.Tests.Visual.Collections
[Test]
public void TestRemoveCollectionExternal()
{
RealmBeatmapCollection first = null!;
BeatmapCollection first = null!;
AddStep("add two collections", () =>
{
@ -128,13 +128,13 @@ namespace osu.Game.Tests.Visual.Collections
{
r.Add(new[]
{
first = new RealmBeatmapCollection(name: "1"),
new RealmBeatmapCollection(name: "2"),
first = new BeatmapCollection(name: "1"),
new BeatmapCollection(name: "2"),
});
});
});
AddStep("change first collection name", () => Realm.Write(r => r.Remove(first)));
AddStep("remove first collection", () => Realm.Write(r => r.Remove(first)));
assertCollectionCount(1);
assertCollectionName(0, "2");
}
@ -154,8 +154,8 @@ namespace osu.Game.Tests.Visual.Collections
});
AddStep("add two collections with same name", () => Realm.Write(r => r.Add(new[]
{
new RealmBeatmapCollection(name: "1"),
new RealmBeatmapCollection(name: "1")
new BeatmapCollection(name: "1"),
new BeatmapCollection(name: "1")
{
BeatmapMD5Hashes = { beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0].MD5Hash }
},
@ -167,8 +167,8 @@ namespace osu.Game.Tests.Visual.Collections
{
AddStep("add two collections", () => Realm.Write(r => r.Add(new[]
{
new RealmBeatmapCollection(name: "1"),
new RealmBeatmapCollection(name: "2")
new BeatmapCollection(name: "1"),
new BeatmapCollection(name: "2")
{
BeatmapMD5Hashes = { beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0].MD5Hash }
},
@ -207,7 +207,7 @@ namespace osu.Game.Tests.Visual.Collections
{
AddStep("add collection", () => Realm.Write(r => r.Add(new[]
{
new RealmBeatmapCollection(name: "1")
new BeatmapCollection(name: "1")
{
BeatmapMD5Hashes = { beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0].MD5Hash }
},
@ -234,7 +234,7 @@ namespace osu.Game.Tests.Visual.Collections
[Test]
public void TestCollectionRenamedExternal()
{
RealmBeatmapCollection first = null!;
BeatmapCollection first = null!;
AddStep("add two collections", () =>
{
@ -242,8 +242,8 @@ namespace osu.Game.Tests.Visual.Collections
{
r.Add(new[]
{
first = new RealmBeatmapCollection(name: "1"),
new RealmBeatmapCollection(name: "2"),
first = new BeatmapCollection(name: "1"),
new BeatmapCollection(name: "2"),
});
});
});
@ -256,7 +256,7 @@ namespace osu.Game.Tests.Visual.Collections
[Test]
public void TestCollectionRenamedOnTextChange()
{
RealmBeatmapCollection first = null!;
BeatmapCollection first = null!;
AddStep("add two collections", () =>
{
@ -264,8 +264,8 @@ namespace osu.Game.Tests.Visual.Collections
{
r.Add(new[]
{
first = new RealmBeatmapCollection(name: "1"),
new RealmBeatmapCollection(name: "2"),
first = new BeatmapCollection(name: "1"),
new BeatmapCollection(name: "2"),
});
});
});

View File

@ -48,7 +48,7 @@ namespace osu.Game.Tests.Visual.SongSelect
[SetUp]
public void SetUp() => Schedule(() =>
{
Realm.Write(r => r.RemoveAll<RealmBeatmapCollection>());
Realm.Write(r => r.RemoveAll<BeatmapCollection>());
Child = control = new FilterControl
{
@ -69,8 +69,8 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test]
public void TestCollectionAddedToDropdown()
{
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "1"))));
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "2"))));
AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "1"))));
AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "2"))));
assertCollectionDropdownContains("1");
assertCollectionDropdownContains("2");
}
@ -78,10 +78,10 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test]
public void TestCollectionRemovedFromDropdown()
{
var first = new RealmBeatmapCollection(name: "1");
var first = new BeatmapCollection(name: "1");
AddStep("add collection", () => Realm.Write(r => r.Add(first)));
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "2"))));
AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "2"))));
AddStep("remove collection", () => Realm.Write(r => r.Remove(first)));
assertCollectionDropdownContains("1", false);
@ -91,7 +91,7 @@ namespace osu.Game.Tests.Visual.SongSelect
[Test]
public void TestCollectionRenamed()
{
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "1"))));
AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "1"))));
AddStep("select collection", () =>
{
var dropdown = control.ChildrenOfType<CollectionFilterDropdown>().Single();
@ -118,7 +118,7 @@ namespace osu.Game.Tests.Visual.SongSelect
public void TestCollectionFilterHasAddButton()
{
addExpandHeaderStep();
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "1"))));
AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "1"))));
AddStep("hover collection", () => InputManager.MoveMouseTo(getAddOrRemoveButton(1)));
AddAssert("collection has add button", () => getAddOrRemoveButton(1).IsPresent);
}
@ -128,7 +128,7 @@ namespace osu.Game.Tests.Visual.SongSelect
{
addExpandHeaderStep();
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "1"))));
AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "1"))));
AddStep("select available beatmap", () => Beatmap.Value = beatmapManager.GetWorkingBeatmap(beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0]));
AddAssert("button enabled", () => getAddOrRemoveButton(1).Enabled.Value);
@ -144,7 +144,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("select available beatmap", () => Beatmap.Value = beatmapManager.GetWorkingBeatmap(beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0]));
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "1"))));
AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "1"))));
AddAssert("button is plus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.PlusSquare));
AddStep("add beatmap to collection", () => getFirstCollection().BeatmapMD5Hashes.Add(Beatmap.Value.BeatmapInfo.MD5Hash));
@ -161,7 +161,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("select available beatmap", () => Beatmap.Value = beatmapManager.GetWorkingBeatmap(beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0]));
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "1"))));
AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "1"))));
AddAssert("button is plus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.PlusSquare));
addClickAddOrRemoveButtonStep(1);
@ -178,7 +178,7 @@ namespace osu.Game.Tests.Visual.SongSelect
{
addExpandHeaderStep();
AddStep("add collection", () => Realm.Write(r => r.Add(new RealmBeatmapCollection(name: "1"))));
AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "1"))));
AddStep("select collection", () =>
{
InputManager.MoveMouseTo(getCollectionDropdownItems().ElementAt(1));
@ -193,10 +193,10 @@ namespace osu.Game.Tests.Visual.SongSelect
InputManager.Click(MouseButton.Left);
});
AddAssert("collection filter still selected", () => control.CreateCriteria().Collection?.Name.Value == "1");
AddAssert("collection filter still selected", () => control.CreateCriteria().Collection?.Name == "1");
}
private RealmBeatmapCollection getFirstCollection() => Realm.Run(r => r.All<RealmBeatmapCollection>().First());
private BeatmapCollection getFirstCollection() => Realm.Run(r => r.All<BeatmapCollection>().First());
private void assertCollectionHeaderDisplays(string collectionName, bool shouldDisplay = true)
=> AddAssert($"collection dropdown header displays '{collectionName}'",

View File

@ -1,40 +0,0 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using osu.Game.Database;
using Realms;
namespace osu.Game.Beatmaps
{
public class RealmBeatmapCollection : RealmObject, IHasGuidPrimaryKey
{
[PrimaryKey]
public Guid ID { get; }
public string Name { get; set; } = string.Empty;
public IList<string> BeatmapMD5Hashes { get; } = null!;
/// <summary>
/// The date when this collection was last modified.
/// </summary>
public DateTimeOffset LastModified { get; set; }
public RealmBeatmapCollection(string? name = null, IList<string>? beatmapMD5Hashes = null)
{
ID = Guid.NewGuid();
Name = name ?? string.Empty;
BeatmapMD5Hashes = beatmapMD5Hashes ?? new List<string>();
LastModified = DateTimeOffset.UtcNow;
}
[UsedImplicitly]
private RealmBeatmapCollection()
{
}
}
}

View File

@ -1,32 +1,50 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable disable
using System;
using osu.Framework.Bindables;
using System.Collections.Generic;
using JetBrains.Annotations;
using osu.Game.Beatmaps;
using osu.Game.Database;
using Realms;
namespace osu.Game.Collections
{
/// <summary>
/// A collection of beatmaps grouped by a name.
/// </summary>
public class BeatmapCollection
public class BeatmapCollection : RealmObject, IHasGuidPrimaryKey
{
[PrimaryKey]
public Guid ID { get; set; }
/// <summary>
/// The collection's name.
/// </summary>
public readonly Bindable<string> Name = new Bindable<string>();
public string Name { get; set; } = string.Empty;
/// <summary>
/// The <see cref="BeatmapInfo.MD5Hash"/>es of beatmaps contained by the collection.
/// </summary>
public readonly BindableList<string> BeatmapHashes = new BindableList<string>();
public IList<string> BeatmapMD5Hashes { get; } = null!;
/// <summary>
/// The date when this collection was last modified.
/// </summary>
public DateTimeOffset LastModifyDate { get; private set; } = DateTimeOffset.UtcNow;
public DateTimeOffset LastModified { get; set; }
public BeatmapCollection(string? name = null, IList<string>? beatmapMD5Hashes = null)
{
ID = Guid.NewGuid();
Name = name ?? string.Empty;
BeatmapMD5Hashes = beatmapMD5Hashes ?? new List<string>();
LastModified = DateTimeOffset.UtcNow;
}
[UsedImplicitly]
private BeatmapCollection()
{
}
}
}

View File

@ -1,12 +1,10 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable disable
using System;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@ -15,6 +13,7 @@ using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osuTK;
@ -43,8 +42,8 @@ namespace osu.Game.Collections
private readonly IBindableList<string> beatmaps = new BindableList<string>();
private readonly BindableList<CollectionFilterMenuItem> filters = new BindableList<CollectionFilterMenuItem>();
[Resolved(CanBeNull = true)]
private ManageCollectionsDialog manageCollectionsDialog { get; set; }
[Resolved]
private ManageCollectionsDialog? manageCollectionsDialog { get; set; }
public CollectionFilterDropdown()
{
@ -81,7 +80,7 @@ namespace osu.Game.Collections
if (ShowManageCollectionsItem)
filters.Add(new ManageCollectionsFilterMenuItem());
Current.Value = filters.SingleOrDefault(f => f.Collection != null && f.Collection == selectedItem) ?? filters[0];
Current.Value = filters.SingleOrDefault(f => f.Collection != null && f.Collection.ID == selectedItem?.ID) ?? filters[0];
}
/// <summary>
@ -92,11 +91,12 @@ namespace osu.Game.Collections
// Binding the beatmaps will trigger a collection change event, which results in an infinite-loop. This is rebound later, when it's safe to do so.
beatmaps.CollectionChanged -= filterBeatmapsChanged;
if (filter.OldValue?.Collection != null)
beatmaps.UnbindFrom(filter.OldValue.Collection.BeatmapHashes);
if (filter.NewValue?.Collection != null)
beatmaps.BindTo(filter.NewValue.Collection.BeatmapHashes);
// TODO: binding with realm
// if (filter.OldValue?.Collection != null)
// beatmaps.UnbindFrom(filter.OldValue.Collection.BeatmapMD5Hashes);
//
// if (filter.NewValue?.Collection != null)
// beatmaps.BindTo(filter.NewValue.Collection.BeatmapMD5Hashes);
beatmaps.CollectionChanged += filterBeatmapsChanged;
@ -187,26 +187,24 @@ namespace osu.Game.Collections
protected class CollectionDropdownMenuItem : OsuDropdownMenu.DrawableOsuDropdownMenuItem
{
[NotNull]
protected new CollectionFilterMenuItem Item => ((DropdownMenuItem<CollectionFilterMenuItem>)base.Item).Value;
[Resolved]
private IBindable<WorkingBeatmap> beatmap { get; set; }
private IBindable<WorkingBeatmap> beatmap { get; set; } = null!;
[CanBeNull]
private readonly BindableList<string> collectionBeatmaps;
[NotNull]
private readonly Bindable<string> collectionName;
private IconButton addOrRemoveButton;
private Content content;
private IconButton addOrRemoveButton = null!;
private Content content = null!;
private bool beatmapInCollection;
private IDisposable? realmSubscription;
private BeatmapCollection? collection => Item.Collection;
public CollectionDropdownMenuItem(MenuItem item)
: base(item)
{
collectionBeatmaps = Item.Collection?.BeatmapHashes.GetBoundCopy();
collectionName = Item.CollectionName.GetBoundCopy();
}
@ -223,14 +221,17 @@ namespace osu.Game.Collections
});
}
[Resolved]
private RealmAccess realm { get; set; } = null!;
protected override void LoadComplete()
{
base.LoadComplete();
if (collectionBeatmaps != null)
if (Item.Collection != null)
{
collectionBeatmaps.CollectionChanged += (_, _) => collectionChanged();
beatmap.BindValueChanged(_ => collectionChanged(), true);
realmSubscription = realm.SubscribeToPropertyChanged(r => r.Find<BeatmapCollection>(Item.Collection.ID), c => c.BeatmapMD5Hashes, _ => hashesChanged());
beatmap.BindValueChanged(_ => hashesChanged(), true);
}
// Although the DrawableMenuItem binds to value changes of the item's text, the item is an internal implementation detail of Dropdown that has no knowledge
@ -252,11 +253,11 @@ namespace osu.Game.Collections
base.OnHoverLost(e);
}
private void collectionChanged()
private void hashesChanged()
{
Debug.Assert(collectionBeatmaps != null);
Debug.Assert(collection != null);
beatmapInCollection = collectionBeatmaps.Contains(beatmap.Value.BeatmapInfo.MD5Hash);
beatmapInCollection = collection.BeatmapMD5Hashes.Contains(beatmap.Value.BeatmapInfo.MD5Hash);
addOrRemoveButton.Enabled.Value = !beatmap.IsDefault;
addOrRemoveButton.Icon = beatmapInCollection ? FontAwesome.Solid.MinusSquare : FontAwesome.Solid.PlusSquare;
@ -273,7 +274,7 @@ namespace osu.Game.Collections
private void updateButtonVisibility()
{
if (collectionBeatmaps == null)
if (collection == null)
addOrRemoveButton.Alpha = 0;
else
addOrRemoveButton.Alpha = IsHovered || IsPreSelected || beatmapInCollection ? 1 : 0;
@ -281,13 +282,22 @@ namespace osu.Game.Collections
private void addOrRemove()
{
Debug.Assert(collectionBeatmaps != null);
Debug.Assert(collection != null);
if (!collectionBeatmaps.Remove(beatmap.Value.BeatmapInfo.MD5Hash))
collectionBeatmaps.Add(beatmap.Value.BeatmapInfo.MD5Hash);
realm.Write(r =>
{
if (!collection.BeatmapMD5Hashes.Remove(beatmap.Value.BeatmapInfo.MD5Hash))
collection.BeatmapMD5Hashes.Add(beatmap.Value.BeatmapInfo.MD5Hash);
});
}
protected override Drawable CreateContent() => content = (Content)base.CreateContent();
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
realmSubscription?.Dispose();
}
}
}
}

View File

@ -1,10 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable disable
using System;
using JetBrains.Annotations;
using osu.Framework.Bindables;
namespace osu.Game.Collections
@ -18,26 +15,26 @@ namespace osu.Game.Collections
/// The collection to filter beatmaps from.
/// May be null to not filter by collection (include all beatmaps).
/// </summary>
[CanBeNull]
public readonly BeatmapCollection Collection;
public readonly BeatmapCollection? Collection;
/// <summary>
/// The name of the collection.
/// </summary>
[NotNull]
public readonly Bindable<string> CollectionName;
/// <summary>
/// Creates a new <see cref="CollectionFilterMenuItem"/>.
/// </summary>
/// <param name="collection">The collection to filter beatmaps from.</param>
public CollectionFilterMenuItem([CanBeNull] BeatmapCollection collection)
public CollectionFilterMenuItem(BeatmapCollection? collection)
{
Collection = collection;
CollectionName = Collection?.Name.GetBoundCopy() ?? new Bindable<string>("All beatmaps");
CollectionName = new Bindable<string>(collection?.Name ?? "All beatmaps");
}
public bool Equals(CollectionFilterMenuItem other)
// TODO: track name changes i guess?
public bool Equals(CollectionFilterMenuItem? other)
{
if (other == null)
return false;
@ -45,7 +42,7 @@ namespace osu.Game.Collections
// collections may have the same name, so compare first on reference equality.
// this relies on the assumption that only one instance of the BeatmapCollection exists game-wide, managed by CollectionManager.
if (Collection != null)
return Collection == other.Collection;
return Collection.ID == other.Collection?.ID;
// fallback to name-based comparison.
// this is required for special dropdown items which don't have a collection (all beatmaps / manage collections items below).

View File

@ -8,7 +8,7 @@ namespace osu.Game.Collections
{
public class CollectionToggleMenuItem : ToggleMenuItem
{
public CollectionToggleMenuItem(RealmBeatmapCollection collection, IBeatmapInfo beatmap)
public CollectionToggleMenuItem(BeatmapCollection collection, IBeatmapInfo beatmap)
: base(collection.Name, MenuItemType.Standard, state =>
{
if (state)

View File

@ -1,19 +1,16 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable disable
using System;
using Humanizer;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
using osu.Game.Overlays.Dialog;
namespace osu.Game.Collections
{
public class DeleteCollectionDialog : PopupDialog
{
public DeleteCollectionDialog(RealmBeatmapCollection collection, Action deleteAction)
public DeleteCollectionDialog(BeatmapCollection collection, Action deleteAction)
{
HeaderText = "Confirm deletion of";
BodyText = $"{collection.Name} ({"beatmap".ToQuantity(collection.BeatmapMD5Hashes.Count)})";

View File

@ -1,35 +1,33 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable disable
using System.Diagnostics;
using System.Linq;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Containers;
using osuTK;
namespace osu.Game.Collections
{
/// <summary>
/// Visualises a list of <see cref="RealmBeatmapCollection"/>s.
/// Visualises a list of <see cref="BeatmapCollection"/>s.
/// </summary>
public class DrawableCollectionList : OsuRearrangeableListContainer<RealmBeatmapCollection>
public class DrawableCollectionList : OsuRearrangeableListContainer<BeatmapCollection>
{
private Scroll scroll;
private Scroll scroll = null!;
protected override ScrollContainer<Drawable> CreateScrollContainer() => scroll = new Scroll();
protected override FillFlowContainer<RearrangeableListItem<RealmBeatmapCollection>> CreateListFillFlowContainer() => new Flow
protected override FillFlowContainer<RearrangeableListItem<BeatmapCollection>> CreateListFillFlowContainer() => new Flow
{
DragActive = { BindTarget = DragActive }
};
// TODO: source from realm
protected override OsuRearrangeableListItem<RealmBeatmapCollection> CreateOsuDrawable(RealmBeatmapCollection item)
protected override OsuRearrangeableListItem<BeatmapCollection> CreateOsuDrawable(BeatmapCollection item)
{
if (item.ID == scroll.PlaceholderItem.Model.ID)
return scroll.ReplacePlaceholder();
@ -49,7 +47,7 @@ namespace osu.Game.Collections
/// <summary>
/// The currently-displayed placeholder item.
/// </summary>
public DrawableCollectionListItem PlaceholderItem { get; private set; }
public DrawableCollectionListItem PlaceholderItem { get; private set; } = null!;
protected override Container<Drawable> Content => content;
private readonly Container content;
@ -79,6 +77,7 @@ namespace osu.Game.Collections
});
ReplacePlaceholder();
Debug.Assert(PlaceholderItem != null);
}
protected override void Update()
@ -98,7 +97,7 @@ namespace osu.Game.Collections
var previous = PlaceholderItem;
placeholderContainer.Clear(false);
placeholderContainer.Add(PlaceholderItem = new DrawableCollectionListItem(new RealmBeatmapCollection(), false));
placeholderContainer.Add(PlaceholderItem = new DrawableCollectionListItem(new BeatmapCollection(), false));
return previous;
}
@ -107,7 +106,7 @@ namespace osu.Game.Collections
/// <summary>
/// The flow of <see cref="DrawableCollectionListItem"/>. Disables layout easing unless a drag is in progress.
/// </summary>
private class Flow : FillFlowContainer<RearrangeableListItem<RealmBeatmapCollection>>
private class Flow : FillFlowContainer<RearrangeableListItem<BeatmapCollection>>
{
public readonly IBindable<bool> DragActive = new Bindable<bool>();

View File

@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable disable
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
@ -12,7 +10,6 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
@ -24,15 +21,15 @@ using osuTK.Graphics;
namespace osu.Game.Collections
{
/// <summary>
/// Visualises a <see cref="RealmBeatmapCollection"/> inside a <see cref="DrawableCollectionList"/>.
/// Visualises a <see cref="BeatmapCollection"/> inside a <see cref="DrawableCollectionList"/>.
/// </summary>
public class DrawableCollectionListItem : OsuRearrangeableListItem<RealmBeatmapCollection>
public class DrawableCollectionListItem : OsuRearrangeableListItem<BeatmapCollection>
{
private const float item_height = 35;
private const float button_width = item_height * 0.75f;
/// <summary>
/// Whether the <see cref="RealmBeatmapCollection"/> currently exists inside realm.
/// Whether the <see cref="BeatmapCollection"/> currently exists inside realm.
/// </summary>
public IBindable<bool> IsCreated => isCreated;
@ -41,9 +38,9 @@ namespace osu.Game.Collections
/// <summary>
/// Creates a new <see cref="DrawableCollectionListItem"/>.
/// </summary>
/// <param name="item">The <see cref="RealmBeatmapCollection"/>.</param>
/// <param name="item">The <see cref="BeatmapCollection"/>.</param>
/// <param name="isCreated">Whether <paramref name="item"/> currently exists inside realm.</param>
public DrawableCollectionListItem(RealmBeatmapCollection item, bool isCreated)
public DrawableCollectionListItem(BeatmapCollection item, bool isCreated)
: base(item)
{
this.isCreated.Value = isCreated;
@ -63,12 +60,15 @@ namespace osu.Game.Collections
{
public readonly Bindable<bool> IsCreated = new Bindable<bool>();
private readonly RealmBeatmapCollection collection;
private readonly BeatmapCollection collection;
private Container textBoxPaddingContainer;
private ItemTextBox textBox;
private Container textBoxPaddingContainer = null!;
private ItemTextBox textBox = null!;
public ItemContent(RealmBeatmapCollection collection)
[Resolved]
private RealmAccess realm { get; set; } = null!;
public ItemContent(BeatmapCollection collection)
{
this.collection = collection;
@ -107,9 +107,6 @@ namespace osu.Game.Collections
};
}
[Resolved]
private RealmAccess realm { get; set; }
protected override void LoadComplete()
{
base.LoadComplete();
@ -156,20 +153,20 @@ namespace osu.Game.Collections
{
public readonly IBindable<bool> IsCreated = new Bindable<bool>();
public Func<Vector2, bool> IsTextBoxHovered;
[Resolved(CanBeNull = true)]
private IDialogOverlay dialogOverlay { get; set; }
public Func<Vector2, bool> IsTextBoxHovered = null!;
[Resolved]
private RealmAccess realmAccess { get; set; }
private IDialogOverlay? dialogOverlay { get; set; }
private readonly RealmBeatmapCollection collection;
[Resolved]
private RealmAccess realmAccess { get; set; } = null!;
private Drawable fadeContainer;
private Drawable background;
private readonly BeatmapCollection collection;
public DeleteButton(RealmBeatmapCollection collection)
private Drawable fadeContainer = null!;
private Drawable background = null!;
public DeleteButton(BeatmapCollection collection)
{
this.collection = collection;
RelativeSizeAxes = Axes.Y;

View File

@ -7,7 +7,7 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
using osu.Framework.Logging;
using osu.Game.Beatmaps;
using osu.Game.Collections;
using osu.Game.IO;
using osu.Game.IO.Legacy;
using osu.Game.Overlays.Notifications;
@ -75,7 +75,7 @@ namespace osu.Game.Database
notification.State = ProgressNotificationState.Completed;
}
private Task importCollections(List<RealmBeatmapCollection> newCollections)
private Task importCollections(List<BeatmapCollection> newCollections)
{
var tcs = new TaskCompletionSource<bool>();
@ -85,7 +85,7 @@ namespace osu.Game.Database
{
foreach (var collection in newCollections)
{
var existing = r.All<RealmBeatmapCollection>().FirstOrDefault(c => c.Name == collection.Name);
var existing = r.All<BeatmapCollection>().FirstOrDefault(c => c.Name == collection.Name);
if (existing != null)
{
@ -111,7 +111,7 @@ namespace osu.Game.Database
return tcs.Task;
}
private List<RealmBeatmapCollection> readCollections(Stream stream, ProgressNotification? notification = null)
private List<BeatmapCollection> readCollections(Stream stream, ProgressNotification? notification = null)
{
if (notification != null)
{
@ -119,7 +119,7 @@ namespace osu.Game.Database
notification.Progress = 0;
}
var result = new List<RealmBeatmapCollection>();
var result = new List<BeatmapCollection>();
try
{
@ -135,7 +135,7 @@ namespace osu.Game.Database
if (notification?.CancellationToken.IsCancellationRequested == true)
return result;
var collection = new RealmBeatmapCollection(sr.ReadString());
var collection = new BeatmapCollection(sr.ReadString());
int mapCount = sr.ReadInt32();
for (int j = 0; j < mapCount; j++)

View File

@ -38,7 +38,7 @@ namespace osu.Game.Overlays.Music
else
{
item.InSelectedCollection = item.Model.Value.Beatmaps.Select(b => b.MD5Hash)
.Any(criteria.Collection.BeatmapHashes.Contains);
.Any(criteria.Collection.BeatmapMD5Hashes.Contains);
}
}

View File

@ -3,7 +3,7 @@
using osu.Framework.Allocation;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
using osu.Game.Collections;
using osu.Game.Database;
using osu.Game.Localisation;
using osu.Game.Overlays.Notifications;
@ -50,7 +50,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
private void deleteAllCollections()
{
realm.Write(r => r.RemoveAll<RealmBeatmapCollection>());
realm.Write(r => r.RemoveAll<BeatmapCollection>());
notificationOverlay.Post(new ProgressCompletionNotification { Text = "Deleted all collections!" });
}
}

View File

@ -499,7 +499,7 @@ namespace osu.Game.Screens.OnlinePlay
{
if (beatmaps.QueryBeatmap(b => b.OnlineID == beatmap.OnlineID) is BeatmapInfo local && !local.BeatmapSet.AsNonNull().DeletePending)
{
var collectionItems = realm.Realm.All<RealmBeatmapCollection>().Select(c => new CollectionToggleMenuItem(c, beatmap)).Cast<OsuMenuItem>().ToList();
var collectionItems = realm.Realm.All<BeatmapCollection>().Select(c => new CollectionToggleMenuItem(c, beatmap)).Cast<OsuMenuItem>().ToList();
if (manageCollectionsDialog != null)
collectionItems.Add(new OsuMenuItem("Manage...", MenuItemType.Standard, manageCollectionsDialog.Show));

View File

@ -76,7 +76,7 @@ namespace osu.Game.Screens.Select.Carousel
}
if (match)
match &= criteria.Collection?.BeatmapHashes.Contains(BeatmapInfo.MD5Hash) ?? true;
match &= criteria.Collection?.BeatmapMD5Hashes.Contains(BeatmapInfo.MD5Hash) ?? true;
if (match && criteria.RulesetCriteria != null)
match &= criteria.RulesetCriteria.Matches(BeatmapInfo);

View File

@ -238,7 +238,7 @@ namespace osu.Game.Screens.Select.Carousel
if (beatmapInfo.OnlineID > 0 && beatmapOverlay != null)
items.Add(new OsuMenuItem("Details...", MenuItemType.Standard, () => beatmapOverlay.FetchAndShowBeatmap(beatmapInfo.OnlineID)));
var collectionItems = realm.Realm.All<RealmBeatmapCollection>().Select(c => new CollectionToggleMenuItem(c, beatmapInfo)).Cast<OsuMenuItem>().ToList();
var collectionItems = realm.Realm.All<BeatmapCollection>().AsEnumerable().Select(c => new CollectionToggleMenuItem(c, beatmapInfo)).Cast<OsuMenuItem>().ToList();
if (manageCollectionsDialog != null)
collectionItems.Add(new OsuMenuItem("Manage...", MenuItemType.Standard, manageCollectionsDialog.Show));

View File

@ -224,7 +224,7 @@ namespace osu.Game.Screens.Select.Carousel
if (beatmapSet.OnlineID > 0 && viewDetails != null)
items.Add(new OsuMenuItem("Details...", MenuItemType.Standard, () => viewDetails(beatmapSet.OnlineID)));
var collectionItems = realm.Realm.All<RealmBeatmapCollection>().AsEnumerable().Select(createCollectionMenuItem).ToList();
var collectionItems = realm.Realm.All<BeatmapCollection>().AsEnumerable().Select(createCollectionMenuItem).ToList();
if (manageCollectionsDialog != null)
collectionItems.Add(new OsuMenuItem("Manage...", MenuItemType.Standard, manageCollectionsDialog.Show));
@ -239,7 +239,7 @@ namespace osu.Game.Screens.Select.Carousel
}
}
private MenuItem createCollectionMenuItem(RealmBeatmapCollection collection)
private MenuItem createCollectionMenuItem(BeatmapCollection collection)
{
Debug.Assert(beatmapSet != null);