Fix FramedReplayInputHandler incorrectly blocking in streaming mode when time requested is before the first frame

Most of this is just tidying up the logic to (hopefully) be better to
follow, again (again (again)).

The actual fix is that we now allow interpolation/playback when the
incoming time is less than the first frame's time, regardless of
receiving status.
This commit is contained in:
Dean Herbert 2020-10-30 16:09:01 +09:00
parent 0f997386ae
commit 32e68a6a3c
1 changed files with 40 additions and 16 deletions

View File

@ -40,7 +40,7 @@ public TFrame NextFrame
return null;
if (!currentFrameIndex.HasValue)
return (TFrame)Frames[0];
return currentDirection > 0 ? (TFrame)Frames[0] : null;
int nextFrame = clampedNextFrameIndex;
@ -109,30 +109,54 @@ private bool inImportantSection
Debug.Assert(currentDirection != 0);
TFrame next = NextFrame;
// check if the next frame is valid for the current playback direction.
// validity is if the next frame is equal or "earlier" than the current point in time (so we can change to it)
int compare = time.CompareTo(next?.Time);
if (next != null && (compare == 0 || compare == currentDirection))
if (!HasFrames)
{
currentFrameIndex = clampedNextFrameIndex;
return CurrentTime = CurrentFrame.Time;
// in the case all frames are received, allow time to progress regardless.
if (replay.HasReceivedAllFrames)
return CurrentTime = time;
return null;
}
// at this point, the frame can't be advanced (in the replay).
// even so, we may be able to move the clock forward due to being at the end of the replay or
// moving towards the next valid frame.
TFrame next = NextFrame;
// if we have a next frame, check if it is before or at the current time in playback, and advance time to it if so.
if (next != null)
{
int compare = time.CompareTo(next.Time);
if (compare == 0 || compare == currentDirection)
{
currentFrameIndex = clampedNextFrameIndex;
return CurrentTime = CurrentFrame.Time;
}
}
// at this point, the frame index can't be advanced.
// even so, we may be able to propose the clock progresses forward due to being at an extent of the replay,
// or moving towards the next valid frame (ie. interpolating in a non-important section).
// the exception is if currently in an important section, which is respected above all.
if (inImportantSection)
{
Debug.Assert(next != null || !replay.HasReceivedAllFrames);
return null;
}
// in the case we have no next frames and haven't received the full replay, block.
if (next == null && !replay.HasReceivedAllFrames) return null;
// if a next frame does exist, allow interpolation.
if (next != null)
return CurrentTime = time;
return CurrentTime = time;
// if all frames have been received, allow playing beyond extents.
if (replay.HasReceivedAllFrames)
return CurrentTime = time;
// if not all frames are received but we are before the first frame, allow playing.
if (time < Frames[0].Time)
return CurrentTime = time;
// in the case we have no next frames and haven't received enough frame data, block.
return null;
}
private void updateDirection(double time)