Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change PassThroughInputManager to not sync new presses outside Handle() #6221

Merged
merged 11 commits into from
Jul 1, 2024
12 changes: 10 additions & 2 deletions osu.Framework.Tests/Visual/Input/TestSceneInputManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ public partial class ContainingInputManagerStatusText : Container
mouseStatus,
keyboardStatus,
joystickStatus,
touchStatus,
midiStatus,
tabletStatus,
onMouseDownStatus,
onMouseUpStatus,
onMouseMoveStatus,
Expand All @@ -100,6 +103,9 @@ public ContainingInputManagerStatusText()
mouseStatus = new SmallText(),
keyboardStatus = new SmallText(),
joystickStatus = new SmallText(),
touchStatus = new SmallText(),
midiStatus = new SmallText(),
tabletStatus = new SmallText(),
onMouseDownStatus = new SmallText { Text = "OnMouseDown 0" },
onMouseUpStatus = new SmallText { Text = "OnMouseUp 0" },
onMouseMoveStatus = new SmallText { Text = "OnMouseMove 0" },
Expand All @@ -114,11 +120,13 @@ protected override void Update()
{
var inputManager = GetContainingInputManager();
var currentState = inputManager!.CurrentState;
var mouse = currentState.Mouse;
inputManagerStatus.Text = $"{inputManager}";
mouseStatus.Text = $"Mouse: {mouse.Position} {mouse.Scroll} " + string.Join(' ', mouse.Buttons);
mouseStatus.Text = $"Mouse: {currentState.Mouse.Position} {currentState.Mouse.Scroll} " + string.Join(' ', currentState.Mouse.Buttons);
keyboardStatus.Text = "Keyboard: " + string.Join(' ', currentState.Keyboard.Keys);
joystickStatus.Text = "Joystick: " + string.Join(' ', currentState.Joystick.Buttons);
touchStatus.Text = $"Touch: {string.Join(' ', currentState.Touch.ActiveSources.Select(s => $"({s},{currentState.Touch.GetTouchPosition(s)})"))}";
midiStatus.Text = "MIDI: " + string.Join(' ', currentState.Midi.Keys.Select(k => $"({k},{currentState.Midi.Velocities[k]})"));
tabletStatus.Text = "Tablet: " + string.Join(' ', currentState.Tablet.PenButtons) + " " + string.Join(' ', currentState.Tablet.AuxiliaryButtons);
base.Update();
}

Expand Down
149 changes: 74 additions & 75 deletions osu.Framework.Tests/Visual/Input/TestScenePassThroughInputManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,6 @@ private void addTestInputManagerStep()
ChildrenEnumerable = Enumerable.Empty<Drawable>();
});

[Test]
public void ReceiveInitialState()
{
AddStep("Press mouse left", () => InputManager.PressButton(MouseButton.Left));
AddStep("Press A", () => InputManager.PressKey(Key.A));
AddStep("Press Joystick", () => InputManager.PressJoystickButton(JoystickButton.Button1));
addTestInputManagerStep();
AddAssert("mouse left not pressed", () => !mouse.IsPressed(MouseButton.Left));
AddAssert("A pressed", () => keyboard.IsPressed(Key.A));
AddAssert("Joystick pressed", () => joystick.IsPressed(JoystickButton.Button1));
AddStep("Release", () =>
{
InputManager.ReleaseButton(MouseButton.Left);
InputManager.ReleaseKey(Key.A);
InputManager.ReleaseJoystickButton(JoystickButton.Button1);
});
AddAssert("All released", () => !mouse.HasAnyButtonPressed && !keyboard.HasAnyButtonPressed && !joystick.HasAnyButtonPressed);
}

[Test]
public void UseParentInputChange()
{
Expand All @@ -94,22 +75,7 @@ public void UseParentInputChange()
}

[Test]
public void TestUpReceivedOnDownFromSync()
{
addTestInputManagerStep();
AddStep("UseParentInput = false", () => testInputManager.UseParentInput = false);
AddStep("press keyboard", () => InputManager.PressKey(Key.A));
AddAssert("key not pressed", () => !testInputManager.CurrentState.Keyboard.Keys.HasAnyButtonPressed);

AddStep("UseParentInput = true", () => testInputManager.UseParentInput = true);
AddAssert("key pressed", () => testInputManager.CurrentState.Keyboard.Keys.Single() == Key.A);

AddStep("release keyboard", () => InputManager.ReleaseKey(Key.A));
AddAssert("key released", () => !testInputManager.CurrentState.Keyboard.Keys.HasAnyButtonPressed);
}

[Test]
public void MouseDownNoSync()
public void TestMouseDownNoSync()
{
addTestInputManagerStep();
AddStep("UseParentInput = false", () => testInputManager.UseParentInput = false);
Expand All @@ -119,7 +85,7 @@ public void MouseDownNoSync()
}

[Test]
public void NoMouseUp()
public void TestNoMouseUp()
{
addTestInputManagerStep();
AddStep("Press left", () => InputManager.PressButton(MouseButton.Left));
Expand All @@ -134,28 +100,50 @@ public void NoMouseUp()
AddAssert("mouse up count == 0", () => testInputManager.Status.MouseUpCount == 0);
}

