RFC. Another attempt at this.
- Supersedes https://github.com/ppy/osu/pull/31881
- Supersedes / closes https://github.com/ppy/osu/pull/31355
- Closes https://github.com/ppy/osu/issues/29861
This is a weird diff because I am feeling rather boxed in by all the
constraints, namely that:
- Leaderboard state should be global state
- But the global state is essentially managed by song select and namely
`BeatmapLeaderboard` itself. That's because trying to e.g. not have
`BeatmapLeaderboard` pass the beatmap and the ruleset to the global
leaderboard manager is worse, as it essentially introduces two
parallel paths of execution that need to be somehow merged into one
(as in I'd have to somehow sync `LeaderboardManager` responding to
beatmap/ruleset changes with `BeatmapLeaderboard` which is inheritance
hell)
- Also local leaderboard fetching is data-push (as in the scores can
change under the leaderboard manager), and online leaderboard fetching
is data-pull (as in the scores do not change unless the leaderboard
manager does something). Also online leaderboard fetching can fail.
Which is why I need to still have the weird setup wherein there's a
`FetchWithCriteriaAsync()` (because I need to be able to respond to
online requests taking time, or failing), but also the
`BeatmapLeaderboard` only uses the public `Scores` bindable to
actually read the scores (because it needs to respond to new local
scores arriving).
- Another thing to think about here is what happens when a retrieval
fails because e.g. the user requested friend leaderboards without
having supporter. With how this diff is written, that special
condition is handled to `BeatmapLeaderboard`, and
`LeaderboardManager`'s state will remain as whatever it was before
that scope change was requested, which may be considered good or it
may not (I imagine it's better to show scores in gameplay than not in
this case, but maybe I'm wrong?)
One of my pending work items for post-realm merge.
The lowest-level import task is no longer asynchronous, as we don't want
it to span multiple threads to allow easier interaction with realm.
Removing the `Task` spec simplifies a heap of usages.
Individual usages should decide whether they want to run the import
asynchronously, by either using an alternative override or spooling up a
thread themselves.