feat(event): implement synchronous key and mouse state tracking (#88)

Co-authored-by: fallenoak <git@fallenoak.me>
This commit is contained in:
Phaneron 2025-10-02 16:45:17 -04:00 committed by GitHub
parent e9ef44c008
commit 6fa4382bc6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 122 additions and 4 deletions

View File

@ -53,8 +53,30 @@ int32_t EventIsControlKeyDown() {
} }
int32_t EventIsKeyDown(KEY key) { int32_t EventIsKeyDown(KEY key) {
// TODO auto hContext = PropGet(PROP_EVENTCONTEXT);
auto contextId = *reinterpret_cast<uint32_t*>(hContext);
int32_t findMask;
auto context = TSingletonInstanceId<EvtContext, offsetof(EvtContext, m_id)>::s_idTable.Ptr(
contextId,
0,
&findMask
);
if (!context) {
return 0; return 0;
}
auto keystate = IEvtQueueCheckSyncKeyState(context, key);
if (findMask != -1) {
TSingletonInstanceId<EvtContext, offsetof(EvtContext, m_id)>::s_idTable.Unlock(
findMask & (INSTANCE_TABLE_SLOT_COUNT - 1),
findMask >= INSTANCE_TABLE_SLOT_COUNT
);
}
return keystate;
} }
int32_t EventIsShiftKeyDown() { int32_t EventIsShiftKeyDown() {

View File

@ -3,11 +3,82 @@
#include "event/EvtHandler.hpp" #include "event/EvtHandler.hpp"
#include <storm/Error.hpp> #include <storm/Error.hpp>
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<const EVENT_DATA_KEY*>(data)->key;
UpdateSyncKeyState(context, key, id);
break;
}
case EVENT_ID_MOUSEDOWN:
case EVENT_ID_MOUSEUP: {
auto button = reinterpret_cast<const EVENT_DATA_MOUSE*>(data)->button;
UpdateSyncMouseState(context, button, id == EVENT_ID_MOUSEDOWN);
break;
}
}
}
void IEvtQueueDispatch(EvtContext* context, EVENTID id, const void* data) { void IEvtQueueDispatch(EvtContext* context, EVENTID id, const void* data) {
STORM_ASSERT(context); STORM_ASSERT(context);
// TODO UpdateSyncState(context, id, data);
// UpdateSyncState(data, &id, context, v3);
// TODO // TODO
// if (SErrIsDisplayingError()) { // if (SErrIsDisplayingError()) {
@ -65,3 +136,26 @@ void IEvtQueueRegister(EvtContext* context, EVENTID id, int32_t (*handler)(const
handlerList->LinkNode(evtHandler, 2, h); 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;
}

View File

@ -11,4 +11,6 @@ void IEvtQueueDispatchAll(EvtContext* context);
void IEvtQueueRegister(EvtContext* context, EVENTID id, int32_t (*handler)(const void*, void*), void* param, float priority); void IEvtQueueRegister(EvtContext* context, EVENTID id, int32_t (*handler)(const void*, void*), void* param, float priority);
int32_t IEvtQueueCheckSyncKeyState(EvtContext* context, KEY key);
#endif #endif