diff --git a/CHANGELOG.md b/CHANGELOG.md index e97aa16..c5fd404 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ Jump to version: - [5.0.0](#500) ## 5.4.0 (Unreleased) +### MLEM +Additions +- Added consuming variants of IsPressed methods to InputHandler ### MLEM.Ui Fixes diff --git a/MLEM/Input/InputHandler.cs b/MLEM/Input/InputHandler.cs index d5e4491..d275656 100644 --- a/MLEM/Input/InputHandler.cs +++ b/MLEM/Input/InputHandler.cs @@ -140,6 +140,7 @@ namespace MLEM.Input { private readonly bool[] triggerGamepadButtonRepeat = new bool[GamePad.MaximumGamePadCount]; private readonly Buttons?[] heldGamepadButtons = new Buttons?[GamePad.MaximumGamePadCount]; private readonly List gestures = new List(); + private readonly HashSet<(GenericInput, int)> consumedPresses = new HashSet<(GenericInput, int)>(); private Point ViewportOffset => new Point(-this.Game.GraphicsDevice.Viewport.X, -this.Game.GraphicsDevice.Viewport.Y); private Dictionary<(GenericInput, int), DateTime> inputsDownAccum = new Dictionary<(GenericInput, int), DateTime>(); @@ -171,6 +172,9 @@ namespace MLEM.Input { public void Update() { var now = DateTime.UtcNow; var active = this.Game.IsActive; + + this.consumedPresses.Clear(); + if (this.HandleKeyboard) { this.LastKeyboardState = this.KeyboardState; this.KeyboardState = active ? Keyboard.GetState() : default; @@ -351,6 +355,22 @@ namespace MLEM.Input { return this.WasKeyUp(key) && this.IsKeyDown(key); } + /// + /// Returns whether the given key is considered pressed, and marks the press as consumed if it is. + /// A key is considered pressed if it was not down the last update call, but is down the current update call. + /// A key press is considered consumed if this method has already returned true previously since the last call. + /// If is true, this method will also return true to signify a key repeat. + /// + /// The key to query. + /// If the key is pressed and the press is not consumed yet. + public bool TryConsumeKeyPressed(Keys key) { + if (this.IsKeyPressed(key) && !this.consumedPresses.Contains((key, -1))) { + this.consumedPresses.Add((key, -1)); + return true; + } + return false; + } + /// /// Returns whether the given modifier key is down. /// @@ -410,6 +430,21 @@ namespace MLEM.Input { return this.WasMouseButtonUp(button) && this.IsMouseButtonDown(button); } + /// + /// Returns whether the given mouse button is considered pressed, and marks the press as consumed if it is. + /// A mouse button is considered pressed if it was up the last update call, and is down the current update call. + /// A mouse button press is considered consumed if this method has already returned true previously since the last call. + /// + /// The button to query. + /// If the button is pressed and the press is not consumed yet. + public bool TryConsumeMouseButtonPressed(MouseButton button) { + if (this.IsMouseButtonPressed(button) && !this.consumedPresses.Contains((button, -1))) { + this.consumedPresses.Add((button, -1)); + return true; + } + return false; + } + /// public bool IsGamepadButtonDown(Buttons button, int index = -1) { if (index < 0) { @@ -492,6 +527,23 @@ namespace MLEM.Input { return this.WasGamepadButtonUp(button, index) && this.IsGamepadButtonDown(button, index); } + /// + /// Returns whether the given gamepad button on the given index is considered pressed, and marks the press as consumed if it is. + /// A gamepad button is considered pressed if it was down the last update call, and is up the current update call. + /// A gamepad button press is considered consumed if this method has already returned true previously since the last call. + /// If is true, this method will also return true to signify a gamepad button repeat. + /// + /// The button to query. + /// The zero-based index of the gamepad, or -1 for any gamepad. + /// Whether the given button is pressed and the press is not consumed yet. + public bool TryConsumeGamepadButtonPressed(Buttons button, int index = -1) { + if (this.IsGamepadButtonPressed(button) && !this.consumedPresses.Contains((button, index))) { + this.consumedPresses.Add((button, index)); + return true; + } + return false; + } + /// /// Queries for a gesture of a given type that finished during the current update call. /// @@ -552,7 +604,7 @@ namespace MLEM.Input { /// /// The control whose up state to query /// The index of the gamepad to query (if applicable), or -1 for any gamepad - /// Whether the given control is down + /// Whether the given control is up. /// If the passed control isn't of a supported type public bool IsUp(GenericInput control, int index = -1) { switch (control.Type) { @@ -573,7 +625,7 @@ namespace MLEM.Input { /// /// The control whose pressed state to query /// The index of the gamepad to query (if applicable), or -1 for any gamepad - /// Whether the given control is down + /// Whether the given control is pressed. /// If the passed control isn't of a supported type public bool IsPressed(GenericInput control, int index = -1) { switch (control.Type) { @@ -588,6 +640,26 @@ namespace MLEM.Input { } } + /// + /// Returns if a given control of any kind is pressed, and marks the press as consumed if it is. + /// This is a helper function that can be passed a , or . + /// + /// The control whose pressed state to query. + /// The index of the gamepad to query (if applicable), or -1 for any gamepad. + /// Whether the given control is pressed and the press is not consumed yet. + public bool TryConsumePressed(GenericInput control, int index = -1) { + switch (control.Type) { + case GenericInput.InputType.Keyboard: + return this.TryConsumeKeyPressed(control); + case GenericInput.InputType.Gamepad: + return this.TryConsumeGamepadButtonPressed(control, index); + case GenericInput.InputType.Mouse: + return this.TryConsumeMouseButtonPressed(control); + default: + return false; + } + } + /// public bool IsAnyDown(params GenericInput[] controls) { foreach (var control in controls) {