From 2789986699b4f4fc77da1fe946af96e617cde4f6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Jan 2022 17:47:46 +0900 Subject: [PATCH 1/5] Use asynchronous loading for beatmap carousel again --- osu.Game/Screens/Select/BeatmapCarousel.cs | 34 ++++++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index ea10e47cff..7f9b19443a 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -181,6 +181,11 @@ namespace osu.Game.Screens.Select RightClickScrollingEnabled.ValueChanged += enabled => Scroll.RightMouseScrollbar = enabled.NewValue; RightClickScrollingEnabled.TriggerChange(); + + using (var realm = realmFactory.CreateContext()) + { + loadBeatmapSets(getBeatmapSets(realm)); + } } [Resolved] @@ -190,7 +195,7 @@ namespace osu.Game.Screens.Select { base.LoadComplete(); - subscriptionSets = realmFactory.Context.All().Where(s => !s.DeletePending && !s.Protected).QueryAsyncWithNotifications(beatmapSetsChanged); + subscriptionSets = getBeatmapSets(realmFactory.Context).QueryAsyncWithNotifications(beatmapSetsChanged); subscriptionBeatmaps = realmFactory.Context.All().Where(b => !b.Hidden).QueryAsyncWithNotifications(beatmapsChanged); // Can't use main subscriptions because we can't lookup deleted indices. @@ -220,8 +225,29 @@ namespace osu.Game.Screens.Select if (changes == null) { - // initial load - loadBeatmapSets(sender); + // During initial population, we must manually account for the fact that our original query was done on an async thread. + // Since then, there may have been imports or deletions. + // Here we manually catch up on any changes. + var populatedSets = new HashSet(); + foreach (var s in beatmapSets) + populatedSets.Add(s.BeatmapSet.ID); + + var realmSets = new HashSet(); + foreach (var s in sender) + realmSets.Add(s.ID); + + foreach (var s in realmSets) + { + if (!populatedSets.Contains(s)) + UpdateBeatmapSet(realmFactory.Context.Find(s)); + } + + foreach (var s in populatedSets) + { + if (!realmSets.Contains(s)) + RemoveBeatmapSet(realmFactory.Context.Find(s)); + } + return; } @@ -242,6 +268,8 @@ namespace osu.Game.Screens.Select UpdateBeatmapSet(sender[i].BeatmapSet); } + private IRealmCollection getBeatmapSets(Realm realm) => realm.All().Where(s => !s.DeletePending && !s.Protected).AsRealmCollection(); + public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet) => Schedule(() => { var existingSet = beatmapSets.FirstOrDefault(b => b.BeatmapSet.Equals(beatmapSet)); From 6c46fd6931a73f3329964c2e97ba5b650832edc5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Jan 2022 00:14:00 +0900 Subject: [PATCH 2/5] Fix some failing tests due to realm beatmaps overwriting test beatmaps --- osu.Game/Screens/Select/BeatmapCarousel.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 7f9b19443a..2dc9bfba0f 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -182,9 +182,10 @@ namespace osu.Game.Screens.Select RightClickScrollingEnabled.ValueChanged += enabled => Scroll.RightMouseScrollbar = enabled.NewValue; RightClickScrollingEnabled.TriggerChange(); - using (var realm = realmFactory.CreateContext()) + if (!loadedTestBeatmaps) { - loadBeatmapSets(getBeatmapSets(realm)); + using (var realm = realmFactory.CreateContext()) + loadBeatmapSets(getBeatmapSets(realm)); } } From 1dabf6c8a52cf176a2acae19e4b571b599b93347 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Jan 2022 16:39:42 +0900 Subject: [PATCH 3/5] Fix `BeatmapCarousel` signalling it is finished loading before catching up on realm changes --- osu.Game/Screens/Select/BeatmapCarousel.cs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 2dc9bfba0f..437567d4b2 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -126,14 +126,8 @@ namespace osu.Game.Screens.Select applyActiveCriteria(false); - // Run on late scheduler want to ensure this runs after all pending UpdateBeatmapSet / RemoveBeatmapSet operations are run. - SchedulerAfterChildren.Add(() => - { - BeatmapSetsChanged?.Invoke(); - BeatmapSetsLoaded = true; - - itemsCache.Invalidate(); - }); + if (loadedTestBeatmaps) + signalBeatmapsLoaded(); } private readonly List visibleItems = new List(); @@ -249,6 +243,7 @@ namespace osu.Game.Screens.Select RemoveBeatmapSet(realmFactory.Context.Find(s)); } + signalBeatmapsLoaded(); return; } @@ -547,6 +542,16 @@ namespace osu.Game.Screens.Select } } + private void signalBeatmapsLoaded() + { + Debug.Assert(BeatmapSetsLoaded == false); + + BeatmapSetsChanged?.Invoke(); + BeatmapSetsLoaded = true; + + itemsCache.Invalidate(); + } + private float? scrollTarget; /// From 3ba712703b7a464c85ffe08927b370c8b8f6514a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Jan 2022 17:50:17 +0900 Subject: [PATCH 4/5] Add a note about hidden beatmap check --- osu.Game/Screens/Select/BeatmapCarousel.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 437567d4b2..d23febf429 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -713,6 +713,11 @@ namespace osu.Game.Screens.Select { beatmapSet = beatmapSet.Detach(); + // This can be moved to the realm query if required using: + // .Filter("DeletePending == false && Protected == false && ALL Beatmaps.Hidden == false") + // + // As long as we are detaching though, it makes more sense to do it here as adding to the realm query has an overhead + // as seen at https://github.com/realm/realm-dotnet/discussions/2773#discussioncomment-2004275. if (beatmapSet.Beatmaps.All(b => b.Hidden)) return null; From b1cf3befa6700c49403d5e628f14da0daa37d7df Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Jan 2022 18:36:20 +0900 Subject: [PATCH 5/5] Fix incorrect query in comment --- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index d23febf429..75ad0511e6 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -714,7 +714,7 @@ namespace osu.Game.Screens.Select beatmapSet = beatmapSet.Detach(); // This can be moved to the realm query if required using: - // .Filter("DeletePending == false && Protected == false && ALL Beatmaps.Hidden == false") + // .Filter("DeletePending == false && Protected == false && ANY Beatmaps.Hidden == false") // // As long as we are detaching though, it makes more sense to do it here as adding to the realm query has an overhead // as seen at https://github.com/realm/realm-dotnet/discussions/2773#discussioncomment-2004275.