From 5d4e6cf86ad830e49eec31aa3f9fde6ff7742d2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Wed, 21 Aug 2024 00:47:54 +0200 Subject: [PATCH] Support handling touch state as part of the client update So the touch state can be handled by gameclient components independently from their rendering, so touch inputs are not skipped when frames are. --- src/engine/client/input.cpp | 13 +++++++++---- src/engine/client/input.h | 1 + src/engine/input.h | 6 ++++++ src/game/client/component.h | 8 ++++++++ src/game/client/gameclient.cpp | 17 +++++++++++++++++ 5 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/engine/client/input.cpp b/src/engine/client/input.cpp index f94894eca..29ee33982 100644 --- a/src/engine/client/input.cpp +++ b/src/engine/client/input.cpp @@ -300,6 +300,14 @@ const std::vector &CInput::TouchFingerStates() const return m_vTouchFingerStates; } +void CInput::ClearTouchDeltas() +{ + for(CTouchFingerState &TouchFingerState : m_vTouchFingerStates) + { + TouchFingerState.m_Delta = vec2(0.0f, 0.0f); + } +} + std::string CInput::GetClipboardText() { char *pClipboardText = SDL_GetClipboardText(); @@ -347,10 +355,7 @@ void CInput::Clear() mem_zero(m_aInputState, sizeof(m_aInputState)); mem_zero(m_aInputCount, sizeof(m_aInputCount)); m_vInputEvents.clear(); - for(CTouchFingerState &TouchFingerState : m_vTouchFingerStates) - { - TouchFingerState.m_Delta = vec2(0.0f, 0.0f); - } + ClearTouchDeltas(); } float CInput::GetUpdateTime() const diff --git a/src/engine/client/input.h b/src/engine/client/input.h index 70127785f..4194bd2a3 100644 --- a/src/engine/client/input.h +++ b/src/engine/client/input.h @@ -144,6 +144,7 @@ public: bool NativeMousePressed(int Index) const override; const std::vector &TouchFingerStates() const override; + void ClearTouchDeltas() override; std::string GetClipboardText() override; void SetClipboardText(const char *pText) override; diff --git a/src/engine/input.h b/src/engine/input.h index 9aa873358..edfc14596 100644 --- a/src/engine/input.h +++ b/src/engine/input.h @@ -137,6 +137,12 @@ public: * @return vector of all touch finger states */ virtual const std::vector &TouchFingerStates() const = 0; + /** + * Must be called after the touch finger states have been used during the client update to ensure that + * touch deltas are only accumulated until the next update. If the touch states are only used during + * rendering, i.e. for user interfaces, then this is called automatically by calling @link Clear @endlink. + */ + virtual void ClearTouchDeltas() = 0; // clipboard virtual std::string GetClipboardText() = 0; diff --git a/src/game/client/component.h b/src/game/client/component.h index 639c8b140..9d14615a0 100644 --- a/src/game/client/component.h +++ b/src/game/client/component.h @@ -212,6 +212,14 @@ public: * @param Event The input event. */ virtual bool OnInput(const IInput::CEvent &Event) { return false; } + /** + * Called with all current touch finger states. + * + * @param vTouchFingerStates The touch finger states to be handled. + * + * @return `true` if the component used the touch events, `false` otherwise + */ + virtual bool OnTouchState(const std::vector &vTouchFingerStates) { return false; } }; #endif diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 1f450fa04..fd47241a9 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -403,6 +403,23 @@ void CGameClient::OnUpdate() } } + // handle touch events + const std::vector &vTouchFingerStates = Input()->TouchFingerStates(); + bool TouchHandled = false; + for(auto &pComponent : m_vpInput) + { + if(TouchHandled) + { + // Also update inactive components so they can handle touch fingers being released. + pComponent->OnTouchState({}); + } + else if(pComponent->OnTouchState(vTouchFingerStates)) + { + Input()->ClearTouchDeltas(); + TouchHandled = true; + } + } + // handle key presses Input()->ConsumeEvents([&](const IInput::CEvent &Event) { for(auto &pComponent : m_vpInput)