From 33060990b7741ec2823a58fb590c4a4da554a8c3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Dec 2021 17:05:00 +0900 Subject: [PATCH] Temporarily disable `WorkingBeatmapCache` and fix multiple invalid data flows --- osu.Game/Beatmaps/WorkingBeatmapCache.cs | 19 ++-------- osu.Game/Overlays/MusicController.cs | 36 ++++++++++--------- osu.Game/Screens/Menu/IntroScreen.cs | 32 +++++++++++++++-- .../Select/Leaderboards/BeatmapLeaderboard.cs | 11 ------ .../Visual/RateAdjustedBeatmapTestScene.cs | 7 ++-- 5 files changed, 57 insertions(+), 48 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmapCache.cs b/osu.Game/Beatmaps/WorkingBeatmapCache.cs index 95983ae052..888851d1e8 100644 --- a/osu.Game/Beatmaps/WorkingBeatmapCache.cs +++ b/osu.Game/Beatmaps/WorkingBeatmapCache.cs @@ -12,7 +12,6 @@ using osu.Framework.IO.Stores; using osu.Framework.Lists; using osu.Framework.Logging; using osu.Framework.Platform; -using osu.Framework.Statistics; using osu.Framework.Testing; using osu.Game.Beatmaps.Formats; using osu.Game.Database; @@ -86,23 +85,11 @@ namespace osu.Game.Beatmaps if (beatmapInfo?.BeatmapSet == null) return DefaultBeatmap; - lock (workingCache) - { - var working = workingCache.FirstOrDefault(w => beatmapInfo.Equals(w.BeatmapInfo)); + WorkingBeatmap working = null; - if (working != null) - return working; + working = new BeatmapManagerWorkingBeatmap(beatmapInfo, this); - // TODO: is this still required..? - //beatmapInfo.Metadata ??= beatmapInfo.BeatmapSet.Metadata; - - workingCache.Add(working = new BeatmapManagerWorkingBeatmap(beatmapInfo, this)); - - // best effort; may be higher than expected. - GlobalStatistics.Get(nameof(Beatmaps), $"Cached {nameof(WorkingBeatmap)}s").Value = workingCache.Count(); - - return working; - } + return working; } #region IResourceStorageProvider diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 8c115c2c94..2731096a00 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -71,33 +71,37 @@ namespace osu.Game.Overlays [Resolved] private RealmContextFactory realmFactory { get; set; } - protected override void LoadComplete() + [BackgroundDependencyLoader] + private void load() { - base.LoadComplete(); - - beatmapSubscription = realmFactory.Context.All().QueryAsyncWithNotifications(beatmapsChanged); - // Todo: These binds really shouldn't be here, but are unlikely to cause any issues for now. // They are placed here for now since some tests rely on setting the beatmap _and_ their hierarchies inside their load(), which runs before the MusicController's load(). beatmap.BindValueChanged(beatmapChanged, true); mods.BindValueChanged(_ => ResetTrackAdjustments(), true); } + protected override void LoadComplete() + { + base.LoadComplete(); + + // ensure we're ready before completing async load. + // probably not a good way of handling this (as there is a period we aren't watching for changes until the realm subscription finishes up. + foreach (var s in realmFactory.Context.All()) + beatmapSets.Add(s); + + beatmapSubscription = realmFactory.Context.All().QueryAsyncWithNotifications(beatmapsChanged); + } + private void beatmapsChanged(IRealmCollection sender, ChangeSet changes, Exception error) { if (changes == null) - { - beatmapSets.AddRange(sender); - } + return; - // beatmaps.ItemUpdated += set => Schedule(() => - // { - // beatmapSets.Remove(set); - // beatmapSets.Add(set); - // }); - // beatmaps.ItemRemoved += set => Schedule(() => beatmapSets.RemoveAll(s => s.ID == set.ID)); - // - // beatmapSets.AddRange(beatmaps.GetAllUsableBeatmapSets(IncludedDetails.Minimal, true).OrderBy(_ => RNG.Next())); + foreach (int i in changes.InsertedIndices) + beatmapSets.Insert(i, sender[i]); + + foreach (int i in changes.DeletedIndices.OrderByDescending(i => i)) + beatmapSets.RemoveAt(i); } /// diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index f54228b441..e02066560d 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -81,8 +81,11 @@ namespace osu.Game.Screens.Menu this.createNextScreen = createNextScreen; } + [Resolved] + private BeatmapManager beatmaps { get; set; } + [BackgroundDependencyLoader] - private void load(OsuConfigManager config, SkinManager skinManager, BeatmapManager beatmaps, Framework.Game game, RealmContextFactory realmContextFactory) + private void load(OsuConfigManager config, SkinManager skinManager, Framework.Game game, RealmContextFactory realmContextFactory) { // prevent user from changing beatmap while the intro is still running. beatmap = Beatmap.BeginLease(false); @@ -101,7 +104,13 @@ namespace osu.Game.Screens.Menu if (sets.Count > 0) { setInfo = beatmaps.QueryBeatmapSet(s => s.ID == sets[RNG.Next(0, sets.Count - 1)].ID); - initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo?.PerformRead(s => s.Beatmaps[0].ToLive(realmContextFactory))); + setInfo?.PerformRead(s => + { + if (s.Beatmaps.Count == 0) + return; + + initialBeatmap = beatmaps.GetWorkingBeatmap(s.Beatmaps[0].ToLive(realmContextFactory)); + }); } } @@ -131,12 +140,29 @@ namespace osu.Game.Screens.Menu if (setInfo == null) return false; - initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo.PerformRead(s => s.Beatmaps[0].ToLive(realmContextFactory))); + setInfo.PerformRead(s => + { + if (s.Beatmaps.Count == 0) + return; + + initialBeatmap = beatmaps.GetWorkingBeatmap(s.Beatmaps[0].ToLive(realmContextFactory)); + }); return UsingThemedIntro = initialBeatmap != null; } } + protected override void LoadComplete() + { + base.LoadComplete(); + + // TODO: This is temporary to get the setInfo on the update thread, to make things work "better" without using ILive everywhere. + var setInfo = beatmaps.QueryBeatmapSets(b => b.Hash == BeatmapHash).FirstOrDefault(); + + if (setInfo?.Value.Beatmaps.Count > 0) + initialBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Value.Beatmaps.First()); + } + public override void OnResuming(IScreen last) { this.FadeIn(300); diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index 0bc93fc36e..c2ab930550 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -126,17 +126,6 @@ namespace osu.Game.Screens.Select.Leaderboards TopScore = null; } - private void scoreStoreChanged(ScoreInfo score) - { - if (Scope != BeatmapLeaderboardScope.Local) - return; - - if (BeatmapInfo?.ID != score.BeatmapInfoID) - return; - - RefreshScores(); - } - protected override bool IsOnlineScope => Scope != BeatmapLeaderboardScope.Local; private CancellationTokenSource loadCancellationSource; diff --git a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs index ad24ffc7b8..5bac2635f5 100644 --- a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs +++ b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs @@ -12,8 +12,11 @@ namespace osu.Game.Tests.Visual { base.Update(); - // note that this will override any mod rate application - Beatmap.Value.Track.Tempo.Value = Clock.Rate; + if (Beatmap.Value.TrackLoaded && Beatmap.Value.Track != null) // null check... wasn't required until now? + { + // note that this will override any mod rate application + Beatmap.Value.Track.Tempo.Value = Clock.Rate; + } } } }