1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 02:32:55 +08:00

Reuse BeatmapDifficultyManager cache for beatmap difficulty attributes.

This commit is contained in:
Lucas A 2020-09-29 18:32:02 +02:00
parent 35f7de2084
commit 2766cf73b4
12 changed files with 29 additions and 25 deletions

View File

@ -145,7 +145,7 @@ namespace osu.Game.Rulesets.Catch
public override ISkin CreateLegacySkinProvider(ISkinSource source, IBeatmap beatmap) => new CatchLegacySkinTransformer(source); public override ISkin CreateLegacySkinProvider(ISkinSource source, IBeatmap beatmap) => new CatchLegacySkinTransformer(source);
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new CatchPerformanceCalculator(this, beatmap, score); public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score, DifficultyAttributes attributes = null) => new CatchPerformanceCalculator(this, beatmap, score);
public int LegacyID => 2; public int LegacyID => 2;

View File

@ -25,8 +25,8 @@ namespace osu.Game.Rulesets.Catch.Difficulty
private int tinyTicksMissed; private int tinyTicksMissed;
private int misses; private int misses;
public CatchPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score) public CatchPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score, DifficultyAttributes attributes = null)
: base(ruleset, beatmap, score) : base(ruleset, beatmap, score, attributes)
{ {
} }

View File

@ -29,8 +29,8 @@ namespace osu.Game.Rulesets.Mania.Difficulty
private int countMeh; private int countMeh;
private int countMiss; private int countMiss;
public ManiaPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score) public ManiaPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score, DifficultyAttributes attributes)
: base(ruleset, beatmap, score) : base(ruleset, beatmap, score, attributes)
{ {
} }

View File

@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Mania
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap, this); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap, this);
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new ManiaPerformanceCalculator(this, beatmap, score); public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score, DifficultyAttributes attributes = null) => new ManiaPerformanceCalculator(this, beatmap, score, attributes);
public const string SHORT_NAME = "mania"; public const string SHORT_NAME = "mania";

View File

@ -31,8 +31,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
private int countMeh; private int countMeh;
private int countMiss; private int countMiss;
public OsuPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score) public OsuPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score, DifficultyAttributes attributes)
: base(ruleset, beatmap, score) : base(ruleset, beatmap, score, attributes)
{ {
countHitCircles = Beatmap.HitObjects.Count(h => h is HitCircle); countHitCircles = Beatmap.HitObjects.Count(h => h is HitCircle);

View File

@ -171,7 +171,7 @@ namespace osu.Game.Rulesets.Osu
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new OsuDifficultyCalculator(this, beatmap); public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new OsuDifficultyCalculator(this, beatmap);
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new OsuPerformanceCalculator(this, beatmap, score); public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score, DifficultyAttributes attributes = null) => new OsuPerformanceCalculator(this, beatmap, score, attributes);
public override HitObjectComposer CreateHitObjectComposer() => new OsuHitObjectComposer(this); public override HitObjectComposer CreateHitObjectComposer() => new OsuHitObjectComposer(this);

View File

@ -24,8 +24,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
private int countMeh; private int countMeh;
private int countMiss; private int countMiss;
public TaikoPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score) public TaikoPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score, DifficultyAttributes attributes = null)
: base(ruleset, beatmap, score) : base(ruleset, beatmap, score, attributes)
{ {
} }

View File

@ -153,7 +153,7 @@ namespace osu.Game.Rulesets.Taiko
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new TaikoDifficultyCalculator(this, beatmap); public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new TaikoDifficultyCalculator(this, beatmap);
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new TaikoPerformanceCalculator(this, beatmap, score); public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score, DifficultyAttributes attributes = null) => new TaikoPerformanceCalculator(this, beatmap, score, attributes);
public int LegacyID => 1; public int LegacyID => 1;

View File

@ -15,6 +15,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Lists; using osu.Framework.Lists;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Beatmaps namespace osu.Game.Beatmaps
@ -207,7 +208,7 @@ namespace osu.Game.Beatmaps
var calculator = ruleset.CreateDifficultyCalculator(beatmapManager.GetWorkingBeatmap(beatmapInfo)); var calculator = ruleset.CreateDifficultyCalculator(beatmapManager.GetWorkingBeatmap(beatmapInfo));
var attributes = calculator.Calculate(key.Mods); var attributes = calculator.Calculate(key.Mods);
return difficultyCache[key] = new StarDifficulty(attributes.StarRating, attributes.MaxCombo); return difficultyCache[key] = new StarDifficulty(attributes.StarRating, attributes.MaxCombo, attributes);
} }
catch catch
{ {
@ -300,11 +301,13 @@ namespace osu.Game.Beatmaps
public readonly double Stars; public readonly double Stars;
public readonly int MaxCombo; public readonly int MaxCombo;
public StarDifficulty(double stars, int maxCombo) public readonly DifficultyAttributes Attributes;
public StarDifficulty(double stars, int maxCombo, DifficultyAttributes attributes = null)
{ {
Stars = stars; Stars = stars;
MaxCombo = maxCombo; MaxCombo = maxCombo;
Attributes = attributes;
// Todo: Add more members (BeatmapInfo.DifficultyRating? Attributes? Etc...) // Todo: Add more members (BeatmapInfo.DifficultyRating? Attributes? Etc...)
} }
} }

