A game framework written with osu! in mind.
at master 5.7 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 NUnit.Framework; 6using osu.Framework.Graphics; 7using osu.Framework.Graphics.Shapes; 8using osu.Framework.Input.Events; 9using osu.Framework.Testing; 10using osuTK; 11using osuTK.Input; 12 13namespace osu.Framework.Tests.Input 14{ 15 [HeadlessTest] 16 public class KeyboardInputTest : ManualInputManagerTestScene 17 { 18 /// <summary> 19 /// Tests that if the hierarchy is changed while a key is held, the <see cref="Drawable.OnKeyUp"/> event is 20 /// only propagated to the hierarchy that originally handled <see cref="Drawable.OnKeyDown"/>. 21 /// </summary> 22 [Test] 23 public void TestKeyUpOnlyPropagatedToOriginalTargets() 24 { 25 var receptors = new InputReceptor[3]; 26 27 AddStep("create hierarchy", () => 28 { 29 Children = new Drawable[] 30 { 31 receptors[0] = new InputReceptor 32 { 33 Size = new Vector2(100), 34 KeyDown = () => true 35 }, 36 receptors[1] = new InputReceptor { Size = new Vector2(100) } 37 }; 38 }); 39 40 AddStep("press key", () => InputManager.PressKey(Key.A)); 41 AddStep("add receptor above", () => 42 { 43 Add(receptors[2] = new InputReceptor 44 { 45 Size = new Vector2(100), 46 KeyDown = () => true, 47 KeyUp = () => true 48 }); 49 }); 50 51 AddStep("release key", () => InputManager.ReleaseKey(Key.A)); 52 53 AddAssert("receptor 0 handled key down", () => receptors[0].DownReceived); 54 AddAssert("receptor 0 handled key up", () => receptors[0].UpReceived); 55 AddAssert("receptor 1 handled key down", () => receptors[1].DownReceived); 56 AddAssert("receptor 1 handled key up", () => receptors[1].UpReceived); 57 AddAssert("receptor 2 did not handle key down", () => !receptors[2].DownReceived); 58 AddAssert("receptor 2 did not handle key up", () => !receptors[2].UpReceived); 59 } 60 61 /// <summary> 62 /// Tests that a drawable that is removed from the hierarchy (or is otherwise removed from the input queues) won't receive OnKeyDown() events for every subsequent repeat. 63 /// </summary> 64 [Test] 65 public void TestNoLongerValidDrawableDoesNotReceiveRepeat() 66 { 67 var receptors = new InputReceptor[2]; 68 69 AddStep("create hierarchy", () => 70 { 71 Children = new Drawable[] 72 { 73 receptors[0] = new InputReceptor { Size = new Vector2(100) }, 74 receptors[1] = new InputReceptor { Size = new Vector2(100) } 75 }; 76 }); 77 78 AddStep("press key", () => InputManager.PressKey(Key.A)); 79 AddUntilStep("wait for repeat on receptor 0", () => receptors[0].RepeatReceived); 80 81 AddStep("remove receptor 0 & reset repeat", () => 82 { 83 Remove(receptors[0]); 84 receptors[0].RepeatReceived = false; 85 receptors[1].RepeatReceived = false; 86 }); 87 88 AddUntilStep("wait for repeat on receptor 1", () => receptors[1].RepeatReceived); 89 AddAssert("receptor 0 did not receive repeat", () => !receptors[0].RepeatReceived); 90 } 91 92 /// <summary> 93 /// Tests that a drawable that was previously removed from the hierarchy receives repeat OnKeyDown() events when re-added to the hierarchy, 94 /// if it previously received a non-repeat OnKeyDown() event. 95 /// </summary> 96 [Test] 97 public void TestReValidatedDrawableReceivesRepeat() 98 { 99 var receptors = new InputReceptor[2]; 100 101 AddStep("create hierarchy", () => 102 { 103 Children = new Drawable[] 104 { 105 receptors[0] = new InputReceptor { Size = new Vector2(100) }, 106 receptors[1] = new InputReceptor { Size = new Vector2(100) } 107 }; 108 }); 109 110 AddStep("press key", () => InputManager.PressKey(Key.A)); 111 AddStep("remove receptor 0 & reset repeat", () => 112 { 113 Remove(receptors[0]); 114 receptors[0].RepeatReceived = false; 115 receptors[1].RepeatReceived = false; 116 }); 117 118 AddUntilStep("wait for repeat on receptor 1", () => receptors[1].RepeatReceived); 119 AddStep("add back receptor 0", () => Add(receptors[0])); 120 121 AddUntilStep("wait for repeat on receptor 0", () => receptors[0].RepeatReceived); 122 } 123 124 private class InputReceptor : Box 125 { 126 public bool DownReceived { get; set; } 127 public bool UpReceived { get; set; } 128 public bool RepeatReceived { get; set; } 129 130 public Func<bool> KeyDown; 131 public Func<bool> KeyUp; 132 133 protected override bool OnKeyDown(KeyDownEvent e) 134 { 135 if (e.Repeat) 136 { 137 RepeatReceived = true; 138 return false; 139 } 140 141 DownReceived = true; 142 return KeyDown?.Invoke() ?? false; 143 } 144 145 protected override void OnKeyUp(KeyUpEvent e) 146 { 147 UpReceived = true; 148 KeyUp?.Invoke(); 149 } 150 } 151 } 152}