From 6fa4382bc6b45cd41b67ab3c9fbe8ad4b02fe4fe Mon Sep 17 00:00:00 2001 From: Phaneron Date: Thu, 2 Oct 2025 16:45:17 -0400 Subject: [PATCH] feat(event): implement synchronous key and mouse state tracking (#88) Co-authored-by: fallenoak --- src/event/Event.cpp | 26 +++++++++++- src/event/Queue.cpp | 98 ++++++++++++++++++++++++++++++++++++++++++++- src/event/Queue.hpp | 2 + 3 files changed, 122 insertions(+), 4 deletions(-) diff --git a/src/event/Event.cpp b/src/event/Event.cpp index 3d044e5..454f11d 100644 --- a/src/event/Event.cpp +++ b/src/event/Event.cpp @@ -53,8 +53,30 @@ int32_t EventIsControlKeyDown() { } int32_t EventIsKeyDown(KEY key) { - // TODO - return 0; + auto hContext = PropGet(PROP_EVENTCONTEXT); + auto contextId = *reinterpret_cast(hContext); + + int32_t findMask; + auto context = TSingletonInstanceId::s_idTable.Ptr( + contextId, + 0, + &findMask + ); + + if (!context) { + return 0; + } + + auto keystate = IEvtQueueCheckSyncKeyState(context, key); + + if (findMask != -1) { + TSingletonInstanceId::s_idTable.Unlock( + findMask & (INSTANCE_TABLE_SLOT_COUNT - 1), + findMask >= INSTANCE_TABLE_SLOT_COUNT + ); + } + + return keystate; } int32_t EventIsShiftKeyDown() { diff --git a/src/event/Queue.cpp b/src/event/Queue.cpp index 47734fb..7e61f10 100644 --- a/src/event/Queue.cpp +++ b/src/event/Queue.cpp @@ -3,11 +3,82 @@ #include "event/EvtHandler.hpp" #include +void UpdateSyncMouseState(EvtContext* context, MOUSEBUTTON button, int32_t down) { + if (down) { + context->m_queueSyncButtonState |= button; + } else { + context->m_queueSyncButtonState &= ~button; + } +} + +void UpdateSyncKeyState(EvtContext* context, KEY key, EVENTID& id) { + context->m_critsect.Enter(); + + int32_t keyDown = 0; + + auto list = &context->m_queueSyncKeyDownList; + + for (auto node = list->Head(); node;) { + if (node->key == key) { + keyDown = 1; + node = list->DeleteNode(node); + } else { + node = list->Next(node); + } + } + + if (id == EVENT_ID_KEYDOWN) { + if (keyDown) { + id = EVENT_ID_KEYDOWN_REPEATING; + } + + auto node = context->m_queueSyncKeyDownList.NewNode(2, 0, 0); + node->key = key; + } + + context->m_critsect.Leave(); +} + +void ResetSyncState(EvtContext* context) { + context->m_queueSyncButtonState = 0; + + context->m_critsect.Enter(); + + context->m_queueSyncKeyDownList.Clear(); + + context->m_critsect.Leave(); +} + +void UpdateSyncState(EvtContext* context, EVENTID& id, const void* data) { + STORM_VALIDATE_BEGIN; + STORM_VALIDATE(context); + STORM_VALIDATE_END_VOID; + + switch (id) { + case EVENT_ID_FOCUS: + ResetSyncState(context); + break; + + case EVENT_ID_KEYDOWN: + case EVENT_ID_KEYUP: { + auto key = reinterpret_cast(data)->key; + UpdateSyncKeyState(context, key, id); + break; + } + + case EVENT_ID_MOUSEDOWN: + case EVENT_ID_MOUSEUP: { + auto button = reinterpret_cast(data)->button; + UpdateSyncMouseState(context, button, id == EVENT_ID_MOUSEDOWN); + break; + } + } +} + void IEvtQueueDispatch(EvtContext* context, EVENTID id, const void* data) { STORM_ASSERT(context); - // TODO - // UpdateSyncState(data, &id, context, v3); + UpdateSyncState(context, id, data); // TODO // if (SErrIsDisplayingError()) { @@ -65,3 +136,26 @@ void IEvtQueueRegister(EvtContext* context, EVENTID id, int32_t (*handler)(const handlerList->LinkNode(evtHandler, 2, h); } + +int32_t IEvtQueueCheckSyncKeyState(EvtContext* context, KEY key) { + STORM_VALIDATE_BEGIN; + STORM_VALIDATE(context); + STORM_VALIDATE_END; + + context->m_critsect.Enter(); + + int32_t keystate = 0; + + auto list = &context->m_queueSyncKeyDownList; + + for (auto node = list->Head(); node; node = list->Next(node)) { + if (node->key == key) { + keystate = 1; + break; + } + } + + context->m_critsect.Leave(); + + return keystate; +} diff --git a/src/event/Queue.hpp b/src/event/Queue.hpp index f916f0c..642e9f7 100644 --- a/src/event/Queue.hpp +++ b/src/event/Queue.hpp @@ -11,4 +11,6 @@ void IEvtQueueDispatchAll(EvtContext* context); void IEvtQueueRegister(EvtContext* context, EVENTID id, int32_t (*handler)(const void*, void*), void* param, float priority); +int32_t IEvtQueueCheckSyncKeyState(EvtContext* context, KEY key); + #endif