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.
This commit is contained in:
Robert Müller 2024-08-21 00:47:54 +02:00
parent 337d5c7ab3
commit 41ad7263eb
5 changed files with 41 additions and 4 deletions

View file

@ -300,6 +300,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();
@ -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

View file

@ -144,6 +144,7 @@ public:
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;

View file

@ -137,6 +137,12 @@ public:
* @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;

View file

@ -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<IInput::CTouchFingerState> &vTouchFingerStates) { return false; }
};
#endif

View file

@ -443,6 +443,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)