diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index 844db4a80f..64adcecba4 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -73,7 +73,7 @@ namespace osu.Desktop } public StableStorage() - : base(string.Empty) + : base(string.Empty, null) { } } diff --git a/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs b/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs index 6a9d1bdbc7..8d3d898655 100644 --- a/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs +++ b/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs @@ -28,9 +28,9 @@ namespace osu.Game.Rulesets.Catch.Replays } } - public override List GetPendingStates() + public override List GetPendingInputs() { - if (!Position.HasValue) return new List(); + if (!Position.HasValue) return new List(); var actions = new List(); @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Catch.Replays else if (Position.Value < CurrentFrame.Position) actions.Add(CatchAction.MoveLeft); - return new List + return new List { new CatchReplayState { diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 3b4a7b13e7..30f4979255 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -16,6 +16,7 @@ using osu.Game.Rulesets.Catch.Objects.Drawable; using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.UI; using OpenTK; using OpenTK.Graphics; @@ -93,7 +94,7 @@ namespace osu.Game.Rulesets.Catch.UI { base.UpdateAfterChildren(); - var state = GetContainingInputManager().CurrentState as CatchFramedReplayInputHandler.CatchReplayState; + var state = (GetContainingInputManager().CurrentState as RulesetInputManagerInputState)?.LastReplayState as CatchFramedReplayInputHandler.CatchReplayState; if (state?.CatcherX != null) MovableCatcher.X = state.CatcherX.Value; diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaFramedReplayInputHandler.cs b/osu.Game.Rulesets.Mania/Replays/ManiaFramedReplayInputHandler.cs index c71db745e0..29eeb1cab5 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaFramedReplayInputHandler.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaFramedReplayInputHandler.cs @@ -17,6 +17,6 @@ namespace osu.Game.Rulesets.Mania.Replays protected override bool IsImportant(ManiaReplayFrame frame) => frame.Actions.Any(); - public override List GetPendingStates() => new List { new ReplayState { PressedActions = CurrentFrame.Actions } }; + public override List GetPendingInputs() => new List { new ReplayState { PressedActions = CurrentFrame.Actions } }; } } diff --git a/osu.Game.Rulesets.Osu/Replays/OsuReplayInputHandler.cs b/osu.Game.Rulesets.Osu/Replays/OsuReplayInputHandler.cs index f9e5bfa89b..2eed41d13f 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuReplayInputHandler.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuReplayInputHandler.cs @@ -30,13 +30,16 @@ namespace osu.Game.Rulesets.Osu.Replays } } - public override List GetPendingStates() + public override List GetPendingInputs() { - return new List + return new List { + new MousePositionAbsoluteInput + { + Position = GamefieldToScreenSpace(Position ?? Vector2.Zero) + }, new ReplayState { - Mouse = new ReplayMouseState(GamefieldToScreenSpace(Position ?? Vector2.Zero)), PressedActions = CurrentFrame.Actions } }; diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoFramedReplayInputHandler.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoFramedReplayInputHandler.cs index 6ccbd575e5..eae033401e 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoFramedReplayInputHandler.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoFramedReplayInputHandler.cs @@ -17,6 +17,6 @@ namespace osu.Game.Rulesets.Taiko.Replays protected override bool IsImportant(TaikoReplayFrame frame) => frame.Actions.Any(); - public override List GetPendingStates() => new List { new ReplayState { PressedActions = CurrentFrame.Actions } }; + public override List GetPendingInputs() => new List { new ReplayState { PressedActions = CurrentFrame.Actions } }; } } diff --git a/osu.Game/Input/Handlers/ReplayInputHandler.cs b/osu.Game/Input/Handlers/ReplayInputHandler.cs index 5454dd0c9f..57a2e5df6d 100644 --- a/osu.Game/Input/Handlers/ReplayInputHandler.cs +++ b/osu.Game/Input/Handlers/ReplayInputHandler.cs @@ -32,16 +32,14 @@ namespace osu.Game.Input.Handlers public override int Priority => 0; - public class ReplayState : InputState + public class ReplayState : IInput where T : struct { public List PressedActions; - public override InputState Clone() + public void Apply(InputState state, IInputStateChangeHandler handler) { - var clone = (ReplayState)base.Clone(); - clone.PressedActions = new List(PressedActions); - return clone; + handler.HandleCustomInput(state, this); } } } diff --git a/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs b/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs index 0f5490a182..f13d96b35e 100644 --- a/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs +++ b/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Replays return true; } - public override List GetPendingStates() => new List(); + public override List GetPendingInputs() => new List(); public bool AtLastFrame => currentFrameIndex == Frames.Count - 1; public bool AtFirstFrame => currentFrameIndex == 0; @@ -119,7 +119,8 @@ namespace osu.Game.Rulesets.Replays { public ReplayKeyboardState(List keys) { - Keys = keys; + foreach (var key in keys) + Keys.Add(key); } } } diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index 58a66a5224..f8c4fff5b8 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -15,6 +15,7 @@ using osu.Game.Input.Bindings; using osu.Game.Input.Handlers; using osu.Game.Screens.Play; using OpenTK.Input; +using static osu.Game.Input.Handlers.ReplayInputHandler; namespace osu.Game.Rulesets.UI { @@ -29,6 +30,18 @@ namespace osu.Game.Rulesets.UI } } + protected override InputState CreateInitialState() + { + var state = base.CreateInitialState(); + return new RulesetInputManagerInputState + { + Mouse = state.Mouse, + Keyboard = state.Keyboard, + Joystick = state.Joystick, + LastReplayState = null + }; + } + protected readonly KeyBindingContainer KeyBindingContainer; protected override Container Content => KeyBindingContainer; @@ -42,13 +55,18 @@ namespace osu.Game.Rulesets.UI private List lastPressedActions = new List(); - protected override void HandleNewState(InputState state) + public override void HandleCustomInput(InputState state, IInput input) { - base.HandleNewState(state); + if (!(input is ReplayState replayState)) + { + base.HandleCustomInput(state, input); + return; + } - var replayState = state as ReplayInputHandler.ReplayState; - - if (replayState == null) return; + if (state is RulesetInputManagerInputState inputState) + { + inputState.LastReplayState = replayState; + } // Here we handle states specifically coming from a replay source. // These have extra action information rather than keyboard keys or mouse buttons. @@ -80,7 +98,7 @@ namespace osu.Game.Rulesets.UI if (replayInputHandler != null) RemoveHandler(replayInputHandler); replayInputHandler = value; - UseParentState = replayInputHandler == null; + UseParentInput = replayInputHandler == null; if (replayInputHandler != null) AddHandler(replayInputHandler); @@ -123,7 +141,7 @@ namespace osu.Game.Rulesets.UI protected override bool RequiresChildrenUpdate => base.RequiresChildrenUpdate && validState; - private bool isAttached => replayInputHandler != null && !UseParentState; + private bool isAttached => replayInputHandler != null && !UseParentInput; private const int max_catch_up_updates_per_frame = 50; @@ -267,4 +285,10 @@ namespace osu.Game.Rulesets.UI { void Attach(KeyCounterCollection keyCounter); } + + public class RulesetInputManagerInputState : InputState + where T : struct + { + public ReplayState LastReplayState; + } } diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index d0aa0dad92..29382c25f3 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -182,14 +183,14 @@ namespace osu.Game.Screens.Play.HUD protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { - if (!pendingAnimation && state.Mouse.Buttons.Count == 1) + if (!pendingAnimation && state.Mouse.Buttons.Count() == 1) BeginConfirm(); return true; } protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { - if (state.Mouse.Buttons.Count == 0) + if (!state.Mouse.Buttons.Any()) AbortConfirm(); return true; } diff --git a/osu.Game/Tests/Platform/TestStorage.cs b/osu.Game/Tests/Platform/TestStorage.cs index 883aae2184..5b31c7b4d0 100644 --- a/osu.Game/Tests/Platform/TestStorage.cs +++ b/osu.Game/Tests/Platform/TestStorage.cs @@ -7,7 +7,7 @@ namespace osu.Game.Tests.Platform { public class TestStorage : DesktopStorage { - public TestStorage(string baseName) : base(baseName) + public TestStorage(string baseName) : base(baseName, null) { } diff --git a/osu.Game/Tests/Visual/ManualInputManagerTestCase.cs b/osu.Game/Tests/Visual/ManualInputManagerTestCase.cs index 132a655c15..01676ad56e 100644 --- a/osu.Game/Tests/Visual/ManualInputManagerTestCase.cs +++ b/osu.Game/Tests/Visual/ManualInputManagerTestCase.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual /// protected void ReturnUserInput() { - AddStep("Return user input", () => InputManager.UseParentState = true); + AddStep("Return user input", () => InputManager.UseParentInput = true); } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f0bc330994..9cc538f70f 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,7 +18,7 @@ - +