From 936bde28a35ef8ea0ba9f4af801c09e8ea6b4bcc Mon Sep 17 00:00:00 2001 From: ekrctb Date: Fri, 16 Apr 2021 13:59:11 +0900 Subject: [PATCH 1/4] Remove manual handling of IsActive in RulesetInputManager Now it is supported in framework --- osu.Game/Rulesets/UI/RulesetInputManager.cs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index 5ab09f9516..d6f002ea2c 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -11,7 +10,6 @@ using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; -using osu.Framework.Input.StateChanges; using osu.Framework.Input.StateChanges.Events; using osu.Framework.Input.States; using osu.Game.Configuration; @@ -102,17 +100,6 @@ public ReplayInputHandler ReplayInputHandler #endregion - // to avoid allocation - private readonly List emptyInputList = new List(); - - protected override List GetPendingInputs() - { - if (replayInputHandler?.IsActive == false) - return emptyInputList; - - return base.GetPendingInputs(); - } - #region Setting application (disables etc.) private Bindable mouseDisabled; From 84bc81a6deda614ce407730d62750c7a52195671 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Fri, 16 Apr 2021 12:31:32 +0900 Subject: [PATCH 2/4] Make FramedReplayInputHandler.CurrentTime non-null --- .../EmptyFreeformFramedReplayInputHandler.cs | 5 +---- .../Replays/PippidonFramedReplayInputHandler.cs | 5 +---- .../Replays/CatchFramedReplayInputHandler.cs | 5 +---- .../Replays/OsuFramedReplayInputHandler.cs | 5 +---- .../Rulesets/Replays/FramedReplayInputHandler.cs | 13 +++++++------ 5 files changed, 11 insertions(+), 22 deletions(-) diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Replays/EmptyFreeformFramedReplayInputHandler.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Replays/EmptyFreeformFramedReplayInputHandler.cs index f25ea6ec62..b7e2031bb9 100644 --- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Replays/EmptyFreeformFramedReplayInputHandler.cs +++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Replays/EmptyFreeformFramedReplayInputHandler.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using osu.Framework.Input.StateChanges; using osu.Framework.Utils; @@ -30,9 +29,7 @@ protected Vector2 Position if (frame == null) return Vector2.Zero; - Debug.Assert(CurrentTime != null); - - return Interpolation.ValueAt(CurrentTime.Value, frame.Position, NextFrame.Position, frame.Time, NextFrame.Time); + return Interpolation.ValueAt(CurrentTime, frame.Position, NextFrame.Position, frame.Time, NextFrame.Time); } } diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Replays/PippidonFramedReplayInputHandler.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Replays/PippidonFramedReplayInputHandler.cs index 18efa6b885..69c7df5fac 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Replays/PippidonFramedReplayInputHandler.cs +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Replays/PippidonFramedReplayInputHandler.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; -using System.Diagnostics; using osu.Framework.Input.StateChanges; using osu.Framework.Utils; using osu.Game.Replays; @@ -29,9 +28,7 @@ protected Vector2 Position if (frame == null) return Vector2.Zero; - Debug.Assert(CurrentTime != null); - - return NextFrame != null ? Interpolation.ValueAt(CurrentTime.Value, frame.Position, NextFrame.Position, frame.Time, NextFrame.Time) : frame.Position; + return NextFrame != null ? Interpolation.ValueAt(CurrentTime, frame.Position, NextFrame.Position, frame.Time, NextFrame.Time) : frame.Position; } } diff --git a/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs b/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs index 99d899db80..5fea855a16 100644 --- a/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs +++ b/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using osu.Framework.Input.StateChanges; using osu.Framework.Utils; @@ -29,9 +28,7 @@ protected float? Position if (frame == null) return null; - Debug.Assert(CurrentTime != null); - - return NextFrame != null ? Interpolation.ValueAt(CurrentTime.Value, frame.Position, NextFrame.Position, frame.Time, NextFrame.Time) : frame.Position; + return NextFrame != null ? Interpolation.ValueAt(CurrentTime, frame.Position, NextFrame.Position, frame.Time, NextFrame.Time) : frame.Position; } } diff --git a/osu.Game.Rulesets.Osu/Replays/OsuFramedReplayInputHandler.cs b/osu.Game.Rulesets.Osu/Replays/OsuFramedReplayInputHandler.cs index cf48dc053f..6ac0bbd045 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuFramedReplayInputHandler.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuFramedReplayInputHandler.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using osu.Framework.Input.StateChanges; using osu.Framework.Utils; @@ -30,9 +29,7 @@ protected Vector2? Position if (frame == null) return null; - Debug.Assert(CurrentTime != null); - - return NextFrame != null ? Interpolation.ValueAt(CurrentTime.Value, frame.Position, NextFrame.Position, frame.Time, NextFrame.Time) : frame.Position; + return NextFrame != null ? Interpolation.ValueAt(CurrentTime, frame.Position, NextFrame.Position, frame.Time, NextFrame.Time) : frame.Position; } } diff --git a/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs b/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs index 279087ead9..0442acebe5 100644 --- a/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs +++ b/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +#nullable enable + using System; using System.Collections.Generic; using JetBrains.Annotations; @@ -32,7 +34,7 @@ public abstract class FramedReplayInputHandler : ReplayInputHandler /// /// Returns null if the current time is strictly before the first frame. /// The replay is empty. - public TFrame CurrentFrame + public TFrame? CurrentFrame { get { @@ -49,7 +51,7 @@ public TFrame CurrentFrame /// /// Returns null if the current frame is the last frame. /// The replay is empty. - public TFrame NextFrame + public TFrame? NextFrame { get { @@ -69,8 +71,7 @@ public TFrame NextFrame // This input handler should be enabled only if there is at least one replay frame. public override bool IsActive => HasFrames; - // Can make it non-null but that is a breaking change. - protected double? CurrentTime { get; private set; } + protected double CurrentTime { get; private set; } protected virtual double AllowedImportantTimeSpan => sixty_frame_time * 1.2; @@ -101,7 +102,7 @@ private bool inImportantSection 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 + Math.Abs(CurrentTime - NextFrame?.Time ?? 0) <= AllowedImportantTimeSpan; // the next frame is within an allowable time span } } @@ -151,7 +152,7 @@ private bool inImportantSection CurrentTime = Math.Clamp(time, frameStart, frameEnd); // In an important section, a mid-frame time cannot be used and a null is returned instead. - return inImportantSection && frameStart < time && time < frameEnd ? null : CurrentTime; + return inImportantSection && frameStart < time && time < frameEnd ? null : (double?)CurrentTime; } private double getFrameTime(int index) From 91c7d8d26cf2143cb85c53cf9770676947ab57e4 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Fri, 16 Apr 2021 12:53:58 +0900 Subject: [PATCH 3/4] Introduce `StartFrame` and `EndFrame` to simplify the replay interpolation code --- .../EmptyFreeformFramedReplayInputHandler.cs | 18 ++-------- .../PippidonFramedReplayInputHandler.cs | 18 ++-------- .../Replays/CatchFramedReplayInputHandler.cs | 17 ++-------- .../Replays/OsuFramedReplayInputHandler.cs | 18 ++-------- .../Replays/FramedReplayInputHandler.cs | 34 ++++++++++++------- 5 files changed, 33 insertions(+), 72 deletions(-) diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Replays/EmptyFreeformFramedReplayInputHandler.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Replays/EmptyFreeformFramedReplayInputHandler.cs index b7e2031bb9..cc4483de31 100644 --- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Replays/EmptyFreeformFramedReplayInputHandler.cs +++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Replays/EmptyFreeformFramedReplayInputHandler.cs @@ -7,7 +7,6 @@ using osu.Framework.Utils; using osu.Game.Replays; using osu.Game.Rulesets.Replays; -using osuTK; namespace osu.Game.Rulesets.EmptyFreeform.Replays { @@ -20,24 +19,13 @@ public EmptyFreeformFramedReplayInputHandler(Replay replay) protected override bool IsImportant(EmptyFreeformReplayFrame frame) => frame.Actions.Any(); - protected Vector2 Position - { - get - { - var frame = CurrentFrame; - - if (frame == null) - return Vector2.Zero; - - return Interpolation.ValueAt(CurrentTime, frame.Position, NextFrame.Position, frame.Time, NextFrame.Time); - } - } - public override void CollectPendingInputs(List inputs) { + var position = Interpolation.ValueAt(CurrentTime, StartFrame.Position, EndFrame.Position, StartFrame.Time, EndFrame.Time); + inputs.Add(new MousePositionAbsoluteInput { - Position = GamefieldToScreenSpace(Position), + Position = GamefieldToScreenSpace(position), }); inputs.Add(new ReplayState { diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Replays/PippidonFramedReplayInputHandler.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Replays/PippidonFramedReplayInputHandler.cs index 69c7df5fac..e005346e1e 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Replays/PippidonFramedReplayInputHandler.cs +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Replays/PippidonFramedReplayInputHandler.cs @@ -6,7 +6,6 @@ using osu.Framework.Utils; using osu.Game.Replays; using osu.Game.Rulesets.Replays; -using osuTK; namespace osu.Game.Rulesets.Pippidon.Replays { @@ -19,24 +18,13 @@ public PippidonFramedReplayInputHandler(Replay replay) protected override bool IsImportant(PippidonReplayFrame frame) => true; - protected Vector2 Position - { - get - { - var frame = CurrentFrame; - - if (frame == null) - return Vector2.Zero; - - return NextFrame != null ? Interpolation.ValueAt(CurrentTime, frame.Position, NextFrame.Position, frame.Time, NextFrame.Time) : frame.Position; - } - } - public override void CollectPendingInputs(List inputs) { + var position = Interpolation.ValueAt(CurrentTime, StartFrame.Position, EndFrame.Position, StartFrame.Time, EndFrame.Time); + inputs.Add(new MousePositionAbsoluteInput { - Position = GamefieldToScreenSpace(Position) + Position = GamefieldToScreenSpace(position) }); } } diff --git a/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs b/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs index 5fea855a16..137328b1c3 100644 --- a/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs +++ b/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs @@ -19,27 +19,14 @@ public CatchFramedReplayInputHandler(Replay replay) protected override bool IsImportant(CatchReplayFrame frame) => frame.Actions.Any(); - protected float? Position - { - get - { - var frame = CurrentFrame; - - if (frame == null) - return null; - - return NextFrame != null ? Interpolation.ValueAt(CurrentTime, frame.Position, NextFrame.Position, frame.Time, NextFrame.Time) : frame.Position; - } - } - public override void CollectPendingInputs(List inputs) { - if (!Position.HasValue) return; + var position = Interpolation.ValueAt(CurrentTime, StartFrame.Position, EndFrame.Position, StartFrame.Time, EndFrame.Time); inputs.Add(new CatchReplayState { PressedActions = CurrentFrame?.Actions ?? new List(), - CatcherX = Position.Value + CatcherX = position }); } diff --git a/osu.Game.Rulesets.Osu/Replays/OsuFramedReplayInputHandler.cs b/osu.Game.Rulesets.Osu/Replays/OsuFramedReplayInputHandler.cs index 6ac0bbd045..7d696dfb79 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuFramedReplayInputHandler.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuFramedReplayInputHandler.cs @@ -7,7 +7,6 @@ using osu.Framework.Utils; using osu.Game.Replays; using osu.Game.Rulesets.Replays; -using osuTK; namespace osu.Game.Rulesets.Osu.Replays { @@ -20,22 +19,11 @@ public OsuFramedReplayInputHandler(Replay replay) protected override bool IsImportant(OsuReplayFrame frame) => frame.Actions.Any(); - protected Vector2? Position - { - get - { - var frame = CurrentFrame; - - if (frame == null) - return null; - - return NextFrame != null ? Interpolation.ValueAt(CurrentTime, frame.Position, NextFrame.Position, frame.Time, NextFrame.Time) : frame.Position; - } - } - public override void CollectPendingInputs(List inputs) { - inputs.Add(new MousePositionAbsoluteInput { Position = GamefieldToScreenSpace(Position ?? Vector2.Zero) }); + var position = Interpolation.ValueAt(CurrentTime, StartFrame.Position, EndFrame.Position, StartFrame.Time, EndFrame.Time); + + inputs.Add(new MousePositionAbsoluteInput { Position = GamefieldToScreenSpace(position) }); inputs.Add(new ReplayState { PressedActions = CurrentFrame?.Actions ?? new List() }); } } diff --git a/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs b/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs index 0442acebe5..0f25a45177 100644 --- a/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs +++ b/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs @@ -33,32 +33,42 @@ public abstract class FramedReplayInputHandler : ReplayInputHandler /// The current time is always between the start and the end time of the current frame. /// /// Returns null if the current time is strictly before the first frame. + public TFrame? CurrentFrame => currentFrameIndex == -1 ? null : (TFrame)Frames[currentFrameIndex]; + + /// + /// The next frame of the replay. + /// The start time of is always greater or equal to the start time of regardless of the seeking direction. + /// + /// Returns null if the current frame is the last frame. + public TFrame? NextFrame => currentFrameIndex == Frames.Count - 1 ? null : (TFrame)Frames[currentFrameIndex + 1]; + + /// + /// The frame for the start value of the interpolation of the replay movement. + /// /// The replay is empty. - 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)]; } } /// - /// The next frame of the replay. - /// The start time is always greater or equal to the start time of regardless of the seeking direction. + /// The frame for the end value of the interpolation of the replay movement. /// - /// Returns null if the current frame is the last frame. /// The replay is empty. - 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 @@ private bool inImportantSection { 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 } } From a965e8a75d1ae770d6e3d1a4548132e3b6abc2ce Mon Sep 17 00:00:00 2001 From: ekrctb Date: Fri, 16 Apr 2021 13:06:02 +0900 Subject: [PATCH 4/4] Remove AutoGenerator workaround of now-fixed issue --- .../Replays/CatchAutoGenerator.cs | 4 ---- .../TestSceneAutoGeneration.cs | 16 ++++++++-------- .../Replays/ManiaAutoGenerator.cs | 4 ---- .../Replays/OsuAutoGenerator.cs | 2 -- .../Replays/TaikoAutoGenerator.cs | 1 - 5 files changed, 8 insertions(+), 19 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs index 64ded8e94f..10230b6b78 100644 --- a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs +++ b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs @@ -125,10 +125,6 @@ void moveToNext(PalpableCatchHitObject h) private void addFrame(double time, float? position = null, bool dashing = false) { - // todo: can be removed once FramedReplayInputHandler correctly handles rewinding before first frame. - if (Replay.Frames.Count == 0) - Replay.Frames.Add(new CatchReplayFrame(time - 1, position, false, null)); - var last = currentFrame; currentFrame = new CatchReplayFrame(time, position, dashing, last); Replay.Frames.Add(currentFrame); diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneAutoGeneration.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneAutoGeneration.cs index 399a46aa77..cffec3dfd5 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneAutoGeneration.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneAutoGeneration.cs @@ -19,7 +19,7 @@ public class TestSceneAutoGeneration : OsuTestScene /// /// The number of frames which are generated at the start of a replay regardless of hitobject content. /// - private const int frame_offset = 1; + private const int frame_offset = 0; [Test] public void TestSingleNote() @@ -33,7 +33,7 @@ public void TestSingleNote() var generated = new ManiaAutoGenerator(beatmap).Generate(); - Assert.IsTrue(generated.Frames.Count == frame_offset + 2, "Replay must have 3 frames"); + Assert.AreEqual(generated.Frames.Count, frame_offset + 2, "Incorrect number of frames"); Assert.AreEqual(1000, generated.Frames[frame_offset].Time, "Incorrect hit time"); Assert.AreEqual(1000 + ManiaAutoGenerator.RELEASE_DELAY, generated.Frames[frame_offset + 1].Time, "Incorrect release time"); Assert.IsTrue(checkContains(generated.Frames[frame_offset], ManiaAction.Special1), "Special1 has not been pressed"); @@ -54,7 +54,7 @@ public void TestSingleHoldNote() var generated = new ManiaAutoGenerator(beatmap).Generate(); - Assert.IsTrue(generated.Frames.Count == frame_offset + 2, "Replay must have 3 frames"); + Assert.AreEqual(generated.Frames.Count, frame_offset + 2, "Incorrect number of frames"); Assert.AreEqual(1000, generated.Frames[frame_offset].Time, "Incorrect hit time"); Assert.AreEqual(3000, generated.Frames[frame_offset + 1].Time, "Incorrect release time"); Assert.IsTrue(checkContains(generated.Frames[frame_offset], ManiaAction.Special1), "Special1 has not been pressed"); @@ -74,7 +74,7 @@ public void TestSingleNoteChord() var generated = new ManiaAutoGenerator(beatmap).Generate(); - Assert.IsTrue(generated.Frames.Count == frame_offset + 2, "Replay must have 3 frames"); + Assert.AreEqual(generated.Frames.Count, frame_offset + 2, "Incorrect number of frames"); Assert.AreEqual(1000, generated.Frames[frame_offset].Time, "Incorrect hit time"); Assert.AreEqual(1000 + ManiaAutoGenerator.RELEASE_DELAY, generated.Frames[frame_offset + 1].Time, "Incorrect release time"); Assert.IsTrue(checkContains(generated.Frames[frame_offset], ManiaAction.Key1, ManiaAction.Key2), "Key1 & Key2 have not been pressed"); @@ -96,7 +96,7 @@ public void TestHoldNoteChord() var generated = new ManiaAutoGenerator(beatmap).Generate(); - Assert.IsTrue(generated.Frames.Count == frame_offset + 2, "Replay must have 3 frames"); + Assert.AreEqual(generated.Frames.Count, frame_offset + 2, "Incorrect number of frames"); Assert.AreEqual(1000, generated.Frames[frame_offset].Time, "Incorrect hit time"); Assert.AreEqual(3000, generated.Frames[frame_offset + 1].Time, "Incorrect release time"); @@ -119,7 +119,7 @@ public void TestSingleNoteStair() var generated = new ManiaAutoGenerator(beatmap).Generate(); - Assert.IsTrue(generated.Frames.Count == frame_offset + 4, "Replay must have 4 generated frames"); + Assert.AreEqual(generated.Frames.Count, frame_offset + 4, "Incorrect number of frames"); Assert.AreEqual(1000, generated.Frames[frame_offset].Time, "Incorrect first note hit time"); Assert.AreEqual(1000 + ManiaAutoGenerator.RELEASE_DELAY, generated.Frames[frame_offset + 1].Time, "Incorrect first note release time"); Assert.AreEqual(2000, generated.Frames[frame_offset + 2].Time, "Incorrect second note hit time"); @@ -146,7 +146,7 @@ public void TestHoldNoteStair() var generated = new ManiaAutoGenerator(beatmap).Generate(); - Assert.IsTrue(generated.Frames.Count == frame_offset + 4, "Replay must have 4 generated frames"); + Assert.AreEqual(generated.Frames.Count, frame_offset + 4, "Incorrect number of frames"); Assert.AreEqual(1000, generated.Frames[frame_offset].Time, "Incorrect first note hit time"); Assert.AreEqual(3000, generated.Frames[frame_offset + 2].Time, "Incorrect first note release time"); Assert.AreEqual(2000, generated.Frames[frame_offset + 1].Time, "Incorrect second note hit time"); @@ -173,7 +173,7 @@ public void TestHoldNoteWithReleasePress() var generated = new ManiaAutoGenerator(beatmap).Generate(); - Assert.IsTrue(generated.Frames.Count == frame_offset + 3, "Replay must have 3 generated frames"); + Assert.AreEqual(generated.Frames.Count, frame_offset + 3, "Incorrect number of frames"); Assert.AreEqual(1000, generated.Frames[frame_offset].Time, "Incorrect first note hit time"); Assert.AreEqual(3000, generated.Frames[frame_offset + 1].Time, "Incorrect second note press time + first note release time"); Assert.AreEqual(3000 + ManiaAutoGenerator.RELEASE_DELAY, generated.Frames[frame_offset + 2].Time, "Incorrect second note release time"); diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs index 7c51d58b74..ada84dfac2 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs @@ -70,10 +70,6 @@ public override Replay Generate() } } - // todo: can be removed once FramedReplayInputHandler correctly handles rewinding before first frame. - if (Replay.Frames.Count == 0) - Replay.Frames.Add(new ManiaReplayFrame(group.First().Time - 1)); - Replay.Frames.Add(new ManiaReplayFrame(group.First().Time, actions.ToArray())); } diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs index 693943a08a..7b0cf651c8 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs @@ -71,8 +71,6 @@ public override Replay Generate() buttonIndex = 0; - AddFrameToReplay(new OsuReplayFrame(-100000, new Vector2(256, 500))); - AddFrameToReplay(new OsuReplayFrame(Beatmap.HitObjects[0].StartTime - 1500, new Vector2(256, 500))); AddFrameToReplay(new OsuReplayFrame(Beatmap.HitObjects[0].StartTime - 1500, new Vector2(256, 500))); for (int i = 0; i < Beatmap.HitObjects.Count; i++) diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs index a3dbe672a4..fa0134aa94 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs @@ -35,7 +35,6 @@ public override Replay Generate() bool hitButton = true; - Frames.Add(new TaikoReplayFrame(-100000)); Frames.Add(new TaikoReplayFrame(Beatmap.HitObjects[0].StartTime - 1000)); for (int i = 0; i < Beatmap.HitObjects.Count; i++)