[Test]
public void TestKeyInput()
{
addTestInputManagerStep();
AddStep("press key", () => InputManager.PressKey(Key.A));
AddAssert("key pressed", () => testInputManager.CurrentState.Keyboard.Keys.Single() == Key.A);

AddStep("release key", () => InputManager.ReleaseKey(Key.A));
AddAssert("key released", () => !testInputManager.CurrentState.Keyboard.Keys.HasAnyButtonPressed);

AddStep("press key", () => InputManager.PressKey(Key.A));
AddStep("UseParentInput = false", () => testInputManager.UseParentInput = false);
AddStep("release key", () => InputManager.ReleaseKey(Key.A));
AddStep("press another key", () => InputManager.PressKey(Key.B));

AddAssert("only first key pressed", () => testInputManager.CurrentState.Keyboard.Keys.Single() == Key.A);

AddStep("UseParentInput = true", () => testInputManager.UseParentInput = true);
AddAssert("key released", () => !testInputManager.CurrentState.Keyboard.Keys.HasAnyButtonPressed);
}

[Test]
public void TestTouchInput()
{
addTestInputManagerStep();
AddStep("begin first touch", () => InputManager.BeginTouch(new Touch(TouchSource.Touch1, Vector2.Zero)));
AddAssert("synced properly", () =>
AddAssert("first touch active", () =>
testInputManager.CurrentState.Touch.ActiveSources.Single() == TouchSource.Touch1 &&
testInputManager.CurrentState.Touch.TouchPositions[(int)TouchSource.Touch1] == Vector2.Zero);

AddStep("end first touch", () => InputManager.EndTouch(new Touch(TouchSource.Touch1, Vector2.Zero)));
AddAssert("first touch not active", () => !testInputManager.CurrentState.Touch.ActiveSources.HasAnyButtonPressed);

AddStep("begin first touch", () => InputManager.BeginTouch(new Touch(TouchSource.Touch1, Vector2.Zero)));
AddStep("UseParentInput = false", () => testInputManager.UseParentInput = false);
AddStep("end first touch", () => InputManager.EndTouch(new Touch(TouchSource.Touch1, Vector2.Zero)));
AddStep("begin second touch", () => InputManager.BeginTouch(new Touch(TouchSource.Touch2, Vector2.One)));

AddAssert("only first touch active", () =>
testInputManager.CurrentState.Touch.ActiveSources.Single() == TouchSource.Touch1 &&
testInputManager.CurrentState.Touch.TouchPositions[(int)TouchSource.Touch1] == Vector2.Zero);

AddStep("UseParentInput = true", () => testInputManager.UseParentInput = true);
AddAssert("synced properly", () =>
testInputManager.CurrentState.Touch.ActiveSources.Single() == TouchSource.Touch2 &&
testInputManager.CurrentState.Touch.TouchPositions[(int)TouchSource.Touch2] == Vector2.One);

AddStep("end second touch", () => InputManager.EndTouch(new Touch(TouchSource.Touch2, new Vector2(2))));
AddAssert("synced properly", () =>
!testInputManager.CurrentState.Touch.ActiveSources.HasAnyButtonPressed &&
testInputManager.CurrentState.Touch.TouchPositions[(int)TouchSource.Touch2] == new Vector2(2));
AddAssert("no touches active", () => !testInputManager.CurrentState.Touch.ActiveSources.HasAnyButtonPressed);
}

[Test]
Expand All @@ -164,20 +152,55 @@ public void TestMidiInput()
addTestInputManagerStep();

AddStep("press C3", () => InputManager.PressMidiKey(MidiKey.C3, 70));
AddAssert("synced properly", () =>
AddAssert("C3 pressed", () =>
testInputManager.CurrentState.Midi.Keys.IsPressed(MidiKey.C3)
&& testInputManager.CurrentState.Midi.Velocities[MidiKey.C3] == 70);

AddStep("release C3", () => InputManager.ReleaseMidiKey(MidiKey.C3, 40));
AddAssert("C3 released", () => !testInputManager.CurrentState.Midi.Keys.HasAnyButtonPressed);

AddStep("press C3", () => InputManager.PressMidiKey(MidiKey.C3, 70));
AddStep("UseParentInput = false", () => testInputManager.UseParentInput = false);
AddStep("release C3", () => InputManager.ReleaseMidiKey(MidiKey.C3, 40));
AddStep("press F#3", () => InputManager.PressMidiKey(MidiKey.FSharp3, 65));

AddAssert("only C3 pressed", () =>
testInputManager.CurrentState.Midi.Keys.Single() == MidiKey.C3
&& testInputManager.CurrentState.Midi.Velocities[MidiKey.C3] == 70);

AddStep("UseParentInput = true", () => testInputManager.UseParentInput = true);
AddAssert("C3 released", () => !testInputManager.CurrentState.Midi.Keys.HasAnyButtonPressed);
}

[Test]
public void TestTabletButtonInput()
{
addTestInputManagerStep();

AddStep("press primary pen button", () => InputManager.PressTabletPenButton(TabletPenButton.Primary));
AddStep("press auxiliary button 4", () => InputManager.PressTabletAuxiliaryButton(TabletAuxiliaryButton.Button4));
AddAssert("primary pen button pressed", () => testInputManager.CurrentState.Tablet.PenButtons.Single() == TabletPenButton.Primary);
AddAssert("auxiliary button 4 pressed", () => testInputManager.CurrentState.Tablet.AuxiliaryButtons.Single() == TabletAuxiliaryButton.Button4);

AddStep("release primary pen button", () => InputManager.ReleaseTabletPenButton(TabletPenButton.Primary));
AddStep("release auxiliary button 4", () => InputManager.ReleaseTabletAuxiliaryButton(TabletAuxiliaryButton.Button4));
AddAssert("primary pen button pressed", () => !testInputManager.CurrentState.Tablet.PenButtons.HasAnyButtonPressed);
AddAssert("auxiliary button 4 pressed", () => !testInputManager.CurrentState.Tablet.AuxiliaryButtons.HasAnyButtonPressed);

AddStep("press primary pen button", () => InputManager.PressTabletPenButton(TabletPenButton.Primary));
AddStep("press auxiliary button 4", () => InputManager.PressTabletAuxiliaryButton(TabletAuxiliaryButton.Button4));
AddStep("UseParentInput = false", () => testInputManager.UseParentInput = false);
AddStep("release primary pen button", () => InputManager.ReleaseTabletPenButton(TabletPenButton.Primary));
AddStep("release auxiliary button 4", () => InputManager.ReleaseTabletAuxiliaryButton(TabletAuxiliaryButton.Button4));
AddStep("press secondary pen button", () => InputManager.PressTabletPenButton(TabletPenButton.Secondary));
AddStep("press auxiliary button 2", () => InputManager.PressTabletAuxiliaryButton(TabletAuxiliaryButton.Button2));

AddAssert("only primary pen button pressed", () => testInputManager.CurrentState.Tablet.PenButtons.Single() == TabletPenButton.Primary);
AddAssert("only auxiliary button 4 pressed", () => testInputManager.CurrentState.Tablet.AuxiliaryButtons.Single() == TabletAuxiliaryButton.Button4);

AddStep("UseParentInput = true", () => testInputManager.UseParentInput = true);
AddAssert("synced properly", () =>
!testInputManager.CurrentState.Midi.Keys.IsPressed(MidiKey.C3) &&
testInputManager.CurrentState.Midi.Velocities[MidiKey.C3] == 40 &&
testInputManager.CurrentState.Midi.Keys.IsPressed(MidiKey.FSharp3) &&
testInputManager.CurrentState.Midi.Velocities[MidiKey.FSharp3] == 65);
AddAssert("primary pen button released", () => !testInputManager.CurrentState.Tablet.PenButtons.HasAnyButtonPressed);
AddAssert("auxiliary button 4 released", () => !testInputManager.CurrentState.Tablet.AuxiliaryButtons.HasAnyButtonPressed);
}

[Test]
Expand Down Expand Up @@ -217,30 +240,6 @@ public void TestMouseTouchProductionOnPassThrough()
AddAssert("pass-through handled mouse", () => testInputManager.CurrentState.Mouse.Buttons.Single() == MouseButton.Left);
}

