Introduce StartFrame and EndFrame to simplify the replay interpolation code

This commit is contained in:
ekrctb
2021-04-16 12:53:58 +09:00
parent 84bc81a6de
commit 91c7d8d26c
5 changed files with 33 additions and 72 deletions

View File

@ -33,32 +33,42 @@ namespace osu.Game.Rulesets.Replays
/// The current time is always between the start and the end time of the current frame.
/// </summary>
/// <remarks>Returns null if the current time is strictly before the first frame.</remarks>
public TFrame? CurrentFrame => currentFrameIndex == -1 ? null : (TFrame)Frames[currentFrameIndex];
/// <summary>
/// The next frame of the replay.
/// The start time of <see cref="NextFrame"/> is always greater or equal to the start time of <see cref="CurrentFrame"/> regardless of the seeking direction.
/// </summary>
/// <remarks>Returns null if the current frame is the last frame.</remarks>
public TFrame? NextFrame => currentFrameIndex == Frames.Count - 1 ? null : (TFrame)Frames[currentFrameIndex + 1];
/// <summary>
/// The frame for the start value of the interpolation of the replay movement.
/// </summary>
/// <exception cref="InvalidOperationException">The replay is empty.</exception>
public TFrame? CurrentFrame
public TFrame StartFrame
{
get
{
if (!HasFrames)
throw new InvalidOperationException($"Attempted to get {nameof(CurrentFrame)} of an empty replay");
throw new InvalidOperationException($"Attempted to get {nameof(StartFrame)} of an empty replay");
return currentFrameIndex == -1 ? null : (TFrame)Frames[currentFrameIndex];
return (TFrame)Frames[Math.Max(0, currentFrameIndex)];
}
}
/// <summary>
/// The next frame of the replay.
/// The start time is always greater or equal to the start time of <see cref="CurrentFrame"/> regardless of the seeking direction.
/// The frame for the end value of the interpolation of the replay movement.
/// </summary>
/// <remarks>Returns null if the current frame is the last frame.</remarks>
/// <exception cref="InvalidOperationException">The replay is empty.</exception>
public TFrame? NextFrame
public TFrame EndFrame
{
get
{
if (!HasFrames)
throw new InvalidOperationException($"Attempted to get {nameof(NextFrame)} of an empty replay");
throw new InvalidOperationException($"Attempted to get {nameof(EndFrame)} of an empty replay");
return currentFrameIndex == Frames.Count - 1 ? null : (TFrame)Frames[currentFrameIndex + 1];
return (TFrame)Frames[Math.Min(currentFrameIndex + 1, Frames.Count - 1)];
}
}
@ -98,11 +108,11 @@ namespace osu.Game.Rulesets.Replays
{
get
{
if (!HasFrames || !FrameAccuratePlayback || CurrentFrame == null)
if (!HasFrames || !FrameAccuratePlayback || currentFrameIndex == -1)
return false;
return IsImportant(CurrentFrame) && // a button is in a pressed state
Math.Abs(CurrentTime - NextFrame?.Time ?? 0) <= AllowedImportantTimeSpan; // the next frame is within an allowable time span
return IsImportant(StartFrame) && // a button is in a pressed state
Math.Abs(CurrentTime - EndFrame.Time) <= AllowedImportantTimeSpan; // the next frame is within an allowable time span
}
}