Fix PR comments.

Nitpick, more cancellation token checks.
This commit is contained in:
Tollii
2021-11-06 16:03:53 +01:00
parent eb7d04bc77
commit cf0b757b16
6 changed files with 30 additions and 22 deletions

View File

@ -408,7 +408,7 @@ namespace osu.Game.Beatmaps
beatmap.BeatmapInfo.Ruleset = ruleset; beatmap.BeatmapInfo.Ruleset = ruleset;
// TODO: this should be done in a better place once we actually need to dynamically update it. // 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(null).StarRating ?? 0; beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance().CreateDifficultyCalculator(new DummyConversionBeatmap(beatmap)).Calculate().StarRating ?? 0;
beatmap.BeatmapInfo.Length = calculateLength(beatmap); beatmap.BeatmapInfo.Length = calculateLength(beatmap);
beatmap.BeatmapInfo.BPM = 60000 / beatmap.GetMostCommonBeatLength(); beatmap.BeatmapInfo.BPM = 60000 / beatmap.GetMostCommonBeatLength();

View File

@ -58,10 +58,10 @@ namespace osu.Game.Beatmaps
/// <param name="ruleset">The <see cref="RulesetInfo"/> to create a playable <see cref="IBeatmap"/> for.</param> /// <param name="ruleset">The <see cref="RulesetInfo"/> to create a playable <see cref="IBeatmap"/> for.</param>
/// <param name="mods">The <see cref="Mod"/>s to apply to the <see cref="IBeatmap"/>.</param> /// <param name="mods">The <see cref="Mod"/>s to apply to the <see cref="IBeatmap"/>.</param>
/// <param name="timeout">The maximum length in milliseconds to wait for load to complete. Defaults to 10,000ms.</param> /// <param name="timeout">The maximum length in milliseconds to wait for load to complete. Defaults to 10,000ms.</param>
/// <param name="cancellationToken">Externally provided cancellation token.</param> /// <param name="timeoutToken">Cancellation token that cancels the beatmap loading process.</param>
/// <returns>The converted <see cref="IBeatmap"/>.</returns> /// <returns>The converted <see cref="IBeatmap"/>.</returns>
/// <exception cref="BeatmapInvalidForRulesetException">If <see cref="Beatmap"/> could not be converted to <paramref name="ruleset"/>.</exception> /// <exception cref="BeatmapInvalidForRulesetException">If <see cref="Beatmap"/> could not be converted to <paramref name="ruleset"/>.</exception>
IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods = null, TimeSpan? timeout = null, CancellationToken cancellationToken = default); IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods = null, TimeSpan? timeout = null, CancellationToken timeoutToken = default);
/// <summary> /// <summary>
/// Load a new audio track instance for this beatmap. This should be called once before accessing <see cref="Track"/>. /// Load a new audio track instance for this beatmap. This should be called once before accessing <see cref="Track"/>.

View File

