1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-13 20:33:35 +08:00
Commit Graph

5 Commits

  • Update lots of packages (#36996)
    It's been a while.
    
    Notes:
    
    - `SharpCompress` usages changed a bit. Manually adjusted these, mostly
    just renames or adjusted parameters.
    - nUnit 3 -> 4 migrated using
    https://gist.github.com/peppy/07994386d793a117350cb5f24b156585. there's
    a mode in this script to update to the newer `Assert.That` syntax but it
    requires fixes and couldn't really be bothered.
    - DeepEqual nuked as the only usage was on a disabled test. The reason
    it's disabled has been merged upstream, but it's failing for other
    (realm) reasons which I don't think is worthwhile to investigate for
    now.
    - This bumps Moq. I think the author is back in a sensible headspace and
    the new version has the stupid shit removed, so probably okay? Nice to
    be on a level playing field with packages for once in a long time.
    - Automapper is silly, but we've discussed this elsewhere.
    - `TestRealmKeyBindingStore` failures are a wildcard, but fixed by using
    a more standardised testing method. Dunno why, don't care.
    
    ---------
    
    Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
  • Fix lifetime calculation in overlapping algorithm
    Changes to lifetime calculation in scrolling rulesets introduced in
    #7367, which aimed to account for the distance between hit objects'
    origin and its edge entering the scrolling area, fixed some issues with
    hitobjects appearing abruptly, but also regressed some other scenarios.
    
    Upon investigation, the regression was localised to the overlapping
    scroll algorithm. The reason for this was two-fold:
    
    * The previous code used TimeAt() to calculate the time of travel from
      the hit object's edge to its origin. For other algorithms, that time
      can be accurately reconstructed, because they don't have periods of
      time where there are multiple hit objects scrolling at different
      velocities.
    
      That invariant does not hold for the overlapping algorithm, therefore
      it is possible for different values to be technically correct for
      TimeAt(). However, the only value that matters for the adjustment
      is the one that's indicated by the control point that applies to the
      hit object origin, which can be uniquely identified.
    
    * Additionally, the offset returned (even if correct) was applied
      externally to the hit object's start time and passed to
      GetDisplayStartTime(). In the overlapping algorithm, the choice of
      control point used in GetDisplayStartTime() is important, since
      the value of the speed multiplier is read within.
    
      Externally rewinding the hit object's start time meant that in some
      cases the speed multiplier of the *previous* control point is applied,
      which led to hit objects appearing too late if the scrolling rate
      decreased.
    
    Because of the above, modify GetDisplayStartTime() to take the offset
    into account in all algorithms, and apply the adjustment correctly
    inside of them. The constant and sequential algorithms needed no
    adjustment from the previous logic, since:
    
    * the constant algorithm disregarded control points, and
    * the sequential algorithm would effectively rewind to time = 0,
      calculate the absolute distance from time = 0 to the hit object start,
      apply the origin offset *to the absolute distance*, and then convert
      back to time, applying all control points in sequence. Due to this
      it was impossible for control points to get mixed up while
      calculating.
    
    As for the overlapping algorithm, the high-level logic is as follows:
    
    * The distance that the origin has to travel is the length of the scroll
      plus the distance from the origin to the object edge.
    * The above distance divided by the scroll length gives the relative
      scroll lengths that the object has to travel.
    * As one relative scroll length takes one time range, the relative
      travel length multiplied by the time range gives the absolute travel
      time of the object origin.
    * Finally, the control point multiplier applicable at origin time is
      applied to the whole travel time.
    
    Correctness of the above is demonstrated by visual tests added before
    and headless unit tests of the algorithms themselves. The sequential
    scroll algorithm was not covered by unit tests, and remains uncovered
    due to floating-point inaccuracies that should be addressed separately.