mirror of
https://github.com/whoahq/whoa.git
synced 2026-02-01 08:12:44 +03:00
188 lines
4.5 KiB
C++
188 lines
4.5 KiB
C++
#include "event/Queue.hpp"
|
|
#include "event/EvtContext.hpp"
|
|
#include "event/EvtHandler.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) {
|
|
STORM_ASSERT(context);
|
|
|
|
UpdateSyncState(context, id, data);
|
|
|
|
// TODO
|
|
// if (SErrIsDisplayingError()) {
|
|
// return;
|
|
// }
|
|
|
|
auto handlerList = &context->m_queueHandlerList[id];
|
|
|
|
EvtHandler marker;
|
|
marker.marker = 1;
|
|
|
|
handlerList->LinkNode(&marker, 1, nullptr);
|
|
|
|
EvtHandler* handler;
|
|
|
|
while (1) {
|
|
handler = marker.link.Next();
|
|
|
|
if (!handler) {
|
|
break;
|
|
}
|
|
|
|
handlerList->LinkNode(&marker, 1, marker.link.Next());
|
|
|
|
if (!handler->marker && !handler->func(data, handler->param)) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
handlerList->UnlinkNode(&marker);
|
|
}
|
|
|
|
void IEvtQueueDispatchAll(EvtContext* context) {
|
|
// TODO
|
|
}
|
|
|
|
void IEvtQueueRegister(EvtContext* context, EVENTID id, int32_t (*handler)(const void*, void*), void* param, float priority) {
|
|
STORM_ASSERT(context);
|
|
|
|
auto handlerList = &context->m_queueHandlerList[id];
|
|
|
|
auto m = SMemAlloc(sizeof(EvtHandler), __FILE__, __LINE__, 0x8);
|
|
auto evtHandler = new (m) EvtHandler();
|
|
|
|
evtHandler->priority = priority;
|
|
evtHandler->param = param;
|
|
evtHandler->func = handler;
|
|
evtHandler->marker = 0;
|
|
|
|
EvtHandler* h = handlerList->Head();
|
|
|
|
while (h && (priority < h->priority || h->marker)) {
|
|
h = handlerList->Link(h)->Next();
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
void IEvtQueueUnregister(EvtContext* context, EVENTID id, EVENTHANDLERFUNC handler, void* param, uint32_t flags) {
|
|
STORM_VALIDATE_BEGIN;
|
|
STORM_VALIDATE(context);
|
|
STORM_VALIDATE_END_VOID;
|
|
|
|
auto idMatch = flags & 0x1;
|
|
auto handlerMatch = flags & 0x2;
|
|
auto paramMatch = flags & 0x4;
|
|
|
|
for (uint32_t q = 0; q < EVENTIDS; q++) {
|
|
auto listMatched = (!idMatch || q == id);
|
|
|
|
if (listMatched) {
|
|
auto handlerList = &context->m_queueHandlerList[q];
|
|
|
|
for (auto node = handlerList->Head(); node; node = handlerList->Next(node)) {
|
|
auto nodeMatched = (!handlerMatch || node->func == handler) && (!paramMatch || node->param == param);
|
|
|
|
if (nodeMatched && !node->marker) {
|
|
node = handlerList->DeleteNode(node);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|