mirror of
https://github.com/ppy/osu.git
synced 2026-05-17 17:33:02 +08:00
Merge pull request #33809 from frenzibyte/fix-leaderboard-loading
Fix leaderboard wedge updating scores in non-update thread
This commit is contained in:
@@ -7,6 +7,7 @@ using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Development;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Beatmaps;
|
||||
@@ -24,7 +25,11 @@ namespace osu.Game.Online.Leaderboards
|
||||
{
|
||||
public partial class LeaderboardManager : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The latest leaderboard scores fetched by the criteria in <see cref="CurrentCriteria"/>.
|
||||
/// </summary>
|
||||
public IBindable<LeaderboardScores?> Scores => scores;
|
||||
|
||||
private readonly Bindable<LeaderboardScores?> scores = new Bindable<LeaderboardScores?>();
|
||||
|
||||
public LeaderboardCriteria? CurrentCriteria { get; private set; }
|
||||
@@ -47,6 +52,9 @@ namespace osu.Game.Online.Leaderboards
|
||||
/// </summary>
|
||||
public void FetchWithCriteria(LeaderboardCriteria newCriteria, bool forceRefresh = false)
|
||||
{
|
||||
if (!ThreadSafety.IsUpdateThread)
|
||||
throw new InvalidOperationException(@$"{nameof(FetchWithCriteria)} must be called from the update thread.");
|
||||
|
||||
if (!forceRefresh && CurrentCriteria?.Equals(newCriteria) == true && scores.Value?.FailState == null)
|
||||
return;
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ namespace osu.Game.Screens.Ranking
|
||||
{
|
||||
private readonly IBindable<LeaderboardScores?> globalScores = new Bindable<LeaderboardScores?>();
|
||||
|
||||
private TaskCompletionSource<LeaderboardScores>? requestTaskSource;
|
||||
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; } = null!;
|
||||
|
||||
@@ -37,6 +39,14 @@ namespace osu.Game.Screens.Ranking
|
||||
globalScores.BindTo(leaderboardManager.Scores);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (requestTaskSource?.Task.IsCompleted == false)
|
||||
requestTaskSource.SetCanceled();
|
||||
}
|
||||
|
||||
protected override async Task<ScoreInfo[]> FetchScores()
|
||||
{
|
||||
Debug.Assert(Score != null);
|
||||
@@ -48,13 +58,18 @@ namespace osu.Game.Screens.Ranking
|
||||
leaderboardManager.CurrentCriteria?.Scope ?? BeatmapLeaderboardScope.Global,
|
||||
leaderboardManager.CurrentCriteria?.ExactMods
|
||||
);
|
||||
var requestTaskSource = new TaskCompletionSource<LeaderboardScores>();
|
||||
|
||||
Debug.Assert(requestTaskSource == null || requestTaskSource.Task.IsCompleted);
|
||||
|
||||
requestTaskSource = new TaskCompletionSource<LeaderboardScores>();
|
||||
|
||||
globalScores.BindValueChanged(_ =>
|
||||
{
|
||||
if (globalScores.Value != null && leaderboardManager.CurrentCriteria?.Equals(criteria) == true)
|
||||
requestTaskSource.TrySetResult(globalScores.Value);
|
||||
});
|
||||
leaderboardManager.FetchWithCriteria(criteria, forceRefresh: true);
|
||||
|
||||
Schedule(() => leaderboardManager.FetchWithCriteria(criteria, forceRefresh: true));
|
||||
|
||||
var result = await requestTaskSource.Task.ConfigureAwait(false);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user