Storing `DrawableHitObject` for later use is not safe – especially
when accessing `HitObject` – as it's a pooled class. In the case here,
it's important to note that `PrepareForUse` can be called a frame or
more later in execution, which made this unsafe.
Closes https://github.com/ppy/osu/issues/24444.
Regressed in https://github.com/ppy/osu/pull/25216.
The new logic will ensure at least one tick is ready for judgement.
There shouldn't be a case where more than one is needed in a single
frame.
Doesn't do much for the client; mostly a safety for osu-web's sake,
as without the change it could theoretically fail to validate the mod
properly in multiplayer contexts.
Intends to fix test failures as seen in https://github.com/ppy/osu/actions/runs/6692350567/job/18181352642#step:5:129
This is what happens if you carelessly fire and forget.
The working theory (that I'm not sure I have the tools to conclusively
confirm) is that the async write from the key binding changing could
fire _after_ the section is reset.
I briefly considered having the test wait for the change, but given that
the entirety of the surrounding flow is using sync operations, this just
looks like a bug to me. And there's no real sane way to inject async
into that flow due to dependence on `OsuButton.Action`.
Probably CI running slow timing balls.
The point of failure is `waitUntilStoryboardSamplesPlay()`
after already testing the important part of the test (that
the samples stop on skip) so let's give it another possible
point to recover.
See https://github.com/ppy/osu/actions/runs/6698399814/job/18201753701.
Checking the delta after the application of rate is not correct. The
delta is in screen-space *before* the rate from rate-changing mods were
applied; the point of the application of the rate is to compensate for
the fact that the spinner is still judged in "track time" - but the goal
is to keep the spinner's difficulty *independent* of rate, which means
that with DT active the user's spin is "twice as effective" to
compensate for the fact that the spinner is twice as short in real time.
In another formulation, with DT active, the user gets to record replay
frames "half as often" as in normal gameplay.
Closes https://github.com/ppy/osu/issues/25239.
`LegacyEditorBeatmapPatcher.processHitObjectLocalData()` was already
supposed to be handling changes to hitobjects that will show up neither
when comparing the hitobjects themselves or the timing point with
"legacy" info stripped - so, in other words, changes to slider velocity
and samples.
However, a change to slider velocity requires default application to
take effect, so just resetting the value would visually fix the timeline
marker but not change the actual object. Calling
`EditorBeatmap.Update()` fixes this by way of triggering default
re-application.
This could probably be smarter (by only invoking the update when
strictly necessary, etc.) - but I'm not sure it's worth the hassle. This
is intended to be a quick fix, rather than a complete solution - the
complete solution would indeed likely entail a wholesale restructuring
of the editor's change handling.