RFC. Closes https://github.com/ppy/osu/issues/18169.
Implements the given proposal of keeping the current stable order but
adding a shuffle facility to the now playing overlay, and enabling it by
default.
There are more changes I want to make here but I'd like this to get
discussion first, because I am likely to continue putting this sort of
selection logic into `MusicController` and I just want to confirm nobody
is going to have a problem with that.
In particular this is not sharing the randomisation implementation with
beatmap carousel because it doesn't generalise nicely (song select cares
about the particular *beatmap difficulties* selected to rewind properly,
while the music controller only cares about picking a *beatmap set*).
It didn't ever really make sense for it to be sharing the implementation
details of that (e.g. colouring of primary/dangerous actions), and with
the hotkey display things got outright hacky, so I'm decoupling it
entirely.
Not entirely sure why they were failing previously, but the most likely
explanation is that by freak accident some mock requests would
previously execute immediately rather than be scheduled on the API
thread, which would change execution ordering and ensure that
`ChannelManager.CurrentChannel` would become the joined channel, rather
than remaining at the channel listing.
These used to work because there was a huge blocking load operation,
which is now more asynchronous.
Note that the change made in `SongSelect` is not required, but defensive
(feels it should have been doing this the whole time).
The only exception to the rule here was "when screen isn't active apply
without debounce" but I'm not sure we want this. It would cause a
stutter on returning to song select and I'm not even sure this is a
common scenario.
I'd rather remove it and see if someone finds an actual case where this
is an issue.
This reverts a portion of https://github.com/ppy/osu/pull/9539.
The rearrangement in `SongSelect` is required to get the initial filter
into `BeatmapCarousel` (and avoid the `FilterChanged` event firing,
causing a delayed/scheduled filter application).