From 57a41c689756f8372ea06fb9eb040bf27940ca37 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 21 Jul 2022 03:18:57 +0900 Subject: [PATCH] Add basic background processor --- osu.Game/BackgroundBeatmapProcessor.cs | 112 +++++++++++++++++++++++++ osu.Game/OsuGame.cs | 2 + osu.Game/OsuGameBase.cs | 3 +- 3 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 osu.Game/BackgroundBeatmapProcessor.cs diff --git a/osu.Game/BackgroundBeatmapProcessor.cs b/osu.Game/BackgroundBeatmapProcessor.cs new file mode 100644 index 0000000000..09db107744 --- /dev/null +++ b/osu.Game/BackgroundBeatmapProcessor.cs @@ -0,0 +1,112 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Logging; +using osu.Game.Beatmaps; +using osu.Game.Database; +using osu.Game.Rulesets; + +namespace osu.Game +{ + public class BackgroundBeatmapProcessor : Component + { + [Resolved] + private RulesetStore rulesetStore { get; set; } = null!; + + [Resolved] + private RealmAccess realmAccess { get; set; } = null!; + + [Resolved] + private BeatmapUpdater beatmapUpdater { get; set; } = null!; + + [Resolved] + private IBindable gameBeatmap { get; set; } = null!; + + protected override void LoadComplete() + { + base.LoadComplete(); + + Task.Run(() => + { + Logger.Log("Beginning background beatmap processing.."); + checkForOutdatedStarRatings(); + processBeatmapSetsWithMissingMetrics(); + Logger.Log("Finished background beatmap processing!"); + }); + } + + /// + /// Check whether the databased difficulty calculation version matches the latest ruleset provided version. + /// If it doesn't, clear out any existing difficulties so they can be incrementally recalculated. + /// + private void checkForOutdatedStarRatings() + { + foreach (var ruleset in rulesetStore.AvailableRulesets) + { + // beatmap being passed in is arbitrary here. just needs to be non-null. + int currentVersion = ruleset.CreateInstance().CreateDifficultyCalculator(gameBeatmap.Value).Version; + + if (ruleset.LastAppliedDifficultyVersion < currentVersion) + { + Logger.Log($"Resetting star ratings for {ruleset.Name} (difficulty calculation version updated from {ruleset.LastAppliedDifficultyVersion} to {currentVersion})"); + + int countReset = 0; + + realmAccess.Write(r => + { + foreach (var b in r.All()) + { + if (b.Ruleset.ShortName == ruleset.ShortName) + { + b.StarRating = 0; + countReset++; + } + } + + r.Find(ruleset.ShortName).LastAppliedDifficultyVersion = currentVersion; + }); + + Logger.Log($"Finished resetting {countReset} beatmap sets for {ruleset.Name}"); + } + } + } + + private void processBeatmapSetsWithMissingMetrics() + { + // TODO: rate limit and pause processing during gameplay. + + HashSet beatmapSetIds = new HashSet(); + + realmAccess.Run(r => + { + foreach (var b in r.All().Where(b => b.StarRating == 0 || (b.OnlineID > 0 && b.LastOnlineUpdate == null))) + { + Debug.Assert(b.BeatmapSet != null); + beatmapSetIds.Add(b.BeatmapSet.ID); + } + }); + + foreach (var id in beatmapSetIds) + { + realmAccess.Run(r => + { + var set = r.Find(id); + + if (set != null) + { + Logger.Log($"Background processing {set}"); + beatmapUpdater.Process(set); + } + }); + } + } + } +} diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 69d02b95ff..4f08511783 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -904,6 +904,8 @@ protected override void LoadComplete() loadComponentSingleFile(CreateHighPerformanceSession(), Add); + loadComponentSingleFile(new BackgroundBeatmapProcessor(), Add); + chatOverlay.State.BindValueChanged(_ => updateChatPollRate()); // Multiplayer modes need to increase poll rate temporarily. API.Activity.BindValueChanged(_ => updateChatPollRate(), true); diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 6a5c6835ba..3b81b5c8cd 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -280,8 +280,7 @@ private void load(ReadableKeyCombinationProvider keyCombinationProvider) AddInternal(difficultyCache); // TODO: OsuGame or OsuGameBase? - beatmapUpdater = new BeatmapUpdater(BeatmapManager, difficultyCache, API, Storage); - + dependencies.CacheAs(beatmapUpdater = new BeatmapUpdater(BeatmapManager, difficultyCache, API, Storage)); dependencies.CacheAs(spectatorClient = new OnlineSpectatorClient(endpoints)); dependencies.CacheAs(multiplayerClient = new OnlineMultiplayerClient(endpoints)); dependencies.CacheAs(metadataClient = new OnlineMetadataClient(endpoints));