Merge pull request #9701 from smoogipoo/fix-tracked-bindable-update-cancellation

This commit is contained in:
Dean Herbert 2020-07-30 10:21:14 +09:00 committed by GitHub
commit 87cf9ff896
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -109,25 +109,58 @@ namespace osu.Game.Beatmaps
}
private CancellationTokenSource trackedUpdateCancellationSource;
private readonly List<CancellationTokenSource> linkedCancellationSources = new List<CancellationTokenSource>();
/// <summary>
/// Updates all tracked <see cref="BindableStarDifficulty"/> using the current ruleset and mods.
/// </summary>
private void updateTrackedBindables()
{
trackedUpdateCancellationSource?.Cancel();
cancelTrackedBindableUpdate();
trackedUpdateCancellationSource = new CancellationTokenSource();
foreach (var b in trackedBindables)
{
if (trackedUpdateCancellationSource.IsCancellationRequested)
break;
var linkedSource = CancellationTokenSource.CreateLinkedTokenSource(trackedUpdateCancellationSource.Token, b.CancellationToken);
linkedCancellationSources.Add(linkedSource);
using (var linkedSource = CancellationTokenSource.CreateLinkedTokenSource(trackedUpdateCancellationSource.Token, b.CancellationToken))
updateBindable(b, currentRuleset.Value, currentMods.Value, linkedSource.Token);
updateBindable(b, currentRuleset.Value, currentMods.Value, linkedSource.Token);
}
}
/// <summary>
/// Cancels the existing update of all tracked <see cref="BindableStarDifficulty"/> via <see cref="updateTrackedBindables"/>.
/// </summary>
private void cancelTrackedBindableUpdate()
{
trackedUpdateCancellationSource?.Cancel();
trackedUpdateCancellationSource = null;
if (linkedCancellationSources != null)
{
foreach (var c in linkedCancellationSources)
c.Dispose();
linkedCancellationSources.Clear();
}
}
/// <summary>
/// Creates a new <see cref="BindableStarDifficulty"/> and triggers an initial value update.
/// </summary>
/// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> that star difficulty should correspond to.</param>
/// <param name="initialRulesetInfo">The initial <see cref="RulesetInfo"/> to get the difficulty with.</param>
/// <param name="initialMods">The initial <see cref="Mod"/>s to get the difficulty with.</param>
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops updating the star difficulty for the given <see cref="BeatmapInfo"/>.</param>
/// <returns>The <see cref="BindableStarDifficulty"/>.</returns>
private BindableStarDifficulty createBindable([NotNull] BeatmapInfo beatmapInfo, [CanBeNull] RulesetInfo initialRulesetInfo, [CanBeNull] IEnumerable<Mod> initialMods,
CancellationToken cancellationToken)
{
var bindable = new BindableStarDifficulty(beatmapInfo, cancellationToken);
updateBindable(bindable, initialRulesetInfo, initialMods, cancellationToken);
return bindable;
}
/// <summary>
/// Updates the value of a <see cref="BindableStarDifficulty"/> with a given ruleset + mods.
/// </summary>
@ -148,22 +181,6 @@ namespace osu.Game.Beatmaps
}, cancellationToken);
}
/// <summary>
/// Creates a new <see cref="BindableStarDifficulty"/> and triggers an initial value update.
/// </summary>
/// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> that star difficulty should correspond to.</param>
/// <param name="initialRulesetInfo">The initial <see cref="RulesetInfo"/> to get the difficulty with.</param>
/// <param name="initialMods">The initial <see cref="Mod"/>s to get the difficulty with.</param>
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops updating the star difficulty for the given <see cref="BeatmapInfo"/>.</param>
/// <returns>The <see cref="BindableStarDifficulty"/>.</returns>
private BindableStarDifficulty createBindable([NotNull] BeatmapInfo beatmapInfo, [CanBeNull] RulesetInfo initialRulesetInfo, [CanBeNull] IEnumerable<Mod> initialMods,
CancellationToken cancellationToken)
{
var bindable = new BindableStarDifficulty(beatmapInfo, cancellationToken);
updateBindable(bindable, initialRulesetInfo, initialMods, cancellationToken);
return bindable;
}
/// <summary>
/// Computes the difficulty defined by a <see cref="DifficultyCacheLookup"/> key, and stores it to the timed cache.
/// </summary>
@ -220,6 +237,14 @@ namespace osu.Game.Beatmaps
return difficultyCache.TryGetValue(key, out existingDifficulty);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
cancelTrackedBindableUpdate();
updateScheduler?.Dispose();
}
private readonly struct DifficultyCacheLookup : IEquatable<DifficultyCacheLookup>
{
public readonly int BeatmapId;