diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index 1e46e265ac..ed100d1876 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -1,7 +1,6 @@ // 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.IO; using System.Threading; @@ -57,11 +56,10 @@ namespace osu.Game.Beatmaps /// /// The to create a playable for. /// The s to apply to the . - /// The maximum length in milliseconds to wait for load to complete. Defaults to 10,000ms. /// Cancellation token that cancels the beatmap loading process. /// The converted . /// If could not be converted to . - IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods = null, TimeSpan? timeout = null, CancellationToken token = default); + IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods = null, CancellationToken token = default); /// /// Load a new audio track instance for this beatmap. This should be called once before accessing . diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index a93c50ce74..0527acca8f 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -81,98 +81,94 @@ namespace osu.Game.Beatmaps /// The applicable . protected virtual IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) => ruleset.CreateBeatmapConverter(beatmap); - public virtual IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods = null, TimeSpan? timeout = null, CancellationToken token = default) + public virtual IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods = null, CancellationToken token = default) { - using (var timeoutSource = createTimeoutTokenSource(timeout)) - using (var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token, timeoutSource.Token)) + mods ??= Array.Empty(); + + var rulesetInstance = ruleset.CreateInstance(); + + IBeatmapConverter converter = CreateBeatmapConverter(Beatmap, rulesetInstance); + + // Check if the beatmap can be converted + if (Beatmap.HitObjects.Count > 0 && !converter.CanConvert()) + throw new BeatmapInvalidForRulesetException($"{nameof(Beatmaps.Beatmap)} can not be converted for the ruleset (ruleset: {ruleset.InstantiationInfo}, converter: {converter})."); + + // Apply conversion mods + foreach (var mod in mods.OfType()) { - mods ??= Array.Empty(); - - var rulesetInstance = ruleset.CreateInstance(); - - IBeatmapConverter converter = CreateBeatmapConverter(Beatmap, rulesetInstance); - - // Check if the beatmap can be converted - if (Beatmap.HitObjects.Count > 0 && !converter.CanConvert()) - throw new BeatmapInvalidForRulesetException($"{nameof(Beatmaps.Beatmap)} can not be converted for the ruleset (ruleset: {ruleset.InstantiationInfo}, converter: {converter})."); - - // Apply conversion mods - foreach (var mod in mods.OfType()) - { - if (linkedTokenSource.IsCancellationRequested) - throw new BeatmapLoadTimeoutException(BeatmapInfo); - - mod.ApplyToBeatmapConverter(converter); - } - - // Convert - IBeatmap converted = converter.Convert(linkedTokenSource.Token); - - // Apply conversion mods to the result - foreach (var mod in mods.OfType()) - { - if (linkedTokenSource.IsCancellationRequested) - throw new BeatmapLoadTimeoutException(BeatmapInfo); - - mod.ApplyToBeatmap(converted); - } - - // Apply difficulty mods - if (mods.Any(m => m is IApplicableToDifficulty)) - { - foreach (var mod in mods.OfType()) - { - if (linkedTokenSource.IsCancellationRequested) - throw new BeatmapLoadTimeoutException(BeatmapInfo); - - mod.ApplyToDifficulty(converted.Difficulty); - } - } - - IBeatmapProcessor processor = rulesetInstance.CreateBeatmapProcessor(converted); - - foreach (var mod in mods.OfType()) - mod.ApplyToBeatmapProcessor(processor); - - processor?.PreProcess(); - - // Compute default values for hitobjects, including creating nested hitobjects in-case they're needed - try - { - foreach (var obj in converted.HitObjects) - { - if (linkedTokenSource.IsCancellationRequested) - throw new BeatmapLoadTimeoutException(BeatmapInfo); - - obj.ApplyDefaults(converted.ControlPointInfo, converted.Difficulty, linkedTokenSource.Token); - } - } - catch (OperationCanceledException) - { + if (token.IsCancellationRequested) throw new BeatmapLoadTimeoutException(BeatmapInfo); - } - foreach (var mod in mods.OfType()) - { - foreach (var obj in converted.HitObjects) - { - if (linkedTokenSource.IsCancellationRequested) - throw new BeatmapLoadTimeoutException(BeatmapInfo); - - mod.ApplyToHitObject(obj); - } - } - - processor?.PostProcess(); - - foreach (var mod in mods.OfType()) - { - linkedTokenSource.Token.ThrowIfCancellationRequested(); - mod.ApplyToBeatmap(converted); - } - - return converted; + mod.ApplyToBeatmapConverter(converter); } + + // Convert + IBeatmap converted = converter.Convert(token); + + // Apply conversion mods to the result + foreach (var mod in mods.OfType()) + { + if (token.IsCancellationRequested) + throw new BeatmapLoadTimeoutException(BeatmapInfo); + + mod.ApplyToBeatmap(converted); + } + + // Apply difficulty mods + if (mods.Any(m => m is IApplicableToDifficulty)) + { + foreach (var mod in mods.OfType()) + { + if (token.IsCancellationRequested) + throw new BeatmapLoadTimeoutException(BeatmapInfo); + + mod.ApplyToDifficulty(converted.Difficulty); + } + } + + IBeatmapProcessor processor = rulesetInstance.CreateBeatmapProcessor(converted); + + foreach (var mod in mods.OfType()) + mod.ApplyToBeatmapProcessor(processor); + + processor?.PreProcess(); + + // Compute default values for hitobjects, including creating nested hitobjects in-case they're needed + try + { + foreach (var obj in converted.HitObjects) + { + if (token.IsCancellationRequested) + throw new BeatmapLoadTimeoutException(BeatmapInfo); + + obj.ApplyDefaults(converted.ControlPointInfo, converted.Difficulty, token); + } + } + catch (OperationCanceledException) + { + throw new BeatmapLoadTimeoutException(BeatmapInfo); + } + + foreach (var mod in mods.OfType()) + { + foreach (var obj in converted.HitObjects) + { + if (token.IsCancellationRequested) + throw new BeatmapLoadTimeoutException(BeatmapInfo); + + mod.ApplyToHitObject(obj); + } + } + + processor?.PostProcess(); + + foreach (var mod in mods.OfType()) + { + token.ThrowIfCancellationRequested(); + mod.ApplyToBeatmap(converted); + } + + return converted; } private CancellationTokenSource loadCancellation = new CancellationTokenSource(); diff --git a/osu.Game/Screens/Play/HUD/PerformancePointsCounter.cs b/osu.Game/Screens/Play/HUD/PerformancePointsCounter.cs index bd06e71304..dea1964faa 100644 --- a/osu.Game/Screens/Play/HUD/PerformancePointsCounter.cs +++ b/osu.Game/Screens/Play/HUD/PerformancePointsCounter.cs @@ -210,7 +210,7 @@ namespace osu.Game.Screens.Play.HUD this.gameplayBeatmap = gameplayBeatmap; } - public override IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods = null, TimeSpan? timeout = null, CancellationToken timeoutToken = default) + public override IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList mods = null, CancellationToken timeoutToken = default) => gameplayBeatmap; protected override IBeatmap GetBeatmap() => gameplayBeatmap;