Skip to content

Commit

Permalink
Optimise away all allocations during input PassThroughInputManager
Browse files Browse the repository at this point in the history
…state sync
  • Loading branch information
peppy committed Jan 10, 2024
1 parent 41b7c32 commit de5ad34
Showing 1 changed file with 50 additions and 17 deletions.
67 changes: 50 additions & 17 deletions osu.Framework/Input/PassThroughInputManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using osu.Framework.Input.States;
using osuTK;
using osuTK.Input;
using JoystickState = osu.Framework.Input.States.JoystickState;

namespace osu.Framework.Input
{
Expand Down Expand Up @@ -176,24 +177,56 @@ protected virtual void SyncInputState(InputState state)
// invariant: if mouse button is currently pressed, then it has been pressed in parent (but not the converse)
// therefore, mouse up events are always synced from parent
// mouse down events are not synced to prevent false clicks
var mouseButtonDifference = (state?.Mouse?.Buttons ?? new ButtonStates<MouseButton>()).EnumerateDifference(CurrentState.Mouse.Buttons);
new MouseButtonInput(mouseButtonDifference.Released.Select(button => new ButtonInputEntry<MouseButton>(button, false))).Apply(CurrentState, this);

new KeyboardKeyInput(state?.Keyboard?.Keys, CurrentState.Keyboard.Keys).Apply(CurrentState, this);

var touchStateDifference = (state?.Touch ?? new TouchState()).EnumerateDifference(CurrentState.Touch);
if (touchStateDifference.deactivated.Length > 0)
new TouchInput(touchStateDifference.deactivated, false).Apply(CurrentState, this);
if (touchStateDifference.activated.Length > 0)
new TouchInput(touchStateDifference.activated, true).Apply(CurrentState, this);

new JoystickButtonInput(state?.Joystick?.Buttons ?? new ButtonStates<JoystickButton>(), CurrentState.Joystick.Buttons).Apply(CurrentState, this);
new JoystickAxisInput(state?.Joystick?.GetAxes() ?? Array.Empty<JoystickAxis>()).Apply(CurrentState, this);

new MidiKeyInput(state?.Midi ?? new MidiState(), CurrentState.Midi).Apply(CurrentState, this);
var mouseDiff = (state?.Mouse?.Buttons ?? new ButtonStates<MouseButton>()).EnumerateDifference(CurrentState.Mouse.Buttons);
if (mouseDiff.Released.Length > 0)
new MouseButtonInput(mouseDiff.Released.Select(button => new ButtonInputEntry<MouseButton>(button, false))).Apply(CurrentState, this);

var keyDiff = (state?.Keyboard.Keys ?? new ButtonStates<Key>()).EnumerateDifference(CurrentState.Keyboard.Keys);
foreach (var key in keyDiff.Released)
new KeyboardKeyInput(key, false).Apply(CurrentState, this);
foreach (var key in keyDiff.Pressed)
new KeyboardKeyInput(key, true).Apply(CurrentState, this);

var touchDiff = (state?.Touch ?? new TouchState()).EnumerateDifference(CurrentState.Touch);
if (touchDiff.deactivated.Length > 0)
new TouchInput(touchDiff.deactivated, false).Apply(CurrentState, this);
if (touchDiff.activated.Length > 0)
new TouchInput(touchDiff.activated, true).Apply(CurrentState, this);

var joyButtonDiff = (state?.Joystick?.Buttons ?? new ButtonStates<JoystickButton>()).EnumerateDifference(CurrentState.Joystick.Buttons);
foreach (var button in joyButtonDiff.Released)
new JoystickButtonInput(button, false).Apply(CurrentState, this);
foreach (var button in joyButtonDiff.Pressed)
new JoystickButtonInput(button, true).Apply(CurrentState, this);

// Basically only perform the full state diff if we have found that any axis changed.
// This avoids unnecessary alloc overhead.
for (int i = 0; i < JoystickState.MAX_AXES; i++)
{
if (state?.Joystick?.AxesValues[i] != CurrentState.Joystick.AxesValues[i])
{
new JoystickAxisInput(state?.Joystick?.GetAxes() ?? Array.Empty<JoystickAxis>()).Apply(CurrentState, this);
break;
}
}

new TabletPenButtonInput(state?.Tablet.PenButtons ?? new ButtonStates<TabletPenButton>(), CurrentState.Tablet.PenButtons).Apply(CurrentState, this);
new TabletAuxiliaryButtonInput(state?.Tablet.AuxiliaryButtons ?? new ButtonStates<TabletAuxiliaryButton>(), CurrentState.Tablet.AuxiliaryButtons).Apply(CurrentState, this);
var midiDiff = (state?.Midi?.Keys ?? new ButtonStates<MidiKey>()).EnumerateDifference(CurrentState.Midi.Keys);
foreach (var key in midiDiff.Released)
new MidiKeyInput(key, CurrentState.Midi.Velocities[key], false).Apply(CurrentState, this);
foreach (var key in midiDiff.Pressed)
new MidiKeyInput(key, state!.Midi!.Velocities[key], true).Apply(CurrentState, this);

var tabletPenDiff = (state?.Tablet?.PenButtons ?? new ButtonStates<TabletPenButton>()).EnumerateDifference(CurrentState.Tablet.PenButtons);
foreach (var button in tabletPenDiff.Released)
new TabletPenButtonInput(button, false).Apply(CurrentState, this);
foreach (var button in tabletPenDiff.Pressed)
new TabletPenButtonInput(button, true).Apply(CurrentState, this);

var tabletAuxiliaryDiff = (state?.Tablet?.AuxiliaryButtons ?? new ButtonStates<TabletAuxiliaryButton>()).EnumerateDifference(CurrentState.Tablet.AuxiliaryButtons);
foreach (var button in tabletAuxiliaryDiff.Released)
new TabletAuxiliaryButtonInput(button, false).Apply(CurrentState, this);
foreach (var button in tabletAuxiliaryDiff.Pressed)
new TabletAuxiliaryButtonInput(button, true).Apply(CurrentState, this);
}
}
}

0 comments on commit de5ad34

Please sign in to comment.