1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-05 10:23:20 +08:00

make performance attributes a struct

This commit is contained in:
minisbett 2024-11-16 16:10:21 +01:00
parent 50be7fb077
commit e70f257947
No known key found for this signature in database
GPG Key ID: 2DB6D529C95A0403
13 changed files with 67 additions and 39 deletions

View File

@ -1,11 +1,23 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using Newtonsoft.Json;
using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Difficulty;
namespace osu.Game.Rulesets.Catch.Difficulty namespace osu.Game.Rulesets.Catch.Difficulty
{ {
public class CatchPerformanceAttributes : PerformanceAttributes public struct CatchPerformanceAttributes : IPerformanceAttributes
{ {
/// <summary>
/// Calculated score performance points.
/// </summary>
[JsonProperty("pp")]
public double Total { get; set; }
public IEnumerable<PerformanceDisplayAttribute> GetAttributesForDisplay()
{
yield return new PerformanceDisplayAttribute(nameof(Total), "Achieved PP", Total);
}
} }
} }

View File

@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
{ {
} }
protected override PerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes) protected override IPerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes)
{ {
var catchAttributes = (CatchDifficultyAttributes)attributes; var catchAttributes = (CatchDifficultyAttributes)attributes;

View File

@ -7,16 +7,20 @@ using osu.Game.Rulesets.Difficulty;
namespace osu.Game.Rulesets.Mania.Difficulty namespace osu.Game.Rulesets.Mania.Difficulty
{ {
public class ManiaPerformanceAttributes : PerformanceAttributes public struct ManiaPerformanceAttributes : IPerformanceAttributes
{ {
/// <summary>
/// Calculated score performance points.
/// </summary>
[JsonProperty("pp")]
public double Total { get; set; }
[JsonProperty("difficulty")] [JsonProperty("difficulty")]
public double Difficulty { get; set; } public double Difficulty { get; set; }
public override IEnumerable<PerformanceDisplayAttribute> GetAttributesForDisplay() public IEnumerable<PerformanceDisplayAttribute> GetAttributesForDisplay()
{ {
foreach (var attribute in base.GetAttributesForDisplay()) yield return new PerformanceDisplayAttribute(nameof(Total), "Achieved PP", Total);
yield return attribute;
yield return new PerformanceDisplayAttribute(nameof(Difficulty), "Difficulty", Difficulty); yield return new PerformanceDisplayAttribute(nameof(Difficulty), "Difficulty", Difficulty);
} }
} }

View File

@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty
{ {
} }
protected override PerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes) protected override IPerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes)
{ {
var maniaAttributes = (ManiaDifficultyAttributes)attributes; var maniaAttributes = (ManiaDifficultyAttributes)attributes;

View File

@ -7,8 +7,14 @@ using osu.Game.Rulesets.Difficulty;
namespace osu.Game.Rulesets.Osu.Difficulty namespace osu.Game.Rulesets.Osu.Difficulty
{ {
public class OsuPerformanceAttributes : PerformanceAttributes public struct OsuPerformanceAttributes : IPerformanceAttributes
{ {
/// <summary>
/// Calculated score performance points.
/// </summary>
[JsonProperty("pp")]
public double Total { get; set; }
[JsonProperty("aim")] [JsonProperty("aim")]
public double Aim { get; set; } public double Aim { get; set; }
@ -24,11 +30,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty
[JsonProperty("effective_miss_count")] [JsonProperty("effective_miss_count")]
public double EffectiveMissCount { get; set; } public double EffectiveMissCount { get; set; }
public override IEnumerable<PerformanceDisplayAttribute> GetAttributesForDisplay() public IEnumerable<PerformanceDisplayAttribute> GetAttributesForDisplay()
{ {
foreach (var attribute in base.GetAttributesForDisplay()) yield return new PerformanceDisplayAttribute(nameof(Total), "Achieved PP", Total);
yield return attribute;
yield return new PerformanceDisplayAttribute(nameof(Aim), "Aim", Aim); yield return new PerformanceDisplayAttribute(nameof(Aim), "Aim", Aim);
yield return new PerformanceDisplayAttribute(nameof(Speed), "Speed", Speed); yield return new PerformanceDisplayAttribute(nameof(Speed), "Speed", Speed);
yield return new PerformanceDisplayAttribute(nameof(Accuracy), "Accuracy", Accuracy); yield return new PerformanceDisplayAttribute(nameof(Accuracy), "Accuracy", Accuracy);

View File

@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
{ {
} }
protected override PerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes) protected override IPerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes)
{ {
var osuAttributes = (OsuDifficultyAttributes)attributes; var osuAttributes = (OsuDifficultyAttributes)attributes;

View File

@ -7,8 +7,14 @@ using osu.Game.Rulesets.Difficulty;
namespace osu.Game.Rulesets.Taiko.Difficulty namespace osu.Game.Rulesets.Taiko.Difficulty
{ {
public class TaikoPerformanceAttributes : PerformanceAttributes public struct TaikoPerformanceAttributes : IPerformanceAttributes
{ {
/// <summary>
/// Calculated score performance points.
/// </summary>
[JsonProperty("pp")]
public double Total { get; set; }
[JsonProperty("difficulty")] [JsonProperty("difficulty")]
public double Difficulty { get; set; } public double Difficulty { get; set; }
@ -21,11 +27,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
[JsonProperty("estimated_unstable_rate")] [JsonProperty("estimated_unstable_rate")]
public double? EstimatedUnstableRate { get; set; } public double? EstimatedUnstableRate { get; set; }
public override IEnumerable<PerformanceDisplayAttribute> GetAttributesForDisplay() public IEnumerable<PerformanceDisplayAttribute> GetAttributesForDisplay()
{ {
foreach (var attribute in base.GetAttributesForDisplay()) yield return new PerformanceDisplayAttribute(nameof(Total), "Achieved PP", Total);
yield return attribute;
yield return new PerformanceDisplayAttribute(nameof(Difficulty), "Difficulty", Difficulty); yield return new PerformanceDisplayAttribute(nameof(Difficulty), "Difficulty", Difficulty);
yield return new PerformanceDisplayAttribute(nameof(Accuracy), "Accuracy", Accuracy); yield return new PerformanceDisplayAttribute(nameof(Accuracy), "Accuracy", Accuracy);
} }

View File

@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
{ {
} }
protected override PerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes) protected override IPerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes)
{ {
var taikoAttributes = (TaikoDifficultyAttributes)attributes; var taikoAttributes = (TaikoDifficultyAttributes)attributes;

View File

@ -6,7 +6,7 @@ using Newtonsoft.Json;
namespace osu.Game.Rulesets.Difficulty namespace osu.Game.Rulesets.Difficulty
{ {
public class PerformanceAttributes public interface IPerformanceAttributes
{ {
/// <summary> /// <summary>
/// Calculated score performance points. /// Calculated score performance points.
@ -19,9 +19,6 @@ namespace osu.Game.Rulesets.Difficulty
/// Some attributes may be omitted if they are not meant for display. /// Some attributes may be omitted if they are not meant for display.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<PerformanceDisplayAttribute> GetAttributesForDisplay() public IEnumerable<PerformanceDisplayAttribute> GetAttributesForDisplay();
{
yield return new PerformanceDisplayAttribute(nameof(Total), "Achieved PP", Total);
}
} }
} }

View File

@ -11,19 +11,19 @@ namespace osu.Game.Rulesets.Difficulty
/// <summary> /// <summary>
/// Actual gameplay performance. /// Actual gameplay performance.
/// </summary> /// </summary>
public PerformanceAttributes Performance { get; set; } public IPerformanceAttributes Performance { get; set; }
/// <summary> /// <summary>
/// Performance of a perfect play for comparison. /// Performance of a perfect play for comparison.
/// </summary> /// </summary>
public PerformanceAttributes PerfectPerformance { get; set; } public IPerformanceAttributes PerfectPerformance { get; set; }
/// <summary> /// <summary>
/// Create a new performance breakdown. /// Create a new performance breakdown.
/// </summary> /// </summary>
/// <param name="performance">Actual gameplay performance.</param> /// <param name="performance">Actual gameplay performance.</param>
/// <param name="perfectPerformance">Performance of a perfect play for comparison.</param> /// <param name="perfectPerformance">Performance of a perfect play for comparison.</param>
public PerformanceBreakdown(PerformanceAttributes performance, PerformanceAttributes perfectPerformance) public PerformanceBreakdown(IPerformanceAttributes performance, IPerformanceAttributes perfectPerformance)
{ {
Performance = performance; Performance = performance;
PerfectPerformance = perfectPerformance; PerfectPerformance = perfectPerformance;

View File

@ -41,18 +41,18 @@ namespace osu.Game.Rulesets.Difficulty
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
PerformanceAttributes[] performanceArray = await Task.WhenAll( IPerformanceAttributes[] performanceArray = await Task.WhenAll(
// compute actual performance // compute actual performance
performanceCalculator.CalculateAsync(score, attributes.Value.Attributes, cancellationToken), performanceCalculator.CalculateAsync(score, attributes.Value.Attributes, cancellationToken),
// compute performance for perfect play // compute performance for perfect play
getPerfectPerformance(score, cancellationToken) getPerfectPerformance(score, cancellationToken)
).ConfigureAwait(false); ).ConfigureAwait(false);
return new PerformanceBreakdown(performanceArray[0] ?? new PerformanceAttributes(), performanceArray[1] ?? new PerformanceAttributes()); return new PerformanceBreakdown(performanceArray[0] ?? new EmptyPerformanceAttributes(), performanceArray[1] ?? new EmptyPerformanceAttributes());
} }
[ItemCanBeNull] [ItemCanBeNull]
private Task<PerformanceAttributes> getPerfectPerformance(ScoreInfo score, CancellationToken cancellationToken = default) private Task<IPerformanceAttributes> getPerfectPerformance(ScoreInfo score, CancellationToken cancellationToken = default)
{ {
return Task.Run(async () => return Task.Run(async () =>
{ {
@ -117,5 +117,12 @@ namespace osu.Game.Rulesets.Difficulty
yield return hitObject.Judgement.MaxResult; yield return hitObject.Judgement.MaxResult;
} }
public class EmptyPerformanceAttributes : IPerformanceAttributes
{
public double Total { get; set; } = 0;
public IEnumerable<PerformanceDisplayAttribute> GetAttributesForDisplay() => [];
}
} }
} }

View File

@ -17,20 +17,20 @@ namespace osu.Game.Rulesets.Difficulty
Ruleset = ruleset; Ruleset = ruleset;
} }
public Task<PerformanceAttributes> CalculateAsync(ScoreInfo score, DifficultyAttributes attributes, CancellationToken cancellationToken) public Task<IPerformanceAttributes> CalculateAsync(ScoreInfo score, DifficultyAttributes attributes, CancellationToken cancellationToken)
=> Task.Run(() => CreatePerformanceAttributes(score, attributes), cancellationToken); => Task.Run(() => CreatePerformanceAttributes(score, attributes), cancellationToken);
public PerformanceAttributes Calculate(ScoreInfo score, DifficultyAttributes attributes) public IPerformanceAttributes Calculate(ScoreInfo score, DifficultyAttributes attributes)
=> CreatePerformanceAttributes(score, attributes); => CreatePerformanceAttributes(score, attributes);
public PerformanceAttributes Calculate(ScoreInfo score, IWorkingBeatmap beatmap) public IPerformanceAttributes Calculate(ScoreInfo score, IWorkingBeatmap beatmap)
=> Calculate(score, Ruleset.CreateDifficultyCalculator(beatmap).Calculate(score.Mods)); => Calculate(score, Ruleset.CreateDifficultyCalculator(beatmap).Calculate(score.Mods));
/// <summary> /// <summary>
/// Creates <see cref="PerformanceAttributes"/> to describe a score's performance. /// Creates <see cref="IPerformanceAttributes"/> to describe a score's performance.
/// </summary> /// </summary>
/// <param name="score">The score to create the attributes for.</param> /// <param name="score">The score to create the attributes for.</param>
/// <param name="attributes">The difficulty attributes for the beatmap relating to the score.</param> /// <param name="attributes">The difficulty attributes for the beatmap relating to the score.</param>
protected abstract PerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes); protected abstract IPerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes);
} }
} }

View File

@ -156,8 +156,8 @@ namespace osu.Game.Screens.Ranking.Statistics
var perfectDisplayAttributes = breakdown.PerfectPerformance.GetAttributesForDisplay(); var perfectDisplayAttributes = breakdown.PerfectPerformance.GetAttributesForDisplay();
setTotalValues( setTotalValues(
displayAttributes.First(a => a.PropertyName == nameof(PerformanceAttributes.Total)), displayAttributes.First(a => a.PropertyName == nameof(IPerformanceAttributes.Total)),
perfectDisplayAttributes.First(a => a.PropertyName == nameof(PerformanceAttributes.Total)) perfectDisplayAttributes.First(a => a.PropertyName == nameof(IPerformanceAttributes.Total))
); );
var rowDimensions = new List<Dimension>(); var rowDimensions = new List<Dimension>();
@ -165,7 +165,7 @@ namespace osu.Game.Screens.Ranking.Statistics
foreach (PerformanceDisplayAttribute attr in displayAttributes) foreach (PerformanceDisplayAttribute attr in displayAttributes)
{ {
if (attr.PropertyName == nameof(PerformanceAttributes.Total)) continue; if (attr.PropertyName == nameof(IPerformanceAttributes.Total)) continue;
var row = createAttributeRow(attr, perfectDisplayAttributes.First(a => a.PropertyName == attr.PropertyName)); var row = createAttributeRow(attr, perfectDisplayAttributes.First(a => a.PropertyName == attr.PropertyName));