View File

@ -21,14 +21,14 @@ namespace osu.Game.Rulesets.Difficulty
protected double TimeRate { get; private set; } = 1; protected double TimeRate { get; private set; } = 1;
protected PerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score) protected PerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score, DifficultyAttributes attributes = null)
{ {
Ruleset = ruleset; Ruleset = ruleset;
Score = score; Score = score;
Beatmap = beatmap.GetPlayableBeatmap(ruleset.RulesetInfo, score.Mods); Beatmap = beatmap.GetPlayableBeatmap(ruleset.RulesetInfo, score.Mods);
Attributes = ruleset.CreateDifficultyCalculator(beatmap).Calculate(score.Mods); Attributes = attributes ?? ruleset.CreateDifficultyCalculator(beatmap).Calculate(score.Mods);
ApplyMods(score.Mods); ApplyMods(score.Mods);
} }

View File

@ -158,7 +158,7 @@ namespace osu.Game.Rulesets
public abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap); public abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap);
public virtual PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => null; public virtual PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score, DifficultyAttributes attributes = null) => null;
public virtual HitObjectComposer CreateHitObjectComposer() => null; public virtual HitObjectComposer CreateHitObjectComposer() => null;

View File

@ -20,6 +20,9 @@ namespace osu.Game.Scoring
[Resolved] [Resolved]
private BeatmapManager beatmapManager { get; set; } private BeatmapManager beatmapManager { get; set; }
[Resolved]
private BeatmapDifficultyManager difficultyManager { get; set; }
/// <summary> /// <summary>
/// Calculates performance for the given <see cref="ScoreInfo"/>. /// Calculates performance for the given <see cref="ScoreInfo"/>.
/// </summary> /// </summary>
@ -30,10 +33,7 @@ namespace osu.Game.Scoring
if (tryGetExisting(score, out var perf, out var lookupKey)) if (tryGetExisting(score, out var perf, out var lookupKey))
return perf; return perf;
return await Task.Factory.StartNew(() => return await computePerformanceAsync(score, lookupKey, token);
{
return computePerformance(score, lookupKey, token);
}, token);
} }
private bool tryGetExisting(ScoreInfo score, out double performance, out PerformanceCacheLookup lookupKey) private bool tryGetExisting(ScoreInfo score, out double performance, out PerformanceCacheLookup lookupKey)
@ -43,14 +43,15 @@ namespace osu.Game.Scoring
return performanceCache.TryGetValue(lookupKey, out performance); return performanceCache.TryGetValue(lookupKey, out performance);
} }
private double computePerformance(ScoreInfo score, PerformanceCacheLookup lookupKey, CancellationToken token = default) private async Task<double> computePerformanceAsync(ScoreInfo score, PerformanceCacheLookup lookupKey, CancellationToken token = default)
{ {
var beatmap = beatmapManager.GetWorkingBeatmap(score.Beatmap); var beatmap = beatmapManager.GetWorkingBeatmap(score.Beatmap);
var attributes = await difficultyManager.GetDifficultyAsync(score.Beatmap, score.Ruleset, score.Mods, token);
if (token.IsCancellationRequested) if (token.IsCancellationRequested)
return default; return default;
var calculator = score.Ruleset.CreateInstance().CreatePerformanceCalculator(beatmap, score); var calculator = score.Ruleset.CreateInstance().CreatePerformanceCalculator(beatmap, score, attributes.Attributes);
var total = calculator.Calculate(); var total = calculator.Calculate();
performanceCache[lookupKey] = total; performanceCache[lookupKey] = total;
@ -74,7 +75,7 @@ namespace osu.Game.Scoring
TotalScore = info.TotalScore; TotalScore = info.TotalScore;
Combo = info.Combo; Combo = info.Combo;
Mods = info.Mods; Mods = info.Mods;
RulesetId = info.Ruleset.ID.Value; RulesetId = info.Ruleset.ID ?? 0;
} }
public override int GetHashCode() public override int GetHashCode()