I'm doing this silently to see if any users complain without being told
about the change. Without this, when holding left arrow for short
bursts, precisely *one* beatmap change happens before actual key repeat
kicks in, which feels really weird (updates the leaderboard / background
unexpectedly).
This is the simplest way to resolve the issue, so if users aren't
offended by it I think we should commit to it.
Personally it's still fast enough to not annoy me at all.
This should better account for scenarios where user FPS is below 60 fps.
Previously the debounce would unexpectedly be longer than usual for low
FPS scenarios.
This is probably where things get a little controversial.
There are some song select flows wherein song select just wants to
ensure sanity by authoritatively setting the global beatmap. The goal is
to change the beatmap immediately and instantly. Therefore it should
kind of be the carousel's job to figure out its grouping complications.
To that end, `CurrentSelection` is made virtual, and overridden in
`BeatmapCarousel` to perform a sort of reconciliation logic. If an
external component sets `CurrentSelection` to a `BeatmapInfo`, one of
the two following things happen:
- Nothing, if the current `GroupedBeatmap` is already a copy of the
beatmap that needs to be selected, or
- The carousel looks at its items, finds any first copy which matches
the beatmap that the external consumer wanted selected, and changes
selection to that instead.
Basically, `BeatmapCarousel.CurrentSelection`, which is
magic-object-typed, can no longer use `BeatmapInfo` directly, it now
must also use `GroupedBeatmap`.
This spills out all the way into song select because of beatmap
selection flows that require hookup from song select.
Closes https://github.com/ppy/osu/issues/34731.
The failure scenario here is as follows:
- User holds down left mouse button for >200ms to reveal the background.
- User presses down another mouse button and releases it in <200ms.
- User releases left mouse button. Song select does not return.
The timing here is key because what is happening here is that the second
mouse button press is overwriting the `revealingBackground` scheduled
delegate. Releasing that same mouse button within 200ms leads to that
scheduled delegate being cancelled and cleared, and thus the release of
left mouse wrongly decides there is nothing left to do.
One thing I'm not entirely sure about is the release behaviour even with
this change; as things stand, the first release of any mouse button will
bring song select back, even if it was not the button that was initially
held down to reveal the background. That's probably easily fixed if
deemed required, but I'm most interested in fixing the bad breakage.
Addresses abrupt playback pointed out in
https://github.com/ppy/osu/discussions/34472.
In cases where the music is already playing, this isn't required (ie
when returning from the player loading screen before gameplay starts).
Takes changes in https://github.com/ppy/osu/pull/34233 and removes *all*
of the complexity.
Supersedes and closes#34233.
Contains same caveat that we can only display one beatmap once in the
carousel; this will be addressed separately.
Closes https://github.com/ppy/osu/issues/34445.
The primary issue is that song select is the only one that supports
non-score sort mode, and therefore if any other component changes the
sort mode in a way opaque to song select to score, then song select will
lose the sort mode because it's using the global leaderboard manager's
state which will contain scores sorted by total.
Notably, the bug this is fixing requires specific circumstances. For
instance, it is not enough to just *start gameplay* for the bug to
manifest, because starting gameplay causes a working beatmap refetch:
https://github.com/ppy/osu/blob/4b73afd1957a9161e2956fc4191c8114d9958372/osu.Game/Screens/SelectV2/SongSelect.cs#L456-L457
which will trigger a *delayed schedule refetch* of the scores:
https://github.com/ppy/osu/blob/d2d3d14f1572ff8fc68fd01ea43c2ef68b5882fa/osu.Game/Screens/SelectV2/BeatmapLeaderboardWedge.cs#L235-L253
and because the refetch is thusly delayed, there's a very high chance it
*will not run before the screen is resumed* because the wedge will not
have its scheduler run until that point in time.
This conundrum is also because there is no test coverage for this,
because the above makes test coverage setup rather annoying.
The way that this works is that it plugs into the online request to
retrieve the beatmap set that the client is already performing, and
stores user tag data to the local realm database.
This means that for now user tags will only populate for beatmaps that
the user has displayed on song select which is obviously subpar. I plan
to follow this change up by adding user tag state dumps to `online.db`
and using that data for initial tag population to make the majority case
(ranked beatmaps) work.
Note that several decisions were made here that are potential discussion
points:
- `RealmPopulatingOnlineLookupSource` is set up such that it can be the
middle man / redirection point for similar flows that we need and we
are currently missing, such as storing guest difficulty information,
or storing the user's current best score on a beatmap (handy for rank
achieved sorting / filtering / etc.)
- The user tags are stored in `BeatmapMetadata` which breaks the
longstanding assumption that you can arbitrarily pull out a metadata
instance from any of the beatmaps in a set and get essentially the
same object back.
I've attempted to constrain this some by not adding user tags to
the `IBeatmapMetadataInfo` interface through which `BeatmapSetInfo`
exposes metadata further, but I warn in advance that this is
a temporary state of affairs and I will make it worse in the future
when `BeatmapMetadata.Author` becomes `Authors` plural in order to
support guest mapper display (and direct guest difficulty submission).
- The syntax for searching via user tags is chosen to mostly match web -
it's `tag=`, with support for all of the string matching modes song
select already has (bare word for substring, `""` quotes for phrase
isolated by whitespace, `""!` for exact full match).
This is being run in the flow where we are providing a specific beatmap
for immediately selection. In an edge case scenario, the carousel may be
pending on a filter operation, which would cause the whole `SelectAndRun`
call to fail when it doesn't need to.
This is reproduced by multiple test scenes. One example is
`TestSceneOpenEditorTimestamp.TestErrorNotifications`.