Fix gameplay leaderboard not being sorted correctly in tie situations

This commit is contained in:
Dean Herbert 2022-09-14 14:18:12 +09:00
parent 8a6977213a
commit fcf54f1bc8
4 changed files with 16 additions and 1 deletions

View File

@ -88,6 +88,7 @@ public ILeaderboardScore Add(IUser? user, bool isTracked)
Flow.Add(drawable);
drawable.TotalScore.BindValueChanged(_ => sorting.Invalidate(), true);
drawable.DisplayOrder.BindValueChanged(_ => sorting.Invalidate(), true);
int displayCount = Math.Min(Flow.Count, max_panels);
Height = displayCount * (GameplayLeaderboardScore.PANEL_HEIGHT + Flow.Spacing.Y);
@ -160,7 +161,10 @@ private void sort()
if (sorting.IsValid)
return;
var orderedByScore = Flow.OrderByDescending(i => i.TotalScore.Value).ToList();
var orderedByScore = Flow
.OrderByDescending(i => i.TotalScore.Value)
.ThenBy(i => i.DisplayOrder.Value)
.ToList();
for (int i = 0; i < Flow.Count; i++)
{

View File

@ -55,6 +55,7 @@ public class GameplayLeaderboardScore : CompositeDrawable, ILeaderboardScore
public BindableDouble Accuracy { get; } = new BindableDouble(1);
public BindableInt Combo { get; } = new BindableInt();
public BindableBool HasQuit { get; } = new BindableBool();
public Bindable<long> DisplayOrder { get; } = new Bindable<long>();
public Color4? BackgroundColour { get; set; }

View File

@ -14,5 +14,11 @@ public interface ILeaderboardScore
BindableInt Combo { get; }
BindableBool HasQuit { get; }
/// <summary>
/// An optional value to guarantee stable ordering.
/// Lower numbers will appear higher in cases of <see cref="TotalScore"/> ties.
/// </summary>
Bindable<long> DisplayOrder { get; }
}
}

View File

@ -55,6 +55,9 @@ private void showScores()
local.Accuracy.BindTarget = scoreProcessor.Accuracy;
local.Combo.BindTarget = scoreProcessor.Combo;
// Local score should always show lower than any existing scores in cases of ties.
local.DisplayOrder.Value = long.MaxValue;
foreach (var s in scores)
{
var score = Add(s.User, false);
@ -67,6 +70,7 @@ private void showScores()
score.Accuracy.Value = s.Accuracy;
score.Combo.Value = s.MaxCombo;
score.DisplayOrder.Value = s.OnlineID > 0 ? s.OnlineID : s.Date.ToUnixTimeSeconds();
}
}
}