A game framework written with osu! in mind.
at master 262 lines 13 kB view raw
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. 2// See the LICENCE file in the repository root for full licence text. 3 4using System; 5using System.Linq; 6using NUnit.Framework; 7using osu.Framework.Graphics; 8using osu.Framework.Graphics.Shapes; 9using osu.Framework.Input; 10using osu.Framework.Input.Events; 11using osu.Framework.Input.States; 12using osu.Framework.Testing; 13using osu.Framework.Testing.Input; 14using osuTK; 15using osuTK.Input; 16 17namespace osu.Framework.Tests.Visual.Input 18{ 19 public class TestScenePassThroughInputManager : ManualInputManagerTestScene 20 { 21 public TestScenePassThroughInputManager() 22 { 23 RelativeSizeAxes = Axes.Both; 24 } 25 26 private TestInputManager testInputManager; 27 private InputState state; 28 private ButtonStates<MouseButton> mouse; 29 private ButtonStates<Key> keyboard; 30 private ButtonStates<JoystickButton> joystick; 31 32 private void addTestInputManagerStep() 33 { 34 AddStep("Add InputManager", () => 35 { 36 testInputManager = new TestInputManager(); 37 Add(testInputManager); 38 state = testInputManager.CurrentState; 39 mouse = state.Mouse.Buttons; 40 keyboard = state.Keyboard.Keys; 41 joystick = state.Joystick.Buttons; 42 }); 43 } 44 45 [SetUp] 46 public new void SetUp() => Schedule(() => 47 { 48 ChildrenEnumerable = Enumerable.Empty<Drawable>(); 49 }); 50 51 [Test] 52 public void ReceiveInitialState() 53 { 54 AddStep("Press mouse left", () => InputManager.PressButton(MouseButton.Left)); 55 AddStep("Press A", () => InputManager.PressKey(Key.A)); 56 AddStep("Press Joystick", () => InputManager.PressJoystickButton(JoystickButton.Button1)); 57 addTestInputManagerStep(); 58 AddAssert("mouse left not pressed", () => !mouse.IsPressed(MouseButton.Left)); 59 AddAssert("A pressed", () => keyboard.IsPressed(Key.A)); 60 AddAssert("Joystick pressed", () => joystick.IsPressed(JoystickButton.Button1)); 61 AddStep("Release", () => 62 { 63 InputManager.ReleaseButton(MouseButton.Left); 64 InputManager.ReleaseKey(Key.A); 65 InputManager.ReleaseJoystickButton(JoystickButton.Button1); 66 }); 67 AddAssert("All released", () => !mouse.HasAnyButtonPressed && !keyboard.HasAnyButtonPressed && !joystick.HasAnyButtonPressed); 68 } 69 70 [Test] 71 public void UseParentInputChange() 72 { 73 addTestInputManagerStep(); 74 AddStep("Press buttons", () => 75 { 76 InputManager.PressButton(MouseButton.Left); 77 InputManager.PressKey(Key.A); 78 InputManager.PressJoystickButton(JoystickButton.Button1); 79 }); 80 AddAssert("pressed", () => mouse.IsPressed(MouseButton.Left) && keyboard.IsPressed(Key.A) && joystick.IsPressed(JoystickButton.Button1)); 81 AddStep("UseParentInput = false", () => testInputManager.UseParentInput = false); 82 AddAssert("still pressed", () => mouse.IsPressed(MouseButton.Left) && keyboard.IsPressed(Key.A) && joystick.IsPressed(JoystickButton.Button1)); 83 AddStep("Release on parent", () => 84 { 85 InputManager.ReleaseButton(MouseButton.Left); 86 InputManager.ReleaseKey(Key.A); 87 InputManager.ReleaseJoystickButton(JoystickButton.Button1); 88 }); 89 AddAssert("doen't affect child", () => mouse.IsPressed(MouseButton.Left) && keyboard.IsPressed(Key.A) && joystick.IsPressed(JoystickButton.Button1)); 90 AddStep("UseParentInput = true", () => testInputManager.UseParentInput = true); 91 AddAssert("all synced", () => !mouse.IsPressed(MouseButton.Left) && !keyboard.IsPressed(Key.A) && !joystick.IsPressed(JoystickButton.Button1)); 92 } 93 94 [Test] 95 public void TestUpReceivedOnDownFromSync() 96 { 97 addTestInputManagerStep(); 98 AddStep("UseParentInput = false", () => testInputManager.UseParentInput = false); 99 AddStep("press keyboard", () => InputManager.PressKey(Key.A)); 100 AddAssert("key not pressed", () => !testInputManager.CurrentState.Keyboard.Keys.HasAnyButtonPressed); 101 102 AddStep("UseParentInput = true", () => testInputManager.UseParentInput = true); 103 AddAssert("key pressed", () => testInputManager.CurrentState.Keyboard.Keys.Single() == Key.A); 104 105 AddStep("release keyboard", () => InputManager.ReleaseKey(Key.A)); 106 AddAssert("key released", () => !testInputManager.CurrentState.Keyboard.Keys.HasAnyButtonPressed); 107 } 108 109 [Test] 110 public void MouseDownNoSync() 111 { 112 addTestInputManagerStep(); 113 AddStep("UseParentInput = false", () => testInputManager.UseParentInput = false); 114 AddStep("Press left", () => InputManager.PressButton(MouseButton.Left)); 115 AddStep("UseParentInput = true", () => testInputManager.UseParentInput = true); 116 AddAssert("not pressed", () => !mouse.IsPressed(MouseButton.Left)); 117 } 118 119 [Test] 120 public void NoMouseUp() 121 { 122 addTestInputManagerStep(); 123 AddStep("Press left", () => InputManager.PressButton(MouseButton.Left)); 124 AddStep("UseParentInput = false", () => testInputManager.UseParentInput = false); 125 AddStep("Release and press", () => 126 { 127 InputManager.ReleaseButton(MouseButton.Left); 128 InputManager.PressButton(MouseButton.Left); 129 }); 130 AddStep("UseParentInput = true", () => testInputManager.UseParentInput = true); 131 AddAssert("pressed", () => mouse.IsPressed(MouseButton.Left)); 132 AddAssert("mouse up count == 0", () => testInputManager.Status.MouseUpCount == 0); 133 } 134 135 [Test] 136 public void TestTouchInput() 137 { 138 addTestInputManagerStep(); 139 AddStep("begin first touch", () => InputManager.BeginTouch(new Touch(TouchSource.Touch1, Vector2.Zero))); 140 AddAssert("synced properly", () => 141 testInputManager.CurrentState.Touch.ActiveSources.Single() == TouchSource.Touch1 && 142 testInputManager.CurrentState.Touch.TouchPositions[(int)TouchSource.Touch1] == Vector2.Zero); 143 144 AddStep("UseParentInput = false", () => testInputManager.UseParentInput = false); 145 AddStep("end first touch", () => InputManager.EndTouch(new Touch(TouchSource.Touch1, Vector2.Zero))); 146 AddStep("begin second touch", () => InputManager.BeginTouch(new Touch(TouchSource.Touch2, Vector2.One))); 147 148 AddStep("UseParentInput = true", () => testInputManager.UseParentInput = true); 149 AddAssert("synced properly", () => 150 testInputManager.CurrentState.Touch.ActiveSources.Single() == TouchSource.Touch2 && 151 testInputManager.CurrentState.Touch.TouchPositions[(int)TouchSource.Touch2] == Vector2.One); 152 153 AddStep("end second touch", () => InputManager.EndTouch(new Touch(TouchSource.Touch2, new Vector2(2)))); 154 AddAssert("synced properly", () => 155 !testInputManager.CurrentState.Touch.ActiveSources.HasAnyButtonPressed && 156 testInputManager.CurrentState.Touch.TouchPositions[(int)TouchSource.Touch2] == new Vector2(2)); 157 } 158 159 [Test] 160 public void TestMidiInput() 161 { 162 addTestInputManagerStep(); 163 164 AddStep("press C3", () => InputManager.PressMidiKey(MidiKey.C3, 70)); 165 AddAssert("synced properly", () => 166 testInputManager.CurrentState.Midi.Keys.IsPressed(MidiKey.C3) 167 && testInputManager.CurrentState.Midi.Velocities[MidiKey.C3] == 70); 168 169 AddStep("UseParentInput = false", () => testInputManager.UseParentInput = false); 170 AddStep("release C3", () => InputManager.ReleaseMidiKey(MidiKey.C3, 40)); 171 AddStep("press F#3", () => InputManager.PressMidiKey(MidiKey.FSharp3, 65)); 172 173 AddStep("UseParentInput = true", () => testInputManager.UseParentInput = true); 174 AddAssert("synced properly", () => 175 !testInputManager.CurrentState.Midi.Keys.IsPressed(MidiKey.C3) && 176 testInputManager.CurrentState.Midi.Velocities[MidiKey.C3] == 40 && 177 testInputManager.CurrentState.Midi.Keys.IsPressed(MidiKey.FSharp3) && 178 testInputManager.CurrentState.Midi.Velocities[MidiKey.FSharp3] == 65); 179 } 180 181 [Test] 182 public void TestMouseTouchProductionOnPassThrough() 183 { 184 addTestInputManagerStep(); 185 AddStep("setup hierarchy", () => 186 { 187 Add(new HandlingBox 188 { 189 Alpha = 0.5f, 190 Depth = 1, 191 RelativeSizeAxes = Axes.Both, 192 OnHandle = e => e is MouseEvent, 193 }); 194 195 testInputManager.Add(new HandlingBox 196 { 197 Alpha = 0.5f, 198 RelativeSizeAxes = Axes.Both, 199 OnHandle = e => e is TouchEvent, 200 }); 201 }); 202 203 AddStep("begin touch", () => InputManager.BeginTouch(new Touch(TouchSource.Touch1, testInputManager.ScreenSpaceDrawQuad.Centre))); 204 AddAssert("ensure parent manager produced mouse", () => 205 InputManager.CurrentState.Mouse.Buttons.Single() == MouseButton.Left && 206 InputManager.CurrentState.Mouse.Position == testInputManager.ScreenSpaceDrawQuad.Centre); 207 208 AddAssert("pass-through did not produce mouse", () => 209 !testInputManager.CurrentState.Mouse.Buttons.HasAnyButtonPressed && 210 testInputManager.CurrentState.Mouse.Position != testInputManager.ScreenSpaceDrawQuad.Centre); 211 212 AddStep("end touch", () => InputManager.EndTouch(new Touch(TouchSource.Touch1, testInputManager.ScreenSpaceDrawQuad.Centre))); 213 214 AddStep("press mouse", () => InputManager.PressButton(MouseButton.Left)); 215 AddAssert("pass-through handled mouse", () => testInputManager.CurrentState.Mouse.Buttons.Single() == MouseButton.Left); 216 } 217 218 [Test] 219 public void TestTabletButtonInput() 220 { 221 addTestInputManagerStep(); 222 223 AddStep("press primary pen button", () => InputManager.PressTabletPenButton(TabletPenButton.Primary)); 224 AddStep("press auxiliary button 4", () => InputManager.PressTabletAuxiliaryButton(TabletAuxiliaryButton.Button4)); 225 226 AddStep("UseParentInput = false", () => testInputManager.UseParentInput = false); 227 228 AddStep("release primary pen button", () => InputManager.ReleaseTabletPenButton(TabletPenButton.Primary)); 229 AddStep("press tertiary pen button", () => InputManager.PressTabletPenButton(TabletPenButton.Tertiary)); 230 AddStep("release auxiliary button 4", () => InputManager.ReleaseTabletAuxiliaryButton(TabletAuxiliaryButton.Button4)); 231 AddStep("press auxiliary button 2", () => InputManager.PressTabletAuxiliaryButton(TabletAuxiliaryButton.Button2)); 232 233 AddStep("UseParentInput = true", () => testInputManager.UseParentInput = true); 234 AddAssert("pen buttons synced properly", () => 235 !testInputManager.CurrentState.Tablet.PenButtons.Contains(TabletPenButton.Primary) 236 && testInputManager.CurrentState.Tablet.PenButtons.Contains(TabletPenButton.Tertiary)); 237 AddAssert("auxiliary buttons synced properly", () => 238 !testInputManager.CurrentState.Tablet.AuxiliaryButtons.Contains(TabletAuxiliaryButton.Button4) 239 && testInputManager.CurrentState.Tablet.AuxiliaryButtons.Contains(TabletAuxiliaryButton.Button2)); 240 } 241 242 public class TestInputManager : ManualInputManager 243 { 244 public readonly TestSceneInputManager.ContainingInputManagerStatusText Status; 245 246 public TestInputManager() 247 { 248 Size = new Vector2(0.8f); 249 Origin = Anchor.Centre; 250 Anchor = Anchor.Centre; 251 Child = Status = new TestSceneInputManager.ContainingInputManagerStatusText(); 252 } 253 } 254 255 public class HandlingBox : Box 256 { 257 public Func<UIEvent, bool> OnHandle; 258 259 protected override bool Handle(UIEvent e) => OnHandle?.Invoke(e) ?? false; 260 } 261 } 262}