From e50d28ce118f5ade5c9abe9d729943f2257c1219 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Thu, 11 Aug 2022 11:37:41 +0200 Subject: [PATCH] Allow using external gesture handling alongside InputHandler through ExternalGestureHandling --- CHANGELOG.md | 1 + Docs/articles/input.md | 7 ++++++- MLEM/Input/InputHandler.cs | 26 ++++++++++++++++++++++++-- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f768f25..33ed32d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ Jump to version: ### MLEM Improvements - Improved EnumHelper.GetValues signature to return an array +- Allow using external gesture handling alongside InputHandler through ExternalGestureHandling ### MLEM.Ui Additions diff --git a/Docs/articles/input.md b/Docs/articles/input.md index c970cae..f2d0ae5 100644 --- a/Docs/articles/input.md +++ b/Docs/articles/input.md @@ -49,4 +49,9 @@ if (this.InputHandler.GetGesture(GestureType.Tap, out var sample)) { } else { // The gesture did not happen this frame } -``` \ No newline at end of file +``` + +### External gesture handling +If your game already handles gestures through some other means, you might notice that one of the gesture handling methods stops working correctly. This is due to the fact that MonoGame's gesture querying system only supports each gesture to be queried once before it is removed from the queue. + +If you want to continue using your own gesture handling, but still allow the `InputHandler` to use gestures (for [MLEM.Ui](ui.md), for example), you can set `GesturesExternal` to true in your `InputHandler`. Then, you can use `AddExternalGesture` to make the input handler aware of a gesture for the duration of the update frame that you added it on. diff --git a/MLEM/Input/InputHandler.cs b/MLEM/Input/InputHandler.cs index 6135eda..a3ef273 100644 --- a/MLEM/Input/InputHandler.cs +++ b/MLEM/Input/InputHandler.cs @@ -72,6 +72,12 @@ namespace MLEM.Input { /// Inverted behavior means that, instead of an input counting as pressed when it was up in the last frame and is now down, it will be counted as pressed when it was down in the last frame and is now up. /// public bool InvertPressBehavior; + /// + /// If your project already handles the processing of MonoGame's gestures elsewhere, you can set this field to true to ensure that this input handler's gesture handling does not override your own, since objects can only be retrieved once and are then removed from the 's queue. + /// If this value is set to true, but you still want to be able to use , , and , you can make this input handler aware of a gesture for the duration of the update frame that you added it on by using . + /// For more info, see https://mlem.ellpeck.de/articles/input.html#external-gesture-handling. + /// + public bool ExternalGestureHandling; /// /// An array of all , and values that are currently down. @@ -287,9 +293,12 @@ namespace MLEM.Input { this.ViewportTouchState = this.TouchState; } + // we still want to clear gestures when handling externally to maintain the per-frame gesture system this.gestures.Clear(); - while (active && TouchPanel.IsGestureAvailable) - this.gestures.Add(TouchPanel.ReadGesture()); + if (active && !this.ExternalGestureHandling) { + while (TouchPanel.IsGestureAvailable) + this.gestures.Add(TouchPanel.ReadGesture()); + } } if (this.inputsDownAccum.Count <= 0 && this.inputsDown.Count <= 0) { @@ -650,6 +659,19 @@ namespace MLEM.Input { return false; } + /// + /// Adds a gesture to the collection and allows it to be queried using and for the duration of the update frame that it was added on. + /// This method should be used when is set to true, but and should still be available. + /// For more info, see https://mlem.ellpeck.de/articles/input.html#external-gesture-handling. + /// + /// The gesture sample to add. + /// Thrown if is false. + public void AddExternalGesture(GestureSample sample) { + if (!this.ExternalGestureHandling) + throw new InvalidOperationException($"Cannot add external gestures if {nameof(this.ExternalGestureHandling)} is false"); + this.gestures.Add(sample); + } + /// /// Returns if a given control of any kind is down. /// This is a helper function that can be passed a , or .