Skip to content

Remove LeaderboardManager return value and simplify flow further #32913

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 23, 2025

Conversation

peppy
Copy link
Member

@peppy peppy commented Apr 22, 2025

While working through #32844, it became apparent that both @frenzibyte's copy-pasted code was out of date with recent leaderboard changes, and some refactors I made were only applied local in that branch (and not to the old Leaderboard).

This attempts to resolve the issues I came across. See 1e76843 commit message for rationale.

peppy added 2 commits April 22, 2025 19:29
The rationale for this change is that the return value was mostly
useless, and at worst, misleading.

When using `LeaderboardManager`, it's assumed that a consumer will bind
to the global `Scores` list to ensure they receive updates for things
like local score changes via the internal realm subscription. If one
decides to instead use the return value of the task, it will be a static
snapshot that potentially becomes stale in the future.

I fell into this trap when refactoring the new leaderboard component
(while attempting to assert correctness that the values we are
displaying were in fact from the fetch operation we requested).

In the interest of keeping things simple, removing the return value
seems to be the best path forward.
@bdach
Copy link
Collaborator

bdach commented Apr 22, 2025

I pushed a commit removing some more stuff that doesn't need to be there (also fixed a bug in the process - see if you can spot it).

There's a problem though - this breaks if you select a map, go into player loader, and then go back to menu - the leaderboard will show a spinner rather than the previous scores. This is because the criteria hasn't meaningfully changed so there's no refetch, so the global bindable has not changed value. I'm not sure what is the best way of resolving this.

Something like

diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
index 1c62499162..ef5608cca1 100644
--- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
+++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs
@@ -62,7 +62,7 @@ public bool FilterMods
             }
         }
 
-        private readonly IBindable<LeaderboardScores?> fetchedScores = new Bindable<LeaderboardScores?>();
+        private readonly Bindable<LeaderboardScores?> fetchedScores = new Bindable<LeaderboardScores?>();
 
         [Resolved]
         private IBindable<RulesetInfo> ruleset { get; set; } = null!;
@@ -102,10 +102,12 @@ private void load()
             if (!initialFetchComplete)
             {
                 // only bind this after the first fetch to avoid reading stale scores.
-                fetchedScores.BindTo(leaderboardManager.Scores);
+                ((IBindable<LeaderboardScores?>)fetchedScores).BindTo(leaderboardManager.Scores);
                 fetchedScores.BindValueChanged(_ => updateScores(), true);
                 initialFetchComplete = true;
             }
+            else
+                fetchedScores.TriggerChange();
 
             return null;
         }

seems to work but also seems to be quite dodgy.

@bdach
Copy link
Collaborator

bdach commented Apr 23, 2025

Incidentally, along the similar lines as the previous comment, I'm seeing user reports like https://osu.ppy.sh/community/forums/topics/2069984?n=1, and I can believe why they're happening - the leaderboard isn't refetching after completing a play because the criteria hasn't changed either.

One way to fix this would be to just remove the early guard. (Yes you could have a force parameter or something, but as the current code structure stands you'd just be calling it with force every single time, unless more work is done to make it possible to not force every time.)

Thoughts?

@peppy
Copy link
Member Author

peppy commented Apr 23, 2025

Path of least resistance means that I agree with you. I'll adjust as such, but will leave a force parameter for future use.

@bdach bdach added the next release Pull requests which are almost there. We'll aim to get them in the next release, but no guarantees! label Apr 23, 2025
@bdach
Copy link
Collaborator

bdach commented Apr 23, 2025

I'm treating this as a hotfix worthy change because it's fixing a real issue of the leaderboards not refetching after returning to song select after a completed play.

@bdach bdach merged commit 7636573 into ppy:master Apr 23, 2025
7 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
next release Pull requests which are almost there. We'll aim to get them in the next release, but no guarantees! size/L type:code-quality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants