1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 20:22:55 +08:00

Merge pull request #18820 from peppy/beatmap-difficulty-cache-cleanup

Enable NRT and tidy up `BeatmapDifficultyCache`
This commit is contained in:
Dan Balasescu 2022-06-23 23:23:17 +09:00 committed by GitHub
commit 55f1702448
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 59 deletions

View File

@ -157,7 +157,7 @@ namespace osu.Game.Tests.Beatmaps
[TestCase(8.3, DifficultyRating.ExpertPlus)]
public void TestDifficultyRatingMapping(double starRating, DifficultyRating expectedBracket)
{
var actualBracket = BeatmapDifficultyCache.GetDifficultyRating(starRating);
var actualBracket = StarDifficulty.GetDifficultyRating(starRating);
Assert.AreEqual(expectedBracket, actualBracket);
}

View File

@ -1,22 +1,18 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable disable
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Lists;
using osu.Framework.Logging;
using osu.Framework.Threading;
using osu.Framework.Utils;
using osu.Game.Configuration;
using osu.Game.Database;
using osu.Game.Rulesets;
@ -50,19 +46,19 @@ namespace osu.Game.Beatmaps
/// </summary>
private readonly object bindableUpdateLock = new object();
private CancellationTokenSource trackedUpdateCancellationSource;
private CancellationTokenSource trackedUpdateCancellationSource = new CancellationTokenSource();
[Resolved]
private BeatmapManager beatmapManager { get; set; }
private BeatmapManager beatmapManager { get; set; } = null!;
[Resolved]
private Bindable<RulesetInfo> currentRuleset { get; set; }
private Bindable<RulesetInfo> currentRuleset { get; set; } = null!;
[Resolved]
private Bindable<IReadOnlyList<Mod>> currentMods { get; set; }
private Bindable<IReadOnlyList<Mod>> currentMods { get; set; } = null!;
private ModSettingChangeTracker modSettingChangeTracker;
private ScheduledDelegate debouncedModSettingsChange;
private ModSettingChangeTracker? modSettingChangeTracker;
private ScheduledDelegate? debouncedModSettingsChange;
protected override void LoadComplete()
{
@ -91,7 +87,7 @@ namespace osu.Game.Beatmaps
/// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> to get the difficulty of.</param>
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops updating the star difficulty for the given <see cref="BeatmapInfo"/>.</param>
/// <returns>A bindable that is updated to contain the star difficulty when it becomes available. Will be null while in an initial calculating state (but not during updates to ruleset and mods if a stale value is already propagated).</returns>
public IBindable<StarDifficulty?> GetBindableDifficulty([NotNull] IBeatmapInfo beatmapInfo, CancellationToken cancellationToken = default)
public IBindable<StarDifficulty?> GetBindableDifficulty(IBeatmapInfo beatmapInfo, CancellationToken cancellationToken = default)
{
var bindable = createBindable(beatmapInfo, currentRuleset.Value, currentMods.Value, cancellationToken);
@ -112,7 +108,7 @@ namespace osu.Game.Beatmaps
/// <param name="mods">The <see cref="Mod"/>s to get the difficulty with. If <c>null</c>, no mods will be assumed.</param>
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops updating the star difficulty for the given <see cref="IBeatmapInfo"/>.</param>
/// <returns>A bindable that is updated to contain the star difficulty when it becomes available. Will be null while in an initial calculating state.</returns>
public IBindable<StarDifficulty?> GetBindableDifficulty([NotNull] IBeatmapInfo beatmapInfo, [CanBeNull] IRulesetInfo rulesetInfo, [CanBeNull] IEnumerable<Mod> mods,
public IBindable<StarDifficulty?> GetBindableDifficulty(IBeatmapInfo beatmapInfo, IRulesetInfo? rulesetInfo, IEnumerable<Mod>? mods,
CancellationToken cancellationToken = default)
=> createBindable(beatmapInfo, rulesetInfo, mods, cancellationToken);
@ -128,8 +124,8 @@ namespace osu.Game.Beatmaps
/// A <see langword="null"/> return value indicates that the difficulty process failed or was interrupted early,
/// and as such there is no usable star difficulty value to be returned.
/// </returns>
public virtual Task<StarDifficulty?> GetDifficultyAsync([NotNull] IBeatmapInfo beatmapInfo, [CanBeNull] IRulesetInfo rulesetInfo = null,
[CanBeNull] IEnumerable<Mod> mods = null, CancellationToken cancellationToken = default)
public virtual Task<StarDifficulty?> GetDifficultyAsync(IBeatmapInfo beatmapInfo, IRulesetInfo? rulesetInfo = null,
IEnumerable<Mod>? mods = null, CancellationToken cancellationToken = default)
{
// In the case that the user hasn't given us a ruleset, use the beatmap's default ruleset.
rulesetInfo ??= beatmapInfo.Ruleset;
@ -168,34 +164,6 @@ namespace osu.Game.Beatmaps
updateScheduler);
}
/// <summary>
/// Retrieves the <see cref="DifficultyRating"/> that describes a star rating.
/// </summary>
/// <remarks>
/// For more information, see: https://osu.ppy.sh/help/wiki/Difficulties
/// </remarks>
/// <param name="starRating">The star rating.</param>
/// <returns>The <see cref="DifficultyRating"/> that best describes <paramref name="starRating"/>.</returns>
public static DifficultyRating GetDifficultyRating(double starRating)
{
if (Precision.AlmostBigger(starRating, 6.5, 0.005))
return DifficultyRating.ExpertPlus;
if (Precision.AlmostBigger(starRating, 5.3, 0.005))
return DifficultyRating.Expert;
if (Precision.AlmostBigger(starRating, 4.0, 0.005))
return DifficultyRating.Insane;
if (Precision.AlmostBigger(starRating, 2.7, 0.005))
return DifficultyRating.Hard;
if (Precision.AlmostBigger(starRating, 2.0, 0.005))
return DifficultyRating.Normal;
return DifficultyRating.Easy;
}
/// <summary>
/// Updates all tracked <see cref="BindableStarDifficulty"/> using the current ruleset and mods.
/// </summary>
@ -204,7 +172,6 @@ namespace osu.Game.Beatmaps
lock (bindableUpdateLock)
{
cancelTrackedBindableUpdate();
trackedUpdateCancellationSource = new CancellationTokenSource();
foreach (var b in trackedBindables)
{
@ -223,16 +190,13 @@ namespace osu.Game.Beatmaps
{
lock (bindableUpdateLock)
{
trackedUpdateCancellationSource?.Cancel();
trackedUpdateCancellationSource = null;
trackedUpdateCancellationSource.Cancel();
trackedUpdateCancellationSource = new CancellationTokenSource();
if (linkedCancellationSources != null)
{
foreach (var c in linkedCancellationSources)
c.Dispose();
foreach (var c in linkedCancellationSources)
c.Dispose();
linkedCancellationSources.Clear();
}
linkedCancellationSources.Clear();
}
}
@ -244,7 +208,7 @@ namespace osu.Game.Beatmaps
/// <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="IBeatmapInfo"/>.</param>
/// <returns>The <see cref="BindableStarDifficulty"/>.</returns>
private BindableStarDifficulty createBindable([NotNull] IBeatmapInfo beatmapInfo, [CanBeNull] IRulesetInfo initialRulesetInfo, [CanBeNull] IEnumerable<Mod> initialMods,
private BindableStarDifficulty createBindable(IBeatmapInfo beatmapInfo, IRulesetInfo? initialRulesetInfo, IEnumerable<Mod>? initialMods,
CancellationToken cancellationToken)
{
var bindable = new BindableStarDifficulty(beatmapInfo, cancellationToken);
@ -259,7 +223,7 @@ namespace osu.Game.Beatmaps
/// <param name="rulesetInfo">The <see cref="IRulesetInfo"/> to update with.</param>
/// <param name="mods">The <see cref="Mod"/>s to update with.</param>
/// <param name="cancellationToken">A token that may be used to cancel this update.</param>
private void updateBindable([NotNull] BindableStarDifficulty bindable, [CanBeNull] IRulesetInfo rulesetInfo, [CanBeNull] IEnumerable<Mod> mods, CancellationToken cancellationToken = default)
private void updateBindable(BindableStarDifficulty bindable, IRulesetInfo? rulesetInfo, IEnumerable<Mod>? mods, CancellationToken cancellationToken = default)
{
// GetDifficultyAsync will fall back to existing data from IBeatmapInfo if not locally available
// (contrary to GetAsync)
@ -329,7 +293,7 @@ namespace osu.Game.Beatmaps
modSettingChangeTracker?.Dispose();
cancelTrackedBindableUpdate();
updateScheduler?.Dispose();
updateScheduler.Dispose();
}
public readonly struct DifficultyCacheLookup : IEquatable<DifficultyCacheLookup>
@ -339,7 +303,7 @@ namespace osu.Game.Beatmaps
public readonly Mod[] OrderedMods;
public DifficultyCacheLookup([NotNull] BeatmapInfo beatmapInfo, [CanBeNull] RulesetInfo ruleset, IEnumerable<Mod> mods)
public DifficultyCacheLookup(BeatmapInfo beatmapInfo, RulesetInfo? ruleset, IEnumerable<Mod>? mods)
{
BeatmapInfo = beatmapInfo;
// In the case that the user hasn't given us a ruleset, use the beatmap's default ruleset.

View File

@ -128,7 +128,7 @@ namespace osu.Game.Beatmaps
public List<EFScoreInfo> Scores { get; set; }
[JsonIgnore]
public DifficultyRating DifficultyRating => BeatmapDifficultyCache.GetDifficultyRating(StarRating);
public DifficultyRating DifficultyRating => StarDifficulty.GetDifficultyRating(StarRating);
public override string ToString() => this.GetDisplayTitle();

View File

@ -4,6 +4,7 @@
#nullable disable
using JetBrains.Annotations;
using osu.Framework.Utils;
using osu.Game.Rulesets.Difficulty;
namespace osu.Game.Beatmaps
@ -50,6 +51,34 @@ namespace osu.Game.Beatmaps
Attributes = null;
}
public DifficultyRating DifficultyRating => BeatmapDifficultyCache.GetDifficultyRating(Stars);
public DifficultyRating DifficultyRating => GetDifficultyRating(Stars);
/// <summary>
/// Retrieves the <see cref="DifficultyRating"/> that describes a star rating.
/// </summary>
/// <remarks>
/// For more information, see: https://osu.ppy.sh/help/wiki/Difficulties
/// </remarks>
/// <param name="starRating">The star rating.</param>
/// <returns>The <see cref="DifficultyRating"/> that best describes <paramref name="starRating"/>.</returns>
public static DifficultyRating GetDifficultyRating(double starRating)
{
if (Precision.AlmostBigger(starRating, 6.5, 0.005))
return DifficultyRating.ExpertPlus;
if (Precision.AlmostBigger(starRating, 5.3, 0.005))
return DifficultyRating.Expert;
if (Precision.AlmostBigger(starRating, 4.0, 0.005))
return DifficultyRating.Insane;
if (Precision.AlmostBigger(starRating, 2.7, 0.005))
return DifficultyRating.Hard;
if (Precision.AlmostBigger(starRating, 2.0, 0.005))
return DifficultyRating.Normal;
return DifficultyRating.Easy;
}
}
}

View File

@ -31,7 +31,7 @@ namespace osu.Game.Screens.Edit.Verify
[BackgroundDependencyLoader]
private void load()
{
InterpretedDifficulty.Default = BeatmapDifficultyCache.GetDifficultyRating(EditorBeatmap.BeatmapInfo.StarRating);
InterpretedDifficulty.Default = StarDifficulty.GetDifficultyRating(EditorBeatmap.BeatmapInfo.StarRating);
InterpretedDifficulty.SetDefault();
Child = new Container