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

Convert realm data propagation to more correctly use Live<T>

wip
This commit is contained in:
Dean Herbert 2022-07-27 17:17:43 +09:00
parent 41393616d8
commit 438067a18b
12 changed files with 54 additions and 40 deletions

View File

@ -147,10 +147,10 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(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)); AddAssert("button is plus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.PlusSquare));
AddStep("add beatmap to collection", () => getFirstCollection().BeatmapMD5Hashes.Add(Beatmap.Value.BeatmapInfo.MD5Hash)); AddStep("add beatmap to collection", () => Realm.Write(r => getFirstCollection().BeatmapMD5Hashes.Add(Beatmap.Value.BeatmapInfo.MD5Hash)));
AddAssert("button is minus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.MinusSquare)); AddAssert("button is minus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.MinusSquare));
AddStep("remove beatmap from collection", () => getFirstCollection().BeatmapMD5Hashes.Clear()); AddStep("remove beatmap from collection", () => Realm.Write(r => getFirstCollection().BeatmapMD5Hashes.Clear()));
AddAssert("button is plus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.PlusSquare)); AddAssert("button is plus", () => getAddOrRemoveButton(1).Icon.Equals(FontAwesome.Solid.PlusSquare));
} }
@ -178,7 +178,7 @@ namespace osu.Game.Tests.Visual.SongSelect
{ {
addExpandHeaderStep(); addExpandHeaderStep();
AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "1")))); AddStep("add collection", () => Realm.Write(r => r.Add(new BeatmapCollection(name: "1", new List<string> { "abc" }))));
AddStep("select collection", () => AddStep("select collection", () =>
{ {
InputManager.MoveMouseTo(getCollectionDropdownItems().ElementAt(1)); InputManager.MoveMouseTo(getCollectionDropdownItems().ElementAt(1));
@ -193,7 +193,7 @@ namespace osu.Game.Tests.Visual.SongSelect
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
AddAssert("collection filter still selected", () => control.CreateCriteria().Collection?.Name == "1"); AddAssert("collection filter still selected", () => control.CreateCriteria().CollectionBeatmapMD5Hashes.Any());
} }
private BeatmapCollection getFirstCollection() => Realm.Run(r => r.All<BeatmapCollection>().First()); private BeatmapCollection getFirstCollection() => Realm.Run(r => r.All<BeatmapCollection>().First());

View File

@ -38,7 +38,7 @@ namespace osu.Game.Collections
set => current.Current = value; set => current.Current = value;
} }
private readonly IBindableList<BeatmapCollection> collections = new BindableList<BeatmapCollection>(); private readonly IBindableList<Live<BeatmapCollection>> collections = new BindableList<Live<BeatmapCollection>>();
private readonly IBindableList<string> beatmaps = new BindableList<string>(); private readonly IBindableList<string> beatmaps = new BindableList<string>();
private readonly BindableList<CollectionFilterMenuItem> filters = new BindableList<CollectionFilterMenuItem>(); private readonly BindableList<CollectionFilterMenuItem> filters = new BindableList<CollectionFilterMenuItem>();
@ -114,6 +114,7 @@ namespace osu.Game.Collections
/// </summary> /// </summary>
private void filterBeatmapsChanged(object sender, NotifyCollectionChangedEventArgs e) private void filterBeatmapsChanged(object sender, NotifyCollectionChangedEventArgs e)
{ {
// TODO: fuck this shit right off
// The filtered beatmaps have changed, without the filter having changed itself. So a change in filter must be notified. // The filtered beatmaps have changed, without the filter having changed itself. So a change in filter must be notified.
// Note that this does NOT propagate to bound bindables, so the FilterControl must bind directly to the value change event of this bindable. // Note that this does NOT propagate to bound bindables, so the FilterControl must bind directly to the value change event of this bindable.
Current.TriggerChange(); Current.TriggerChange();
@ -200,7 +201,7 @@ namespace osu.Game.Collections
private IDisposable? realmSubscription; private IDisposable? realmSubscription;
private BeatmapCollection? collection => Item.Collection; private Live<BeatmapCollection>? collection => Item.Collection;
public CollectionDropdownMenuItem(MenuItem item) public CollectionDropdownMenuItem(MenuItem item)
: base(item) : base(item)
@ -257,7 +258,7 @@ namespace osu.Game.Collections
{ {
Debug.Assert(collection != null); Debug.Assert(collection != null);
beatmapInCollection = collection.BeatmapMD5Hashes.Contains(beatmap.Value.BeatmapInfo.MD5Hash); beatmapInCollection = collection.PerformRead(c => c.BeatmapMD5Hashes.Contains(beatmap.Value.BeatmapInfo.MD5Hash));
addOrRemoveButton.Enabled.Value = !beatmap.IsDefault; addOrRemoveButton.Enabled.Value = !beatmap.IsDefault;
addOrRemoveButton.Icon = beatmapInCollection ? FontAwesome.Solid.MinusSquare : FontAwesome.Solid.PlusSquare; addOrRemoveButton.Icon = beatmapInCollection ? FontAwesome.Solid.MinusSquare : FontAwesome.Solid.PlusSquare;
@ -284,10 +285,10 @@ namespace osu.Game.Collections
{ {
Debug.Assert(collection != null); Debug.Assert(collection != null);
realm.Write(r => collection.PerformWrite(c =>
{ {
if (!collection.BeatmapMD5Hashes.Remove(beatmap.Value.BeatmapInfo.MD5Hash)) if (!c.BeatmapMD5Hashes.Remove(beatmap.Value.BeatmapInfo.MD5Hash))
collection.BeatmapMD5Hashes.Add(beatmap.Value.BeatmapInfo.MD5Hash); c.BeatmapMD5Hashes.Add(beatmap.Value.BeatmapInfo.MD5Hash);
}); });
} }

View File

@ -3,6 +3,7 @@
using System; using System;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Game.Database;
namespace osu.Game.Collections namespace osu.Game.Collections
{ {
@ -15,7 +16,7 @@ namespace osu.Game.Collections
/// The collection to filter beatmaps from. /// The collection to filter beatmaps from.
/// May be null to not filter by collection (include all beatmaps). /// May be null to not filter by collection (include all beatmaps).
/// </summary> /// </summary>
public readonly BeatmapCollection? Collection; public readonly Live<BeatmapCollection>? Collection;
/// <summary> /// <summary>
/// The name of the collection. /// The name of the collection.
@ -26,10 +27,10 @@ namespace osu.Game.Collections
/// Creates a new <see cref="CollectionFilterMenuItem"/>. /// Creates a new <see cref="CollectionFilterMenuItem"/>.
/// </summary> /// </summary>
/// <param name="collection">The collection to filter beatmaps from.</param> /// <param name="collection">The collection to filter beatmaps from.</param>
public CollectionFilterMenuItem(BeatmapCollection? collection) public CollectionFilterMenuItem(Live<BeatmapCollection>? collection)
{ {
Collection = collection; Collection = collection;
CollectionName = new Bindable<string>(collection?.Name ?? "All beatmaps"); CollectionName = new Bindable<string>(collection?.PerformRead(c => c.Name) ?? "All beatmaps");
} }
// TODO: track name changes i guess? // TODO: track name changes i guess?

View File

@ -2,22 +2,26 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
namespace osu.Game.Collections namespace osu.Game.Collections
{ {
public class CollectionToggleMenuItem : ToggleMenuItem public class CollectionToggleMenuItem : ToggleMenuItem
{ {
public CollectionToggleMenuItem(BeatmapCollection collection, IBeatmapInfo beatmap) public CollectionToggleMenuItem(Live<BeatmapCollection> collection, IBeatmapInfo beatmap)
: base(collection.Name, MenuItemType.Standard, state => : base(collection.PerformRead(c => c.Name), MenuItemType.Standard, state =>
{
collection.PerformWrite(c =>
{ {
if (state) if (state)
collection.BeatmapMD5Hashes.Add(beatmap.MD5Hash); c.BeatmapMD5Hashes.Add(beatmap.MD5Hash);
else else
collection.BeatmapMD5Hashes.Remove(beatmap.MD5Hash); c.BeatmapMD5Hashes.Remove(beatmap.MD5Hash);
});
}) })
{ {
State.Value = collection.BeatmapMD5Hashes.Contains(beatmap.MD5Hash); State.Value = collection.PerformRead(c => c.BeatmapMD5Hashes.Contains(beatmap.MD5Hash));
} }
} }
} }

View File

@ -5,6 +5,7 @@
using JetBrains.Annotations; using JetBrains.Annotations;
using osu.Game.Collections; using osu.Game.Collections;
using osu.Game.Database;
namespace osu.Game.Overlays.Music namespace osu.Game.Overlays.Music
{ {
@ -19,6 +20,6 @@ namespace osu.Game.Overlays.Music
/// The collection to filter beatmaps from. /// The collection to filter beatmaps from.
/// </summary> /// </summary>
[CanBeNull] [CanBeNull]
public BeatmapCollection Collection; public Live<BeatmapCollection> Collection;
} }
} }

View File

@ -31,14 +31,16 @@ namespace osu.Game.Overlays.Music
{ {
var items = (SearchContainer<RearrangeableListItem<Live<BeatmapSetInfo>>>)ListContainer; var items = (SearchContainer<RearrangeableListItem<Live<BeatmapSetInfo>>>)ListContainer;
string[] currentCollectionHashes = criteria.Collection?.PerformRead(c => c.BeatmapMD5Hashes.ToArray());
foreach (var item in items.OfType<PlaylistItem>()) foreach (var item in items.OfType<PlaylistItem>())
{ {
if (criteria.Collection == null) if (currentCollectionHashes == null)
item.InSelectedCollection = true; item.InSelectedCollection = true;
else else
{ {
item.InSelectedCollection = item.Model.Value.Beatmaps.Select(b => b.MD5Hash) item.InSelectedCollection = item.Model.Value.Beatmaps.Select(b => b.MD5Hash)
.Any(criteria.Collection.BeatmapMD5Hashes.Contains); .Any(currentCollectionHashes.Contains);
} }
} }

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) if (beatmaps.QueryBeatmap(b => b.OnlineID == beatmap.OnlineID) is BeatmapInfo local && !local.BeatmapSet.AsNonNull().DeletePending)
{ {
var collectionItems = realm.Realm.All<BeatmapCollection>().Select(c => new CollectionToggleMenuItem(c, beatmap)).Cast<OsuMenuItem>().ToList(); var collectionItems = realm.Realm.All<BeatmapCollection>().Select(c => new CollectionToggleMenuItem(c.ToLive(realm), beatmap)).Cast<OsuMenuItem>().ToList();
if (manageCollectionsDialog != null) if (manageCollectionsDialog != null)
collectionItems.Add(new OsuMenuItem("Manage...", MenuItemType.Standard, manageCollectionsDialog.Show)); collectionItems.Add(new OsuMenuItem("Manage...", MenuItemType.Standard, manageCollectionsDialog.Show));

View File

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

View File

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

View File

@ -254,24 +254,29 @@ namespace osu.Game.Screens.Select.Carousel
else else
state = TernaryState.False; state = TernaryState.False;
var liveCollection = collection.ToLive(realm);
return new TernaryStateToggleMenuItem(collection.Name, MenuItemType.Standard, s => return new TernaryStateToggleMenuItem(collection.Name, MenuItemType.Standard, s =>
{
liveCollection.PerformWrite(c =>
{ {
foreach (var b in beatmapSet.Beatmaps) foreach (var b in beatmapSet.Beatmaps)
{ {
switch (s) switch (s)
{ {
case TernaryState.True: case TernaryState.True:
if (collection.BeatmapMD5Hashes.Contains(b.MD5Hash)) if (c.BeatmapMD5Hashes.Contains(b.MD5Hash))
continue; continue;
collection.BeatmapMD5Hashes.Add(b.MD5Hash); c.BeatmapMD5Hashes.Add(b.MD5Hash);
break; break;
case TernaryState.False: case TernaryState.False:
collection.BeatmapMD5Hashes.Remove(b.MD5Hash); c.BeatmapMD5Hashes.Remove(b.MD5Hash);
break; break;
} }
} }
});
}) })
{ {
State = { Value = state } State = { Value = state }

View File

@ -49,7 +49,7 @@ namespace osu.Game.Screens.Select
Sort = sortMode.Value, Sort = sortMode.Value,
AllowConvertedBeatmaps = showConverted.Value, AllowConvertedBeatmaps = showConverted.Value,
Ruleset = ruleset.Value, Ruleset = ruleset.Value,
Collection = collectionDropdown?.Current.Value?.Collection CollectionBeatmapMD5Hashes = collectionDropdown?.Current.Value?.Collection?.PerformRead(c => c.BeatmapMD5Hashes)
}; };
if (!minimumStars.IsDefault) if (!minimumStars.IsDefault)

View File

@ -68,10 +68,10 @@ namespace osu.Game.Screens.Select
} }
/// <summary> /// <summary>
/// The collection to filter beatmaps from. /// Hashes from the <see cref="BeatmapCollection"/> to filter to.
/// </summary> /// </summary>
[CanBeNull] [CanBeNull]
public BeatmapCollection Collection; public IEnumerable<string> CollectionBeatmapMD5Hashes { get; set; }
[CanBeNull] [CanBeNull]
public IRulesetFilterCriteria RulesetCriteria { get; set; } public IRulesetFilterCriteria RulesetCriteria { get; set; }