1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 00:47:24 +08:00

Throw when getting a frame of an empty replay

This commit is contained in:
ekrctb 2021-04-12 11:17:56 +09:00
parent 4853ac802c
commit d6d8ea5b6b
4 changed files with 32 additions and 19 deletions

View File

@ -204,27 +204,27 @@ namespace osu.Game.Tests.Visual.Gameplay
return; return;
} }
if (replayHandler.NextFrame != null) if (!replayHandler.HasFrames)
{ return;
var lastFrame = replay.Frames.LastOrDefault();
// this isn't perfect as we basically can't be aware of the rate-of-send here (the streamer is not sending data when not being moved). var lastFrame = replay.Frames.LastOrDefault();
// in gameplay playback, the case where NextFrame is null would pause gameplay and handle this correctly; it's strictly a test limitation / best effort implementation.
if (lastFrame != null)
latency = Math.Max(latency, Time.Current - lastFrame.Time);
latencyDisplay.Text = $"latency: {latency:N1}"; // this isn't perfect as we basically can't be aware of the rate-of-send here (the streamer is not sending data when not being moved).
// in gameplay playback, the case where NextFrame is null would pause gameplay and handle this correctly; it's strictly a test limitation / best effort implementation.
if (lastFrame != null)
latency = Math.Max(latency, Time.Current - lastFrame.Time);
double proposedTime = Time.Current - latency + Time.Elapsed; latencyDisplay.Text = $"latency: {latency:N1}";
// this will either advance by one or zero frames. double proposedTime = Time.Current - latency + Time.Elapsed;
double? time = replayHandler.SetFrameFromTime(proposedTime);
if (time == null) // this will either advance by one or zero frames.
return; double? time = replayHandler.SetFrameFromTime(proposedTime);
manualClock.CurrentTime = time.Value; if (time == null)
} return;
manualClock.CurrentTime = time.Value;
} }
[TearDownSteps] [TearDownSteps]

View File

@ -32,8 +32,6 @@ namespace osu.Game.Input.Handlers
public override bool Initialize(GameHost host) => true; public override bool Initialize(GameHost host) => true;
public override bool IsActive => true;
public class ReplayState<T> : IInput public class ReplayState<T> : IInput
where T : struct where T : struct
{ {

View File

@ -17,6 +17,8 @@ namespace osu.Game.Rulesets.Replays
public abstract class FramedReplayInputHandler<TFrame> : ReplayInputHandler public abstract class FramedReplayInputHandler<TFrame> : ReplayInputHandler
where TFrame : ReplayFrame where TFrame : ReplayFrame
{ {
public override bool IsActive => HasFrames;
private readonly Replay replay; private readonly Replay replay;
protected List<ReplayFrame> Frames => replay.Frames; protected List<ReplayFrame> Frames => replay.Frames;
@ -25,7 +27,10 @@ namespace osu.Game.Rulesets.Replays
{ {
get get
{ {
if (!HasFrames || !currentFrameIndex.HasValue) if (!HasFrames)
throw new InvalidOperationException($"Cannot get {nameof(CurrentFrame)} of the empty replay");
if (!currentFrameIndex.HasValue)
return null; return null;
return (TFrame)Frames[currentFrameIndex.Value]; return (TFrame)Frames[currentFrameIndex.Value];
@ -37,7 +42,7 @@ namespace osu.Game.Rulesets.Replays
get get
{ {
if (!HasFrames) if (!HasFrames)
return null; throw new InvalidOperationException($"Cannot get {nameof(NextFrame)} of the empty replay");
if (!currentFrameIndex.HasValue) if (!currentFrameIndex.HasValue)
return currentDirection > 0 ? (TFrame)Frames[0] : null; return currentDirection > 0 ? (TFrame)Frames[0] : null;

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
@ -10,6 +11,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Framework.Input.StateChanges;
using osu.Framework.Input.StateChanges.Events; using osu.Framework.Input.StateChanges.Events;
using osu.Framework.Input.States; using osu.Framework.Input.States;
using osu.Game.Configuration; using osu.Game.Configuration;
@ -100,6 +102,14 @@ namespace osu.Game.Rulesets.UI
#endregion #endregion
protected override List<IInput> GetPendingInputs()
{
if (replayInputHandler != null && !replayInputHandler.IsActive)
return new List<IInput>();
return base.GetPendingInputs();
}
#region Setting application (disables etc.) #region Setting application (disables etc.)
private Bindable<bool> mouseDisabled; private Bindable<bool> mouseDisabled;