diff --git a/osu.Game/Beatmaps/BeatmapDifficultyCache.cs b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs index 035f438b89..bbe5ecb0df 100644 --- a/osu.Game/Beatmaps/BeatmapDifficultyCache.cs +++ b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs @@ -147,13 +147,13 @@ namespace osu.Game.Beatmaps if (CheckExists(lookup, out var existing)) return existing; - return computeDifficulty(lookup); + return computeDifficulty(lookup, token); }, token, TaskCreationOptions.HideScheduler | TaskCreationOptions.RunContinuationsAsynchronously, updateScheduler); } public Task> GetTimedDifficultyAttributesAsync(WorkingBeatmap beatmap, Ruleset ruleset, Mod[] mods, CancellationToken token = default) { - return Task.Factory.StartNew(() => ruleset.CreateDifficultyCalculator(beatmap).CalculateTimed(mods), + return Task.Factory.StartNew(() => ruleset.CreateDifficultyCalculator(beatmap).CalculateTimed(mods, token), token, TaskCreationOptions.HideScheduler | TaskCreationOptions.RunContinuationsAsynchronously, updateScheduler); @@ -270,8 +270,9 @@ namespace osu.Game.Beatmaps /// Computes the difficulty defined by a key, and stores it to the timed cache. /// /// The that defines the computation parameters. + /// The cancellation token. /// The . - private StarDifficulty computeDifficulty(in DifficultyCacheLookup key) + private StarDifficulty computeDifficulty(in DifficultyCacheLookup key, CancellationToken cancellationToken = default) { // In the case that the user hasn't given us a ruleset, use the beatmap's default ruleset. var beatmapInfo = key.BeatmapInfo; @@ -283,7 +284,7 @@ namespace osu.Game.Beatmaps Debug.Assert(ruleset != null); var calculator = ruleset.CreateDifficultyCalculator(beatmapManager.GetWorkingBeatmap(key.BeatmapInfo)); - var attributes = calculator.Calculate(key.OrderedMods); + var attributes = calculator.Calculate(key.OrderedMods, cancellationToken); return new StarDifficulty(attributes); } diff --git a/osu.Game/Beatmaps/BeatmapModelManager.cs b/osu.Game/Beatmaps/BeatmapModelManager.cs index f148d05aca..2166ae1dfc 100644 --- a/osu.Game/Beatmaps/BeatmapModelManager.cs +++ b/osu.Game/Beatmaps/BeatmapModelManager.cs @@ -408,7 +408,7 @@ namespace osu.Game.Beatmaps beatmap.BeatmapInfo.Ruleset = ruleset; // TODO: this should be done in a better place once we actually need to dynamically update it. - beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance().CreateDifficultyCalculator(new DummyConversionBeatmap(beatmap)).Calculate().StarRating ?? 0; + beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance().CreateDifficultyCalculator(new DummyConversionBeatmap(beatmap)).Calculate(null).StarRating ?? 0; beatmap.BeatmapInfo.Length = calculateLength(beatmap); beatmap.BeatmapInfo.BPM = 60000 / beatmap.GetMostCommonBeatLength(); diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index 5b4284dc2f..4fc984b491 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using osu.Framework.Audio.Track; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Game.Beatmaps; @@ -39,10 +40,11 @@ namespace osu.Game.Rulesets.Difficulty /// Calculates the difficulty of the beatmap using a specific mod combination. /// /// The mods that should be applied to the beatmap. + /// The cancellation token. /// A structure describing the difficulty of the beatmap. - public DifficultyAttributes Calculate(params Mod[] mods) + public DifficultyAttributes Calculate(IEnumerable mods, CancellationToken cancellationToken = default) { - preProcess(mods); + preProcess(mods, cancellationToken); var skills = CreateSkills(Beatmap, playableMods, clockRate); @@ -62,10 +64,11 @@ namespace osu.Game.Rulesets.Difficulty /// Calculates the difficulty of the beatmap and returns a set of representing the difficulty at every relevant time value in the beatmap. /// /// The mods that should be applied to the beatmap. + /// The cancellation token. /// The set of . - public List CalculateTimed(params Mod[] mods) + public List CalculateTimed(IEnumerable mods, CancellationToken cancellationToken = default) { - preProcess(mods); + preProcess(mods, cancellationToken); var attribs = new List(); @@ -99,7 +102,7 @@ namespace osu.Game.Rulesets.Difficulty if (combination is MultiMod multi) yield return Calculate(multi.Mods); else - yield return Calculate(combination); + yield return Calculate(new[] { combination }); } } @@ -112,11 +115,12 @@ namespace osu.Game.Rulesets.Difficulty /// Performs required tasks before every calculation. /// /// The original list of s. - private void preProcess(Mod[] mods) + /// The cancellation cancellationToken. + private void preProcess(IEnumerable mods, CancellationToken cancellationToken = default) { playableMods = mods.Select(m => m.DeepClone()).ToArray(); - Beatmap = beatmap.GetPlayableBeatmap(ruleset.RulesetInfo, playableMods); + Beatmap = beatmap.GetPlayableBeatmap(ruleset.RulesetInfo, playableMods, cancellationToken: cancellationToken); var track = new TrackVirtual(10000); playableMods.OfType().ForEach(m => m.ApplyToTrack(track)); diff --git a/osu.Game/Stores/BeatmapImporter.cs b/osu.Game/Stores/BeatmapImporter.cs index 787b1ddd60..7916583ce1 100644 --- a/osu.Game/Stores/BeatmapImporter.cs +++ b/osu.Game/Stores/BeatmapImporter.cs @@ -284,7 +284,7 @@ namespace osu.Game.Stores decoded.BeatmapInfo.Ruleset = rulesetInstance.RulesetInfo; // TODO: this should be done in a better place once we actually need to dynamically update it. - beatmap.StarRating = rulesetInstance.CreateDifficultyCalculator(new DummyConversionBeatmap(decoded)).Calculate().StarRating; + beatmap.StarRating = rulesetInstance.CreateDifficultyCalculator(new DummyConversionBeatmap(decoded)).Calculate(null).StarRating; beatmap.Length = calculateLength(decoded); beatmap.BPM = 60000 / decoded.GetMostCommonBeatLength(); }