diff --git a/src/event/Event.cpp b/src/event/Event.cpp index 6d25f25..a8573a6 100644 --- a/src/event/Event.cpp +++ b/src/event/Event.cpp @@ -53,7 +53,28 @@ int32_t EventIsControlKeyDown() { } int32_t EventIsKeyDown(KEY key) { - // TODO + auto hContext = PropGet(PROP_EVENTCONTEXT); + auto contextId = *reinterpret_cast(hContext); + int32_t findMask; + + auto context = TSingletonInstanceId::s_idTable.Ptr( + contextId, + 0, + &findMask + ); + + if (context) { + 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; + } return 0; } diff --git a/src/event/Queue.cpp b/src/event/Queue.cpp index 47734fb..03bb4db 100644 --- a/src/event/Queue.cpp +++ b/src/event/Queue.cpp @@ -3,11 +3,89 @@ #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; + auto dead = node; + node = list->Next(node); + list->UnlinkNode(dead); + list->DeleteNode(dead); + } 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(); + + EvtKeyDown* node; + + auto list = &context->m_queueSyncKeyDownList; + + while (node = list->Head()) { + list->UnlinkNode(node); + list->DeleteNode(node); + } + + context->m_critsect.Leave(); +} + +void UpdateSyncState(EvtContext* context, EVENTID& id, const void* data) { + KEY key; + MOUSEBUTTON button; + + STORM_ASSERT(context); + + switch (id) { + case EVENT_ID_FOCUS: + ResetSyncState(context); + break; + case EVENT_ID_KEYDOWN: + case EVENT_ID_KEYUP: + key = reinterpret_cast(data)->key; + UpdateSyncKeyState(context, key, id); + break; + case EVENT_ID_MOUSEDOWN: + case EVENT_ID_MOUSEUP: + 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 +143,24 @@ void IEvtQueueRegister(EvtContext* context, EVENTID id, int32_t (*handler)(const handlerList->LinkNode(evtHandler, 2, h); } + +int32_t IEvtQueueCheckSyncKeyState(EvtContext* context, KEY key) { + STORM_VALIDATE(context, ERROR_INVALID_PARAMETER, 0); + + 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