diff --git a/osu.Game/Online/Leaderboards/LeaderboardManager.cs b/osu.Game/Online/Leaderboards/LeaderboardManager.cs index 5750c83c97..632771afc1 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardManager.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardManager.cs @@ -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 { + /// + /// The latest leaderboard scores fetched by the criteria in . + /// public IBindable Scores => scores; + private readonly Bindable scores = new Bindable(); public LeaderboardCriteria? CurrentCriteria { get; private set; } @@ -47,6 +52,9 @@ namespace osu.Game.Online.Leaderboards /// 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; diff --git a/osu.Game/Screens/Ranking/SoloResultsScreen.cs b/osu.Game/Screens/Ranking/SoloResultsScreen.cs index aeb21b09cb..eaf0369e32 100644 --- a/osu.Game/Screens/Ranking/SoloResultsScreen.cs +++ b/osu.Game/Screens/Ranking/SoloResultsScreen.cs @@ -20,6 +20,8 @@ namespace osu.Game.Screens.Ranking { private readonly IBindable globalScores = new Bindable(); + private TaskCompletionSource? 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 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(); + + Debug.Assert(requestTaskSource == null || requestTaskSource.Task.IsCompleted); + + requestTaskSource = new TaskCompletionSource(); + 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);