[Test]
public void TestTabletButtonInput()
{
addTestInputManagerStep();

AddStep("press primary pen button", () => InputManager.PressTabletPenButton(TabletPenButton.Primary));
AddStep("press auxiliary button 4", () => InputManager.PressTabletAuxiliaryButton(TabletAuxiliaryButton.Button4));

AddStep("UseParentInput = false", () => testInputManager.UseParentInput = false);

AddStep("release primary pen button", () => InputManager.ReleaseTabletPenButton(TabletPenButton.Primary));
AddStep("press tertiary pen button", () => InputManager.PressTabletPenButton(TabletPenButton.Tertiary));
AddStep("release auxiliary button 4", () => InputManager.ReleaseTabletAuxiliaryButton(TabletAuxiliaryButton.Button4));
AddStep("press auxiliary button 2", () => InputManager.PressTabletAuxiliaryButton(TabletAuxiliaryButton.Button2));

AddStep("UseParentInput = true", () => testInputManager.UseParentInput = true);
AddAssert("pen buttons synced properly", () =>
!testInputManager.CurrentState.Tablet.PenButtons.Contains(TabletPenButton.Primary)
&& testInputManager.CurrentState.Tablet.PenButtons.Contains(TabletPenButton.Tertiary));
AddAssert("auxiliary buttons synced properly", () =>
!testInputManager.CurrentState.Tablet.AuxiliaryButtons.Contains(TabletAuxiliaryButton.Button4)
&& testInputManager.CurrentState.Tablet.AuxiliaryButtons.Contains(TabletAuxiliaryButton.Button2));
}

public partial class TestInputManager : ManualInputManager
{
public readonly TestSceneInputManager.ContainingInputManagerStatusText Status;
Expand Down
Loading
Loading