diff --git a/osu.Game.Tests/Beatmaps/BeatmapDifficultyManagerTest.cs b/osu.Game.Tests/Beatmaps/BeatmapDifficultyManagerTest.cs index 7c1ddd757f..ec77f48063 100644 --- a/osu.Game.Tests/Beatmaps/BeatmapDifficultyManagerTest.cs +++ b/osu.Game.Tests/Beatmaps/BeatmapDifficultyManagerTest.cs @@ -14,8 +14,8 @@ namespace osu.Game.Tests.Beatmaps [Test] public void TestKeyEqualsWithDifferentModInstances() { - var key1 = new BeatmapDifficultyManager.DifficultyCacheLookup(1234, 0, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); - var key2 = new BeatmapDifficultyManager.DifficultyCacheLookup(1234, 0, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); + var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(1234, 0, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); + var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(1234, 0, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); Assert.That(key1, Is.EqualTo(key2)); } @@ -23,8 +23,8 @@ namespace osu.Game.Tests.Beatmaps [Test] public void TestKeyEqualsWithDifferentModOrder() { - var key1 = new BeatmapDifficultyManager.DifficultyCacheLookup(1234, 0, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); - var key2 = new BeatmapDifficultyManager.DifficultyCacheLookup(1234, 0, new Mod[] { new OsuModHidden(), new OsuModHardRock() }); + var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(1234, 0, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); + var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(1234, 0, new Mod[] { new OsuModHidden(), new OsuModHardRock() }); Assert.That(key1, Is.EqualTo(key2)); } @@ -47,7 +47,7 @@ namespace osu.Game.Tests.Beatmaps [TestCase(8.3, DifficultyRating.ExpertPlus)] public void TestDifficultyRatingMapping(double starRating, DifficultyRating expectedBracket) { - var actualBracket = BeatmapDifficultyManager.GetDifficultyRating(starRating); + var actualBracket = BeatmapDifficultyCache.GetDifficultyRating(starRating); Assert.AreEqual(expectedBracket, actualBracket); } diff --git a/osu.Game/Beatmaps/BeatmapDifficultyManager.cs b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs similarity index 97% rename from osu.Game/Beatmaps/BeatmapDifficultyManager.cs rename to osu.Game/Beatmaps/BeatmapDifficultyCache.cs index 9e83738e70..dafe7c19e6 100644 --- a/osu.Game/Beatmaps/BeatmapDifficultyManager.cs +++ b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs @@ -11,7 +11,7 @@ using System.Threading.Tasks; using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; using osu.Framework.Lists; using osu.Framework.Logging; using osu.Framework.Threading; @@ -23,10 +23,14 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Beatmaps { - public class BeatmapDifficultyManager : CompositeDrawable + /// + /// A component which performs and acts as a central cache for difficulty calculations of beatmap/ruleset/mod combinations. + /// Currently not persisted between game sessions. + /// + public class BeatmapDifficultyCache : Component { // Too many simultaneous updates can lead to stutters. One thread seems to work fine for song select display purposes. - private readonly ThreadedTaskScheduler updateScheduler = new ThreadedTaskScheduler(1, nameof(BeatmapDifficultyManager)); + private readonly ThreadedTaskScheduler updateScheduler = new ThreadedTaskScheduler(1, nameof(BeatmapDifficultyCache)); // A permanent cache to prevent re-computations. private readonly ConcurrentDictionary difficultyCache = new ConcurrentDictionary(); @@ -387,6 +391,6 @@ namespace osu.Game.Beatmaps Attributes = null; } - public DifficultyRating DifficultyRating => BeatmapDifficultyManager.GetDifficultyRating(Stars); + public DifficultyRating DifficultyRating => BeatmapDifficultyCache.GetDifficultyRating(Stars); } } diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index ffd8d14048..a898e10e4f 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -136,7 +136,7 @@ namespace osu.Game.Beatmaps public List Scores { get; set; } [JsonIgnore] - public DifficultyRating DifficultyRating => BeatmapDifficultyManager.GetDifficultyRating(StarDifficulty); + public DifficultyRating DifficultyRating => BeatmapDifficultyCache.GetDifficultyRating(StarDifficulty); public string[] SearchableTerms => new[] { diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index a1d5e33d1e..96e18f120a 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -142,7 +142,7 @@ namespace osu.Game.Beatmaps.Drawables private CancellationTokenSource difficultyCancellation; [Resolved] - private BeatmapDifficultyManager difficultyManager { get; set; } + private BeatmapDifficultyCache difficultyCache { get; set; } public DifficultyRetriever(BeatmapInfo beatmap, RulesetInfo ruleset, IReadOnlyList mods) { @@ -158,8 +158,8 @@ namespace osu.Game.Beatmaps.Drawables { difficultyCancellation = new CancellationTokenSource(); localStarDifficulty = ruleset != null - ? difficultyManager.GetBindableDifficulty(beatmap, ruleset, mods, difficultyCancellation.Token) - : difficultyManager.GetBindableDifficulty(beatmap, difficultyCancellation.Token); + ? difficultyCache.GetBindableDifficulty(beatmap, ruleset, mods, difficultyCancellation.Token) + : difficultyCache.GetBindableDifficulty(beatmap, difficultyCancellation.Token); localStarDifficulty.BindValueChanged(difficulty => StarDifficulty.Value = difficulty.NewValue); } diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 4bc54e7e83..fa183beeb9 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -59,7 +59,7 @@ namespace osu.Game protected ScoreManager ScoreManager; - protected BeatmapDifficultyManager DifficultyManager; + protected BeatmapDifficultyCache DifficultyCache; protected SkinManager SkinManager; @@ -202,7 +202,7 @@ namespace osu.Game dependencies.Cache(FileStore = new FileStore(contextFactory, Storage)); // ordering is important here to ensure foreign keys rules are not broken in ModelStore.Cleanup() - dependencies.Cache(ScoreManager = new ScoreManager(RulesetStore, () => BeatmapManager, Storage, API, contextFactory, Host, () => DifficultyManager, LocalConfig)); + dependencies.Cache(ScoreManager = new ScoreManager(RulesetStore, () => BeatmapManager, Storage, API, contextFactory, Host, () => DifficultyCache, LocalConfig)); dependencies.Cache(BeatmapManager = new BeatmapManager(Storage, contextFactory, RulesetStore, API, Audio, Host, defaultBeatmap, true)); // this should likely be moved to ArchiveModelManager when another case appers where it is necessary @@ -226,8 +226,8 @@ namespace osu.Game ScoreManager.Undelete(getBeatmapScores(item), true); }); - dependencies.Cache(DifficultyManager = new BeatmapDifficultyManager()); - AddInternal(DifficultyManager); + dependencies.Cache(DifficultyCache = new BeatmapDifficultyCache()); + AddInternal(DifficultyCache); var scorePerformanceManager = new ScorePerformanceManager(); dependencies.Cache(scorePerformanceManager); diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index cce6153953..cf1d123c06 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -37,13 +37,13 @@ namespace osu.Game.Scoring private readonly Func beatmaps; [CanBeNull] - private readonly Func difficulties; + private readonly Func difficulties; [CanBeNull] private readonly OsuConfigManager configManager; public ScoreManager(RulesetStore rulesets, Func beatmaps, Storage storage, IAPIProvider api, IDatabaseContextFactory contextFactory, IIpcHost importHost = null, - Func difficulties = null, OsuConfigManager configManager = null) + Func difficulties = null, OsuConfigManager configManager = null) : base(storage, contextFactory, api, new ScoreStore(contextFactory, storage), importHost) { this.rulesets = rulesets; @@ -121,14 +121,14 @@ namespace osu.Game.Scoring public readonly Bindable ScoringMode = new Bindable(); private readonly ScoreInfo score; - private readonly Func difficulties; + private readonly Func difficulties; /// /// Creates a new . /// /// The to provide the total score of. - /// A function to retrieve the . - public TotalScoreBindable(ScoreInfo score, Func difficulties) + /// A function to retrieve the . + public TotalScoreBindable(ScoreInfo score, Func difficulties) { this.score = score; this.difficulties = difficulties; diff --git a/osu.Game/Scoring/ScorePerformanceManager.cs b/osu.Game/Scoring/ScorePerformanceManager.cs index ddda1b99af..326a2fce7f 100644 --- a/osu.Game/Scoring/ScorePerformanceManager.cs +++ b/osu.Game/Scoring/ScorePerformanceManager.cs @@ -22,7 +22,7 @@ namespace osu.Game.Scoring private readonly ConcurrentDictionary performanceCache = new ConcurrentDictionary(); [Resolved] - private BeatmapDifficultyManager difficultyManager { get; set; } + private BeatmapDifficultyCache difficultyCache { get; set; } /// /// Calculates performance for the given . @@ -41,7 +41,7 @@ namespace osu.Game.Scoring private async Task computePerformanceAsync(ScoreInfo score, PerformanceCacheLookup lookupKey, CancellationToken token = default) { - var attributes = await difficultyManager.GetDifficultyAsync(score.Beatmap, score.Ruleset, score.Mods, token); + var attributes = await difficultyCache.GetDifficultyAsync(score.Beatmap, score.Ruleset, score.Mods, token); // Performance calculation requires the beatmap and ruleset to be locally available. If not, return a default value. if (attributes.Attributes == null) diff --git a/osu.Game/Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs b/osu.Game/Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs index f9b7625913..33ee5d2ee4 100644 --- a/osu.Game/Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs +++ b/osu.Game/Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Ranking.Expanded } [BackgroundDependencyLoader] - private void load(BeatmapDifficultyManager beatmapDifficultyManager) + private void load(BeatmapDifficultyCache beatmapDifficultyCache) { var beatmap = score.Beatmap; var metadata = beatmap.BeatmapSet?.Metadata ?? beatmap.Metadata; @@ -143,7 +143,7 @@ namespace osu.Game.Screens.Ranking.Expanded Spacing = new Vector2(5, 0), Children = new Drawable[] { - new StarRatingDisplay(beatmapDifficultyManager.GetDifficulty(beatmap, score.Ruleset, score.Mods)) + new StarRatingDisplay(beatmapDifficultyCache.GetDifficulty(beatmap, score.Ruleset, score.Mods)) { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft diff --git a/osu.Game/Screens/Ranking/Expanded/StarRatingDisplay.cs b/osu.Game/Screens/Ranking/Expanded/StarRatingDisplay.cs index ffb12d474b..f7e50fdc8a 100644 --- a/osu.Game/Screens/Ranking/Expanded/StarRatingDisplay.cs +++ b/osu.Game/Screens/Ranking/Expanded/StarRatingDisplay.cs @@ -34,7 +34,7 @@ namespace osu.Game.Screens.Ranking.Expanded } [BackgroundDependencyLoader] - private void load(OsuColour colours, BeatmapDifficultyManager difficultyManager) + private void load(OsuColour colours, BeatmapDifficultyCache difficultyCache) { AutoSizeAxes = Axes.Both; diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 2634f117de..04c1f6efe4 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -41,7 +41,7 @@ namespace osu.Game.Screens.Select private readonly IBindable ruleset = new Bindable(); [Resolved] - private BeatmapDifficultyManager difficultyManager { get; set; } + private BeatmapDifficultyCache difficultyCache { get; set; } private IBindable beatmapDifficulty; @@ -100,7 +100,7 @@ namespace osu.Game.Screens.Select cancellationSource = new CancellationTokenSource(); beatmapDifficulty?.UnbindAll(); - beatmapDifficulty = difficultyManager.GetBindableDifficulty(beatmap.BeatmapInfo, cancellationSource.Token); + beatmapDifficulty = difficultyCache.GetBindableDifficulty(beatmap.BeatmapInfo, cancellationSource.Token); beatmapDifficulty.BindValueChanged(_ => updateDisplay()); updateDisplay(); diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index 49a370724e..e66469ff8d 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Select.Carousel private BeatmapSetOverlay beatmapOverlay { get; set; } [Resolved] - private BeatmapDifficultyManager difficultyManager { get; set; } + private BeatmapDifficultyCache difficultyCache { get; set; } [Resolved(CanBeNull = true)] private CollectionManager collectionManager { get; set; } @@ -216,7 +216,7 @@ namespace osu.Game.Screens.Select.Carousel if (Item.State.Value != CarouselItemState.Collapsed) { // We've potentially cancelled the computation above so a new bindable is required. - starDifficultyBindable = difficultyManager.GetBindableDifficulty(beatmap, (starDifficultyCancellationSource = new CancellationTokenSource()).Token); + starDifficultyBindable = difficultyCache.GetBindableDifficulty(beatmap, (starDifficultyCancellationSource = new CancellationTokenSource()).Token); starDifficultyBindable.BindValueChanged(d => starCounter.Current = (float)d.NewValue.Stars, true); } diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index 44c328187f..44d908fc46 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Select.Details private IBindable ruleset { get; set; } [Resolved] - private BeatmapDifficultyManager difficultyManager { get; set; } + private BeatmapDifficultyCache difficultyCache { get; set; } protected readonly StatisticRow FirstValue, HpDrain, Accuracy, ApproachRate; private readonly StatisticRow starDifficulty; @@ -161,8 +161,8 @@ namespace osu.Game.Screens.Select.Details starDifficultyCancellationSource = new CancellationTokenSource(); - normalStarDifficulty = difficultyManager.GetBindableDifficulty(Beatmap, ruleset.Value, null, starDifficultyCancellationSource.Token); - moddedStarDifficulty = difficultyManager.GetBindableDifficulty(Beatmap, ruleset.Value, mods.Value, starDifficultyCancellationSource.Token); + normalStarDifficulty = difficultyCache.GetBindableDifficulty(Beatmap, ruleset.Value, null, starDifficultyCancellationSource.Token); + moddedStarDifficulty = difficultyCache.GetBindableDifficulty(Beatmap, ruleset.Value, mods.Value, starDifficultyCancellationSource.Token); normalStarDifficulty.BindValueChanged(_ => updateDisplay()); moddedStarDifficulty.BindValueChanged(_ => updateDisplay(), true);