diff --git a/osu.Game.Tests/Gameplay/TestSceneReplayRecording.cs b/osu.Game.Tests/Gameplay/TestSceneReplayRecording.cs index c2b2ebdb98..ab1998a650 100644 --- a/osu.Game.Tests/Gameplay/TestSceneReplayRecording.cs +++ b/osu.Game.Tests/Gameplay/TestSceneReplayRecording.cs @@ -1,13 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Collections.Generic; -using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Input.StateChanges; @@ -41,7 +38,7 @@ namespace osu.Game.Tests.Gameplay { new TestRulesetInputManager(new TestSceneModSettings.TestRulesetInfo(), 0, SimultaneousBindingMode.Unique) { - RecordTarget = replay, + Recorder = new TestReplayRecorder(replay), Child = new Container { RelativeSizeAxes = Axes.Both, @@ -171,19 +168,6 @@ namespace osu.Game.Tests.Gameplay public class TestRulesetInputManager : RulesetInputManager { - private ReplayRecorder recorder; - - public Replay RecordTarget - { - set - { - if (recorder != null) - throw new InvalidOperationException("Cannot attach more than one recorder"); - - KeyBindingContainer.Add(recorder = new TestReplayRecorder(value)); - } - } - public TestRulesetInputManager(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) : base(ruleset, variant, unique) { @@ -230,66 +214,4 @@ namespace osu.Game.Tests.Gameplay protected override ReplayFrame HandleFrame(InputState state, List pressedActions, ReplayFrame previousFrame) => new TestReplayFrame(Time.Current, ToLocalSpace(state.Mouse.Position), pressedActions.ToArray()); } - - internal abstract class ReplayRecorder : Component, IKeyBindingHandler - where T : struct - { - private readonly Replay target; - - private readonly List pressedActions = new List(); - - private InputManager inputManager; - - public int RecordFrameRate = 60; - - protected ReplayRecorder(Replay target) - { - this.target = target; - - RelativeSizeAxes = Axes.Both; - - Depth = float.MinValue; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - inputManager = GetContainingInputManager(); - } - - protected override bool OnMouseMove(MouseMoveEvent e) - { - recordFrame(false); - return base.OnMouseMove(e); - } - - public bool OnPressed(T action) - { - pressedActions.Add(action); - recordFrame(true); - return false; - } - - public void OnReleased(T action) - { - pressedActions.Remove(action); - recordFrame(true); - } - - private void recordFrame(bool important) - { - var last = target.Frames.LastOrDefault(); - - if (!important && last != null && Time.Current - last.Time < (1000d / RecordFrameRate)) - return; - - var frame = HandleFrame(inputManager.CurrentState, pressedActions, last); - - if (frame != null) - target.Frames.Add(frame); - } - - protected abstract ReplayFrame HandleFrame(InputState state, List testActions, ReplayFrame previousFrame); - } } diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index d0a2722f58..c8af3be980 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -302,6 +302,8 @@ namespace osu.Game.Rulesets.UI protected virtual ReplayInputHandler CreateReplayInputHandler(Replay replay) => null; + protected virtual ReplayRecorder CreateReplayRecorder(Replay replay) => null; + /// /// Creates a Playfield. /// diff --git a/osu.Game/Rulesets/UI/ReplayRecorder.cs b/osu.Game/Rulesets/UI/ReplayRecorder.cs new file mode 100644 index 0000000000..9e2f898206 --- /dev/null +++ b/osu.Game/Rulesets/UI/ReplayRecorder.cs @@ -0,0 +1,81 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Graphics; +using osu.Framework.Input; +using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; +using osu.Framework.Input.States; +using osu.Game.Replays; +using osu.Game.Rulesets.Replays; + +namespace osu.Game.Rulesets.UI +{ + public abstract class ReplayRecorder : ReplayRecorder, IKeyBindingHandler + where T : struct + { + private readonly Replay target; + + private readonly List pressedActions = new List(); + + private InputManager inputManager; + + public int RecordFrameRate = 60; + + protected ReplayRecorder(Replay target) + { + this.target = target; + + RelativeSizeAxes = Axes.Both; + + Depth = float.MinValue; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + inputManager = GetContainingInputManager(); + } + + protected override bool OnMouseMove(MouseMoveEvent e) + { + recordFrame(false); + return base.OnMouseMove(e); + } + + public bool OnPressed(T action) + { + pressedActions.Add(action); + recordFrame(true); + return false; + } + + public void OnReleased(T action) + { + pressedActions.Remove(action); + recordFrame(true); + } + + private void recordFrame(bool important) + { + var last = target.Frames.LastOrDefault(); + + if (!important && last != null && Time.Current - last.Time < (1000d / RecordFrameRate)) + return; + + var frame = HandleFrame(inputManager.CurrentState, pressedActions, last); + + if (frame != null) + target.Frames.Add(frame); + } + + protected abstract ReplayFrame HandleFrame(InputState state, List testActions, ReplayFrame previousFrame); + } + + public abstract class ReplayRecorder : Component + { + } +} diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index 7f85c10b56..043e0f56cc 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -26,6 +27,21 @@ namespace osu.Game.Rulesets.UI public abstract class RulesetInputManager : PassThroughInputManager, ICanAttachKeyCounter, IHasReplayHandler where T : struct { + private ReplayRecorder recorder; + + public ReplayRecorder Recorder + { + set + { + if (recorder != null) + throw new InvalidOperationException("Cannot attach more than one recorder"); + + recorder = value; + + KeyBindingContainer.Add(recorder); + } + } + protected override InputState CreateInitialState() { var state = base.CreateInitialState();