mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 07:42:57 +08:00
Refactor
This commit is contained in:
parent
2de076a74b
commit
88fc53200e
@ -14,7 +14,6 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Scoring;
|
||||
@ -67,7 +66,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
||||
if (value?.Scores.Any() != true)
|
||||
return;
|
||||
|
||||
scoreManager.GetOrderedScoresAsync(value.Scores.Select(s => s.CreateScoreInfo(rulesets)).ToArray(), loadCancellationSource.Token)
|
||||
scoreManager.OrderByTotalScoreAsync(value.Scores.Select(s => s.CreateScoreInfo(rulesets)).ToArray(), loadCancellationSource.Token)
|
||||
.ContinueWith(ordered => Schedule(() =>
|
||||
{
|
||||
if (loadCancellationSource.IsCancellationRequested)
|
||||
|
@ -34,7 +34,6 @@ namespace osu.Game.Scoring
|
||||
|
||||
protected override string ImportFromStablePath => Path.Combine("Data", "r");
|
||||
|
||||
private readonly Bindable<ScoringMode> scoringMode = new Bindable<ScoringMode>();
|
||||
private readonly RulesetStore rulesets;
|
||||
private readonly Func<BeatmapManager> beatmaps;
|
||||
|
||||
@ -52,8 +51,6 @@ namespace osu.Game.Scoring
|
||||
this.beatmaps = beatmaps;
|
||||
this.difficulties = difficulties;
|
||||
this.configManager = configManager;
|
||||
|
||||
configManager?.BindWith(OsuSetting.ScoreDisplayMode, scoringMode);
|
||||
}
|
||||
|
||||
protected override ScoreInfo CreateModel(ArchiveReader archive)
|
||||
@ -106,14 +103,20 @@ namespace osu.Game.Scoring
|
||||
=> base.CheckLocalAvailability(model, items)
|
||||
|| (model.OnlineScoreID != null && items.Any(i => i.OnlineScoreID == model.OnlineScoreID));
|
||||
|
||||
public async Task<ScoreInfo[]> GetOrderedScoresAsync(ScoreInfo[] scores, CancellationToken cancellationToken = default)
|
||||
/// <summary>
|
||||
/// Orders an array of <see cref="ScoreInfo"/>s by total score.
|
||||
/// </summary>
|
||||
/// <param name="scores">The array of <see cref="ScoreInfo"/>s to reorder.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to cancel the process.</param>
|
||||
/// <returns>The given <paramref name="scores"/> ordered by decreasing total score.</returns>
|
||||
public async Task<ScoreInfo[]> OrderByTotalScoreAsync(ScoreInfo[] scores, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var difficultyCache = difficulties?.Invoke();
|
||||
|
||||
if (difficultyCache == null)
|
||||
return orderByTotalScore(scores);
|
||||
|
||||
// Compute difficulties asynchronously first to prevent blocks on the main thread.
|
||||
// Compute difficulties asynchronously first to prevent blocking via the GetTotalScore() call below.
|
||||
foreach (var s in scores)
|
||||
{
|
||||
await difficultyCache.GetDifficultyAsync(s.Beatmap, s.Ruleset, s.Mods, cancellationToken).ConfigureAwait(false);
|
||||
@ -122,7 +125,7 @@ namespace osu.Game.Scoring
|
||||
|
||||
return orderByTotalScore(scores);
|
||||
|
||||
ScoreInfo[] orderByTotalScore(IEnumerable<ScoreInfo> incoming) => incoming.OrderByDescending(GetTotalScore).ThenBy(s => s.OnlineScoreID).ToArray();
|
||||
ScoreInfo[] orderByTotalScore(IEnumerable<ScoreInfo> incoming) => incoming.OrderByDescending(s => GetTotalScore(s)).ThenBy(s => s.OnlineScoreID).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -150,9 +153,22 @@ namespace osu.Game.Scoring
|
||||
/// <returns>The bindable containing the formatted total score string.</returns>
|
||||
public Bindable<string> GetBindableTotalScoreString(ScoreInfo score) => new TotalScoreStringBindable(GetBindableTotalScore(score));
|
||||
|
||||
public long GetTotalScore(ScoreInfo score) => GetTotalScoreAsync(score).Result;
|
||||
/// <summary>
|
||||
/// Retrieves the total score of a <see cref="ScoreInfo"/> in the given <see cref="ScoringMode"/>.
|
||||
/// </summary>
|
||||
/// <param name="score">The <see cref="ScoreInfo"/> to calculate the total score of.</param>
|
||||
/// <param name="mode">The <see cref="ScoringMode"/> to return the total score as.</param>
|
||||
/// <returns>The total score.</returns>
|
||||
public long GetTotalScore(ScoreInfo score, ScoringMode mode = ScoringMode.Standardised) => GetTotalScoreAsync(score).Result;
|
||||
|
||||
public async Task<long> GetTotalScoreAsync(ScoreInfo score, CancellationToken cancellationToken = default)
|
||||
/// <summary>
|
||||
/// Retrieves the total score of a <see cref="ScoreInfo"/> in the given <see cref="ScoringMode"/>.
|
||||
/// </summary>
|
||||
/// <param name="score">The <see cref="ScoreInfo"/> to calculate the total score of.</param>
|
||||
/// <param name="mode">The <see cref="ScoringMode"/> to return the total score as.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to cancel the process.</param>
|
||||
/// <returns>The total score.</returns>
|
||||
public async Task<long> GetTotalScoreAsync(ScoreInfo score, ScoringMode mode = ScoringMode.Standardised, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (score.Beatmap == null)
|
||||
return score.TotalScore;
|
||||
@ -204,7 +220,7 @@ namespace osu.Game.Scoring
|
||||
var scoreProcessor = ruleset.CreateScoreProcessor();
|
||||
scoreProcessor.Mods.Value = score.Mods;
|
||||
|
||||
return (long)Math.Round(scoreProcessor.GetScore(scoringMode.Value, beatmapMaxCombo, accuracy, (double)score.MaxCombo / beatmapMaxCombo, score.Statistics));
|
||||
return (long)Math.Round(scoreProcessor.GetScore(mode, beatmapMaxCombo, accuracy, (double)score.MaxCombo / beatmapMaxCombo, score.Statistics));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -221,7 +237,7 @@ namespace osu.Game.Scoring
|
||||
/// <param name="scoreManager">The <see cref="ScoreManager"/>.</param>
|
||||
public TotalScoreBindable(ScoreInfo score, ScoreManager scoreManager)
|
||||
{
|
||||
ScoringMode.BindValueChanged(_ => Value = scoreManager.GetTotalScore(score), true);
|
||||
ScoringMode.BindValueChanged(mode => Value = scoreManager.GetTotalScore(score, mode.NewValue), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Scoring;
|
||||
using osuTK;
|
||||
@ -65,6 +66,9 @@ namespace osu.Game.Screens.Ranking
|
||||
[Resolved]
|
||||
private ScoreManager scoreManager { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private BeatmapDifficultyCache difficultyCache { get; set; }
|
||||
|
||||
private readonly CancellationTokenSource loadCancellationSource = new CancellationTokenSource();
|
||||
private readonly Flow flow;
|
||||
private readonly Scroll scroll;
|
||||
@ -120,33 +124,33 @@ namespace osu.Game.Screens.Ranking
|
||||
};
|
||||
});
|
||||
|
||||
scoreManager.GetOrderedScoresAsync(new[] { score })
|
||||
.ContinueWith(_ => Schedule(() =>
|
||||
{
|
||||
flow.Add(panel.CreateTrackingContainer().With(d =>
|
||||
{
|
||||
d.Anchor = Anchor.Centre;
|
||||
d.Origin = Anchor.Centre;
|
||||
}));
|
||||
difficultyCache.GetDifficultyAsync(score.Beatmap, score.Ruleset, score.Mods)
|
||||
.ContinueWith(_ => Schedule(() =>
|
||||
{
|
||||
flow.Add(panel.CreateTrackingContainer().With(d =>
|
||||
{
|
||||
d.Anchor = Anchor.Centre;
|
||||
d.Origin = Anchor.Centre;
|
||||
}));
|
||||
|
||||
if (SelectedScore.Value == score)
|
||||
{
|
||||
SelectedScore.TriggerChange();
|
||||
}
|
||||
else
|
||||
{
|
||||
// We want the scroll position to remain relative to the expanded panel. When a new panel is added after the expanded panel, nothing needs to be done.
|
||||
// But when a panel is added before the expanded panel, we need to offset the scroll position by the width of the new panel.
|
||||
if (expandedPanel != null && flow.GetPanelIndex(score) < flow.GetPanelIndex(expandedPanel.Score))
|
||||
{
|
||||
// A somewhat hacky property is used here because we need to:
|
||||
// 1) Scroll after the scroll container's visible range is updated.
|
||||
// 2) Scroll before the scroll container's scroll position is updated.
|
||||
// Without this, we would have a 1-frame positioning error which looks very jarring.
|
||||
scroll.InstantScrollTarget = (scroll.InstantScrollTarget ?? scroll.Target) + ScorePanel.CONTRACTED_WIDTH + panel_spacing;
|
||||
}
|
||||
}
|
||||
}));
|
||||
if (SelectedScore.Value == score)
|
||||
{
|
||||
SelectedScore.TriggerChange();
|
||||
}
|
||||
else
|
||||
{
|
||||
// We want the scroll position to remain relative to the expanded panel. When a new panel is added after the expanded panel, nothing needs to be done.
|
||||
// But when a panel is added before the expanded panel, we need to offset the scroll position by the width of the new panel.
|
||||
if (expandedPanel != null && flow.GetPanelIndex(score) < flow.GetPanelIndex(expandedPanel.Score))
|
||||
{
|
||||
// A somewhat hacky property is used here because we need to:
|
||||
// 1) Scroll after the scroll container's visible range is updated.
|
||||
// 2) Scroll before the scroll container's scroll position is updated.
|
||||
// Without this, we would have a 1-frame positioning error which looks very jarring.
|
||||
scroll.InstantScrollTarget = (scroll.InstantScrollTarget ?? scroll.Target) + ScorePanel.CONTRACTED_WIDTH + panel_spacing;
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
scores = scores.Where(s => s.Mods.Any(m => selectedMods.Contains(m.Acronym)));
|
||||
}
|
||||
|
||||
scoreManager.GetOrderedScoresAsync(scores.ToArray(), loadCancellationSource.Token)
|
||||
scoreManager.OrderByTotalScoreAsync(scores.ToArray(), loadCancellationSource.Token)
|
||||
.ContinueWith(ordered => scoresCallback?.Invoke(ordered.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
|
||||
|
||||
return null;
|
||||
@ -192,7 +192,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
|
||||
req.Success += r =>
|
||||
{
|
||||
scoreManager.GetOrderedScoresAsync(r.Scores.Select(s => s.CreateScoreInfo(rulesets)).ToArray(), loadCancellationSource.Token)
|
||||
scoreManager.OrderByTotalScoreAsync(r.Scores.Select(s => s.CreateScoreInfo(rulesets)).ToArray(), loadCancellationSource.Token)
|
||||
.ContinueWith(ordered => Schedule(() =>
|
||||
{
|
||||
if (loadCancellationSource.IsCancellationRequested)
|
||||
|
Loading…
Reference in New Issue
Block a user