mirror of
https://github.com/Pathoschild/SMAPI.git
synced 2026-10-12 02:08:51 +00:00
reduce allocations in input handling
This reuses the input builders instead of creating new ones each time we build input.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
# Release notes
|
||||
## Upcoming release
|
||||
* For players:
|
||||
* Minor performance optimizations.
|
||||
* Fixed the Linux/macOS installer not saving the color scheme correctly in 4.5.0+.
|
||||
* Fixed typo in config UI text (thanks to QuentiumYT!).
|
||||
* Improved translations. Thanks to dewanggatrustha (updated Indonesian), QuentiumYT (updated French), and Timur13240
|
||||
|
||||
@@ -21,7 +21,7 @@ internal class GamePadStateBuilder : IInputStateBuilder<GamePadStateBuilder, Gam
|
||||
private GamePadState? State;
|
||||
|
||||
/// <summary>The current button states.</summary>
|
||||
private readonly Dictionary<SButton, ButtonState> ButtonStates;
|
||||
private readonly Dictionary<SButton, ButtonState> ButtonStates = [];
|
||||
|
||||
/// <summary>The left trigger value.</summary>
|
||||
private float LeftTrigger;
|
||||
@@ -39,9 +39,8 @@ internal class GamePadStateBuilder : IInputStateBuilder<GamePadStateBuilder, Gam
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="state">The initial state.</param>
|
||||
public GamePadStateBuilder(GamePadState state)
|
||||
/// <inheritdoc />
|
||||
public void Reset(GamePadState state)
|
||||
{
|
||||
this.State = state;
|
||||
|
||||
@@ -51,32 +50,39 @@ internal class GamePadStateBuilder : IInputStateBuilder<GamePadStateBuilder, Gam
|
||||
GamePadButtons buttons = state.Buttons;
|
||||
GamePadTriggers triggers = state.Triggers;
|
||||
GamePadThumbSticks sticks = state.ThumbSticks;
|
||||
this.ButtonStates = new Dictionary<SButton, ButtonState>
|
||||
{
|
||||
[SButton.DPadUp] = pad.Up,
|
||||
[SButton.DPadDown] = pad.Down,
|
||||
[SButton.DPadLeft] = pad.Left,
|
||||
[SButton.DPadRight] = pad.Right,
|
||||
|
||||
[SButton.ControllerA] = buttons.A,
|
||||
[SButton.ControllerB] = buttons.B,
|
||||
[SButton.ControllerX] = buttons.X,
|
||||
[SButton.ControllerY] = buttons.Y,
|
||||
[SButton.LeftStick] = buttons.LeftStick,
|
||||
[SButton.RightStick] = buttons.RightStick,
|
||||
[SButton.LeftShoulder] = buttons.LeftShoulder,
|
||||
[SButton.RightShoulder] = buttons.RightShoulder,
|
||||
[SButton.ControllerBack] = buttons.Back,
|
||||
[SButton.ControllerStart] = buttons.Start,
|
||||
[SButton.BigButton] = buttons.BigButton
|
||||
};
|
||||
var states = this.ButtonStates;
|
||||
states.Clear();
|
||||
states[SButton.DPadUp] = pad.Up;
|
||||
states[SButton.DPadDown] = pad.Down;
|
||||
states[SButton.DPadLeft] = pad.Left;
|
||||
states[SButton.DPadRight] = pad.Right;
|
||||
states[SButton.ControllerA] = buttons.A;
|
||||
states[SButton.ControllerB] = buttons.B;
|
||||
states[SButton.ControllerX] = buttons.X;
|
||||
states[SButton.ControllerY] = buttons.Y;
|
||||
states[SButton.LeftStick] = buttons.LeftStick;
|
||||
states[SButton.RightStick] = buttons.RightStick;
|
||||
states[SButton.LeftShoulder] = buttons.LeftShoulder;
|
||||
states[SButton.RightShoulder] = buttons.RightShoulder;
|
||||
states[SButton.ControllerBack] = buttons.Back;
|
||||
states[SButton.ControllerStart] = buttons.Start;
|
||||
states[SButton.BigButton] = buttons.BigButton;
|
||||
|
||||
this.LeftTrigger = triggers.Left;
|
||||
this.RightTrigger = triggers.Right;
|
||||
this.LeftStickPos = sticks.Left;
|
||||
this.RightStickPos = sticks.Right;
|
||||
}
|
||||
else
|
||||
this.ButtonStates = [];
|
||||
{
|
||||
this.ButtonStates.Clear();
|
||||
|
||||
this.LeftTrigger = 0;
|
||||
this.RightTrigger = 0;
|
||||
this.LeftStickPos = Vector2.Zero;
|
||||
this.RightStickPos = Vector2.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -12,6 +12,10 @@ internal interface IInputStateBuilder<out THandler, TState>
|
||||
/*********
|
||||
** Methods
|
||||
*********/
|
||||
/// <summary>Reset the state.</summary>
|
||||
/// <param name="state">The initial state before any overrides are applied.</param>
|
||||
void Reset(TState state);
|
||||
|
||||
/// <summary>Override the states for a set of buttons.</summary>
|
||||
/// <param name="overrides">The button state overrides.</param>
|
||||
THandler OverrideButtons(IDictionary<SButton, SButtonState> overrides);
|
||||
|
||||
@@ -20,9 +20,8 @@ internal class KeyboardStateBuilder : IInputStateBuilder<KeyboardStateBuilder, K
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="state">The initial state.</param>
|
||||
public KeyboardStateBuilder(KeyboardState state)
|
||||
/// <inheritdoc />
|
||||
public void Reset(KeyboardState state)
|
||||
{
|
||||
this.State = state;
|
||||
|
||||
|
||||
@@ -13,39 +13,38 @@ internal class MouseStateBuilder : IInputStateBuilder<MouseStateBuilder, MouseSt
|
||||
private MouseState? State;
|
||||
|
||||
/// <summary>The current button states.</summary>
|
||||
private readonly IDictionary<SButton, ButtonState> ButtonStates;
|
||||
private readonly Dictionary<SButton, ButtonState> ButtonStates = [];
|
||||
|
||||
/// <summary>The mouse wheel scroll value.</summary>
|
||||
private readonly int ScrollWheelValue;
|
||||
private int ScrollWheelValue;
|
||||
|
||||
|
||||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/// <summary>The X cursor position.</summary>
|
||||
public int X { get; }
|
||||
public int X { get; private set; }
|
||||
|
||||
/// <summary>The Y cursor position.</summary>
|
||||
public int Y { get; }
|
||||
public int Y { get; private set; }
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="state">The initial state.</param>
|
||||
public MouseStateBuilder(MouseState state)
|
||||
/// <inheritdoc />
|
||||
public void Reset(MouseState state)
|
||||
{
|
||||
this.State = state;
|
||||
|
||||
this.ButtonStates = new Dictionary<SButton, ButtonState>
|
||||
{
|
||||
[SButton.MouseLeft] = state.LeftButton,
|
||||
[SButton.MouseMiddle] = state.MiddleButton,
|
||||
[SButton.MouseRight] = state.RightButton,
|
||||
[SButton.MouseX1] = state.XButton1,
|
||||
[SButton.MouseX2] = state.XButton2
|
||||
};
|
||||
var states = this.ButtonStates;
|
||||
states.Clear();
|
||||
states[SButton.MouseLeft] = state.LeftButton;
|
||||
states[SButton.MouseMiddle] = state.MiddleButton;
|
||||
states[SButton.MouseRight] = state.RightButton;
|
||||
states[SButton.MouseX1] = state.XButton1;
|
||||
states[SButton.MouseX2] = state.XButton2;
|
||||
|
||||
this.X = state.X;
|
||||
this.Y = state.Y;
|
||||
this.ScrollWheelValue = state.ScrollWheelValue;
|
||||
|
||||
@@ -29,6 +29,15 @@ internal sealed class SInputState : InputState
|
||||
/// <summary>Whether there are new overrides in <see cref="CustomPressedKeys"/> or <see cref="CustomReleasedKeys"/> that haven't been applied to the previous state.</summary>
|
||||
private bool HasNewOverrides;
|
||||
|
||||
/// <summary>The builder which reads the game pad state and applies overrides.</summary>
|
||||
private readonly GamePadStateBuilder ControllerStateBuilder = new();
|
||||
|
||||
/// <summary>The builder which reads the keyboard state and applies overrides.</summary>
|
||||
private readonly KeyboardStateBuilder KeyboardStateBuilder = new();
|
||||
|
||||
/// <summary>The builder which reads the mouse state and applies overrides.</summary>
|
||||
private readonly MouseStateBuilder MouseStateBuilder = new();
|
||||
|
||||
|
||||
/*********
|
||||
** Accessors
|
||||
@@ -68,10 +77,15 @@ internal sealed class SInputState : InputState
|
||||
{
|
||||
float zoomMultiplier = (1f / Game1.options.zoomLevel);
|
||||
|
||||
// get builders
|
||||
GamePadStateBuilder controller = this.ControllerStateBuilder;
|
||||
KeyboardStateBuilder keyboard = this.KeyboardStateBuilder;
|
||||
MouseStateBuilder mouse = this.MouseStateBuilder;
|
||||
|
||||
// get real values
|
||||
var controller = new GamePadStateBuilder(base.GetGamePadState());
|
||||
var keyboard = new KeyboardStateBuilder(base.GetKeyboardState());
|
||||
var mouse = new MouseStateBuilder(base.GetMouseState());
|
||||
controller.Reset(base.GetGamePadState());
|
||||
keyboard.Reset(base.GetKeyboardState());
|
||||
mouse.Reset(base.GetMouseState());
|
||||
Vector2 cursorAbsolutePos = new((mouse.X * zoomMultiplier) + Game1.viewport.X, (mouse.Y * zoomMultiplier) + Game1.viewport.Y);
|
||||
Vector2? playerTilePos = Context.IsPlayerFree ? Game1.player.Tile : null;
|
||||
HashSet<SButton> reallyDown = new(this.GetPressedButtons(keyboard, mouse, controller));
|
||||
@@ -159,9 +173,13 @@ internal sealed class SInputState : InputState
|
||||
{
|
||||
if (this.HasNewOverrides)
|
||||
{
|
||||
var controller = new GamePadStateBuilder(this.ControllerState);
|
||||
var keyboard = new KeyboardStateBuilder(this.KeyboardState);
|
||||
var mouse = new MouseStateBuilder(this.MouseState);
|
||||
GamePadStateBuilder controller = this.ControllerStateBuilder;
|
||||
KeyboardStateBuilder keyboard = this.KeyboardStateBuilder;
|
||||
MouseStateBuilder mouse = this.MouseStateBuilder;
|
||||
|
||||
controller.Reset(this.ControllerState);
|
||||
keyboard.Reset(this.KeyboardState);
|
||||
mouse.Reset(this.MouseState);
|
||||
|
||||
if (this.ApplyOverrides(pressed: this.CustomPressedKeys, released: this.CustomReleasedKeys, controller, keyboard, mouse))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user