@ -81,9 +81,10 @@ namespace osu.Game.Beatmaps
/// <returns>The applicable <see cref="IBeatmapConverter"/>.</returns> /// <returns>The applicable <see cref="IBeatmapConverter"/>.</returns>
protected virtual IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) => ruleset.CreateBeatmapConverter(beatmap); protected virtual IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) => ruleset.CreateBeatmapConverter(beatmap);
public virtual IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods = null, TimeSpan? timeout = null, CancellationToken cancellationToken = default) public virtual IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods = null, TimeSpan? timeout = null, CancellationToken timeoutToken = default)
{ {
using (var cancellationSource = createCancellationTokenSource(timeout)) using (var timeoutSource = createTimeoutTokenSource(timeout))
using (var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(timeoutToken, timeoutSource.Token))
{ {
mods ??= Array.Empty<Mod>(); mods ??= Array.Empty<Mod>();
@ -98,19 +99,19 @@ namespace osu.Game.Beatmaps
// Apply conversion mods // Apply conversion mods
foreach (var mod in mods.OfType<IApplicableToBeatmapConverter>()) foreach (var mod in mods.OfType<IApplicableToBeatmapConverter>())
{ {
if (cancellationSource.IsCancellationRequested) if (linkedTokenSource.IsCancellationRequested)
throw new BeatmapLoadTimeoutException(BeatmapInfo); throw new BeatmapLoadTimeoutException(BeatmapInfo);
mod.ApplyToBeatmapConverter(converter); mod.ApplyToBeatmapConverter(converter);
} }
// Convert // Convert
IBeatmap converted = converter.Convert(cancellationToken != CancellationToken.None ? cancellationToken : cancellationSource.Token); IBeatmap converted = converter.Convert(linkedTokenSource.Token);
// Apply conversion mods to the result // Apply conversion mods to the result
foreach (var mod in mods.OfType<IApplicableAfterBeatmapConversion>()) foreach (var mod in mods.OfType<IApplicableAfterBeatmapConversion>())
{ {
if (cancellationSource.IsCancellationRequested) if (linkedTokenSource.IsCancellationRequested)
throw new BeatmapLoadTimeoutException(BeatmapInfo); throw new BeatmapLoadTimeoutException(BeatmapInfo);
mod.ApplyToBeatmap(converted); mod.ApplyToBeatmap(converted);
@ -121,7 +122,7 @@ namespace osu.Game.Beatmaps
{ {
foreach (var mod in mods.OfType<IApplicableToDifficulty>()) foreach (var mod in mods.OfType<IApplicableToDifficulty>())
{ {
if (cancellationSource.IsCancellationRequested) if (linkedTokenSource.IsCancellationRequested)
throw new BeatmapLoadTimeoutException(BeatmapInfo); throw new BeatmapLoadTimeoutException(BeatmapInfo);
mod.ApplyToDifficulty(converted.Difficulty); mod.ApplyToDifficulty(converted.Difficulty);
@ -140,10 +141,10 @@ namespace osu.Game.Beatmaps
{ {
foreach (var obj in converted.HitObjects) foreach (var obj in converted.HitObjects)
{ {
if (cancellationSource.IsCancellationRequested) if (linkedTokenSource.IsCancellationRequested)
throw new BeatmapLoadTimeoutException(BeatmapInfo); throw new BeatmapLoadTimeoutException(BeatmapInfo);
obj.ApplyDefaults(converted.ControlPointInfo, converted.Difficulty, cancellationToken != CancellationToken.None ? cancellationToken : cancellationSource.Token); obj.ApplyDefaults(converted.ControlPointInfo, converted.Difficulty, linkedTokenSource.Token);
} }
} }
catch (OperationCanceledException) catch (OperationCanceledException)
@ -155,7 +156,7 @@ namespace osu.Game.Beatmaps
{ {
foreach (var obj in converted.HitObjects) foreach (var obj in converted.HitObjects)
{ {
if (cancellationSource.IsCancellationRequested) if (linkedTokenSource.IsCancellationRequested)
throw new BeatmapLoadTimeoutException(BeatmapInfo); throw new BeatmapLoadTimeoutException(BeatmapInfo);
mod.ApplyToHitObject(obj); mod.ApplyToHitObject(obj);
@ -166,8 +167,7 @@ namespace osu.Game.Beatmaps
foreach (var mod in mods.OfType<IApplicableToBeatmap>()) foreach (var mod in mods.OfType<IApplicableToBeatmap>())
{ {
cancellationSource.Token.ThrowIfCancellationRequested(); linkedTokenSource.Token.ThrowIfCancellationRequested();
cancellationToken.ThrowIfCancellationRequested();
mod.ApplyToBeatmap(converted); mod.ApplyToBeatmap(converted);
} }
@ -200,7 +200,7 @@ namespace osu.Game.Beatmaps
} }
} }
private CancellationTokenSource createCancellationTokenSource(TimeSpan? timeout) private CancellationTokenSource createTimeoutTokenSource(TimeSpan? timeout)
{ {
if (Debugger.IsAttached) if (Debugger.IsAttached)
// ignore timeout when debugger is attached (may be breakpointing / debugging). // ignore timeout when debugger is attached (may be breakpointing / debugging).

View File

@ -42,8 +42,9 @@ namespace osu.Game.Rulesets.Difficulty
/// <param name="mods">The mods that should be applied to the beatmap.</param> /// <param name="mods">The mods that should be applied to the beatmap.</param>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A structure describing the difficulty of the beatmap.</returns> /// <returns>A structure describing the difficulty of the beatmap.</returns>
public DifficultyAttributes Calculate(IEnumerable<Mod> mods, CancellationToken cancellationToken = default) public DifficultyAttributes Calculate(IEnumerable<Mod> mods = null, CancellationToken cancellationToken = default)
{ {
cancellationToken.ThrowIfCancellationRequested();
preProcess(mods, cancellationToken); preProcess(mods, cancellationToken);
var skills = CreateSkills(Beatmap, playableMods, clockRate); var skills = CreateSkills(Beatmap, playableMods, clockRate);
@ -54,8 +55,11 @@ namespace osu.Game.Rulesets.Difficulty
foreach (var hitObject in getDifficultyHitObjects()) foreach (var hitObject in getDifficultyHitObjects())
{ {
foreach (var skill in skills) foreach (var skill in skills)
{
cancellationToken.ThrowIfCancellationRequested();
skill.ProcessInternal(hitObject); skill.ProcessInternal(hitObject);
} }
}
return CreateDifficultyAttributes(Beatmap, playableMods, skills, clockRate); return CreateDifficultyAttributes(Beatmap, playableMods, skills, clockRate);
} }
@ -68,6 +72,7 @@ namespace osu.Game.Rulesets.Difficulty
/// <returns>The set of <see cref="TimedDifficultyAttributes"/>.</returns> /// <returns>The set of <see cref="TimedDifficultyAttributes"/>.</returns>
public List<TimedDifficultyAttributes> CalculateTimed(IEnumerable<Mod> mods, CancellationToken cancellationToken = default) public List<TimedDifficultyAttributes> CalculateTimed(IEnumerable<Mod> mods, CancellationToken cancellationToken = default)
{ {
cancellationToken.ThrowIfCancellationRequested();
preProcess(mods, cancellationToken); preProcess(mods, cancellationToken);
var attribs = new List<TimedDifficultyAttributes>(); var attribs = new List<TimedDifficultyAttributes>();
@ -83,7 +88,10 @@ namespace osu.Game.Rulesets.Difficulty
progressiveBeatmap.HitObjects.Add(hitObject.BaseObject); progressiveBeatmap.HitObjects.Add(hitObject.BaseObject);
foreach (var skill in skills) foreach (var skill in skills)
{
cancellationToken.ThrowIfCancellationRequested();
skill.ProcessInternal(hitObject); skill.ProcessInternal(hitObject);
}
attribs.Add(new TimedDifficultyAttributes(hitObject.EndTime * clockRate, CreateDifficultyAttributes(progressiveBeatmap, playableMods, skills, clockRate))); attribs.Add(new TimedDifficultyAttributes(hitObject.EndTime * clockRate, CreateDifficultyAttributes(progressiveBeatmap, playableMods, skills, clockRate)));
} }
@ -102,7 +110,7 @@ namespace osu.Game.Rulesets.Difficulty
if (combination is MultiMod multi) if (combination is MultiMod multi)
yield return Calculate(multi.Mods); yield return Calculate(multi.Mods);
else else
yield return Calculate(new[] { combination }); yield return Calculate(combination.Yield());
} }
} }
@ -115,12 +123,12 @@ namespace osu.Game.Rulesets.Difficulty
/// Performs required tasks before every calculation. /// Performs required tasks before every calculation.
/// </summary> /// </summary>
/// <param name="mods">The original list of <see cref="Mod"/>s.</param> /// <param name="mods">The original list of <see cref="Mod"/>s.</param>
/// <param name="cancellationToken">The cancellation cancellationToken.</param> /// <param name="cancellationToken">The cancellation timeoutToken.</param>
private void preProcess(IEnumerable<Mod> mods, CancellationToken cancellationToken = default) private void preProcess(IEnumerable<Mod> mods = null, CancellationToken cancellationToken = default)
{ {
playableMods = mods.Select(m => m.DeepClone()).ToArray(); playableMods = mods.Select(m => m.DeepClone()).ToArray();
Beatmap = beatmap.GetPlayableBeatmap(ruleset.RulesetInfo, playableMods, cancellationToken: cancellationToken); Beatmap = beatmap.GetPlayableBeatmap(ruleset.RulesetInfo, playableMods, timeoutToken: cancellationToken);
var track = new TrackVirtual(10000); var track = new TrackVirtual(10000);
playableMods.OfType<IApplicableToTrack>().ForEach(m => m.ApplyToTrack(track)); playableMods.OfType<IApplicableToTrack>().ForEach(m => m.ApplyToTrack(track));

View File

@ -210,7 +210,7 @@ namespace osu.Game.Screens.Play.HUD
this.gameplayBeatmap = gameplayBeatmap; this.gameplayBeatmap = gameplayBeatmap;
} }
public override IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods = null, TimeSpan? timeout = null, CancellationToken cancellationToken = default) public override IBeatmap GetPlayableBeatmap(RulesetInfo ruleset, IReadOnlyList<Mod> mods = null, TimeSpan? timeout = null, CancellationToken timeoutToken = default)
=> gameplayBeatmap; => gameplayBeatmap;
protected override IBeatmap GetBeatmap() => gameplayBeatmap; protected override IBeatmap GetBeatmap() => gameplayBeatmap;

View File

@ -284,7 +284,7 @@ namespace osu.Game.Stores
decoded.BeatmapInfo.Ruleset = rulesetInstance.RulesetInfo; decoded.BeatmapInfo.Ruleset = rulesetInstance.RulesetInfo;
// TODO: this should be done in a better place once we actually need to dynamically update it. // 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(null).StarRating; beatmap.StarRating = rulesetInstance.CreateDifficultyCalculator(new DummyConversionBeatmap(decoded)).Calculate().StarRating;
beatmap.Length = calculateLength(decoded); beatmap.Length = calculateLength(decoded);
beatmap.BPM = 60000 / decoded.GetMostCommonBeatLength(); beatmap.BPM = 60000 / decoded.GetMostCommonBeatLength();
} }