From 66594b7a1b39ce1ec12049e2458a466030ffb5bc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 9 May 2019 16:36:47 +0900 Subject: [PATCH 1/2] Pass GameplayStartTime to FrameStabilityContainer to allow bypassing prior to start --- .../TestCaseFrameStabilityContainer.cs | 20 +++++++++++++++++++ osu.Game/Rulesets/UI/DrawableRuleset.cs | 2 +- .../Rulesets/UI/FrameStabilityContainer.cs | 8 +++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs b/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs index 5cd01fe9a8..584fbe5729 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs @@ -73,6 +73,26 @@ namespace osu.Game.Tests.Visual.Gameplay checkFrameCount(2); } + [Test] + public void TestInitialSeekWithGameplayStart() + { + seekManualTo(1000); + createStabilityContainer(30000); + + confirmSeek(1000); + checkFrameCount(0); + + seekManualTo(10000); + confirmSeek(10000); + + checkFrameCount(1); + + seekManualTo(130000); + confirmSeek(130000); + + checkFrameCount(6002); + } + [Test] public void TestInitialSeek() { diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 77d1e60b87..75526ae50a 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -144,7 +144,7 @@ namespace osu.Game.Rulesets.UI { InternalChildren = new Drawable[] { - frameStabilityContainer = new FrameStabilityContainer + frameStabilityContainer = new FrameStabilityContainer(GameplayStartTime) { Child = KeyBindingInputManager .WithChild(CreatePlayfieldAdjustmentContainer() diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs index ad15bcf057..16a5ca4387 100644 --- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs +++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs @@ -17,10 +17,14 @@ namespace osu.Game.Rulesets.UI /// public class FrameStabilityContainer : Container, IHasReplayHandler { - public FrameStabilityContainer() + private readonly double gameplayStartTime; + + public FrameStabilityContainer(double gameplayStartTime = double.MinValue) { RelativeSizeAxes = Axes.Both; gameplayClock = new GameplayClock(framedClock = new FramedClock(manualClock = new ManualClock())); + + this.gameplayStartTime = gameplayStartTime; } private readonly ManualClock manualClock; @@ -116,6 +120,8 @@ namespace osu.Game.Rulesets.UI firstConsumption = false; } + else if (manualClock.CurrentTime < gameplayStartTime) + manualClock.CurrentTime = newProposedTime = Math.Min(gameplayStartTime, newProposedTime); else if (Math.Abs(manualClock.CurrentTime - newProposedTime) > sixty_frame_time * 1.2f) { newProposedTime = newProposedTime > manualClock.CurrentTime From 3bcfc86b9c92c0640d29fda24537bf47c0b26076 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 9 May 2019 16:37:34 +0900 Subject: [PATCH 2/2] Allow custom MaxCatchUpFrames to be specified Also adjusts the default to allow for smoother seeking. --- .../Visual/Gameplay/TestCaseFrameStabilityContainer.cs | 6 +++++- osu.Game/Rulesets/UI/FrameStabilityContainer.cs | 9 ++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs b/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs index 584fbe5729..7d6430a2cc 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestCaseFrameStabilityContainer.cs @@ -103,7 +103,11 @@ namespace osu.Game.Tests.Visual.Gameplay checkFrameCount(0); } - private void createStabilityContainer() => AddStep("create container", () => mainContainer.Child = new FrameStabilityContainer().WithChild(consumer = new ClockConsumingChild())); + private const int max_frames_catchup = 50; + + private void createStabilityContainer(double gameplayStartTime = double.MinValue) => AddStep("create container", () => + mainContainer.Child = new FrameStabilityContainer(gameplayStartTime) { MaxCatchUpFrames = max_frames_catchup } + .WithChild(consumer = new ClockConsumingChild())); private void seekManualTo(double time) => AddStep($"seek manual clock to {time}", () => manualClock.CurrentTime = time); diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs index 16a5ca4387..9f2bf33628 100644 --- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs +++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs @@ -19,6 +19,11 @@ namespace osu.Game.Rulesets.UI { private readonly double gameplayStartTime; + /// + /// The number of frames (per parent frame) which can be run in an attempt to catch-up to real-time. + /// + public int MaxCatchUpFrames { get; set; } = 5; + public FrameStabilityContainer(double gameplayStartTime = double.MinValue) { RelativeSizeAxes = Axes.Both; @@ -68,8 +73,6 @@ namespace osu.Game.Rulesets.UI private bool isAttached => ReplayInputHandler != null; - private const int max_catch_up_updates_per_frame = 50; - private const double sixty_frame_time = 1000.0 / 60; private bool firstConsumption = true; @@ -81,7 +84,7 @@ namespace osu.Game.Rulesets.UI int loops = 0; - while (validState && requireMoreUpdateLoops && loops++ < max_catch_up_updates_per_frame) + while (validState && requireMoreUpdateLoops && loops++ < MaxCatchUpFrames) { updateClock();