Skip to content

Commit

Permalink
Support handling touch state as part of the client update
Browse files Browse the repository at this point in the history
So the touch state can be handled by gameclient components independently from their rendering, so touch inputs are not skipped when frames are.

Also store the time when touch fingers are first pressed down.
  • Loading branch information
Robyt3 committed Nov 29, 2024
1 parent 3277223 commit eb541f8
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 4 deletions.
14 changes: 10 additions & 4 deletions src/engine/client/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,14 @@ const std::vector<IInput::CTouchFingerState> &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();
Expand Down Expand Up @@ -348,10 +356,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
Expand Down Expand Up @@ -565,6 +570,7 @@ void CInput::HandleTouchDownEvent(const SDL_TouchFingerEvent &Event)
TouchFingerState.m_Finger.m_FingerId = Event.fingerId;
TouchFingerState.m_Position = vec2(Event.x, Event.y);
TouchFingerState.m_Delta = vec2(Event.dx, Event.dy);
TouchFingerState.m_PressTime = time_get_nanoseconds();
m_vTouchFingerStates.emplace_back(TouchFingerState);
}

Expand Down
1 change: 1 addition & 0 deletions src/engine/client/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ class CInput : public IEngineInput
bool NativeMousePressed(int Index) const override;

const std::vector<CTouchFingerState> &TouchFingerStates() const override;
void ClearTouchDeltas() override;

std::string GetClipboardText() override;
void SetClipboardText(const char *pText) override;
Expand Down
11 changes: 11 additions & 0 deletions src/engine/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <base/types.h>
#include <base/vmath.h>

#include <chrono>
#include <cstdint>
#include <functional>
#include <string>
Expand Down Expand Up @@ -128,6 +129,10 @@ class IInput : public IInterface
* @remark This is reset to zero at the end of each frame.
*/
vec2 m_Delta;
/**
* The time when this finger was first pressed down.
*/
std::chrono::nanoseconds m_PressTime;
};
/**
* Returns a vector of the states of all touch fingers currently being pressed down on touch devices.
Expand All @@ -137,6 +142,12 @@ class IInput : public IInterface
* @return vector of all touch finger states
*/
virtual const std::vector<CTouchFingerState> &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;
Expand Down
8 changes: 8 additions & 0 deletions src/game/client/component.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,14 @@ class CComponent
* @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<IInput::CTouchFingerState> &vTouchFingerStates) { return false; }
};

#endif
17 changes: 17 additions & 0 deletions src/game/client/gameclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,23 @@ void CGameClient::OnUpdate()
}
}

// handle touch events
const std::vector<IInput::CTouchFingerState> &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)
Expand Down

0 comments on commit eb541f8

Please sign in to comment.