mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-12-12 11:12:29 +00:00
chore: initial commit
This commit is contained in:
commit
70b00c5c38
965 changed files with 264882 additions and 0 deletions
40
src/event/CEvent.cpp
Normal file
40
src/event/CEvent.cpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#include "event/CEvent.hpp"
|
||||
#include "gx/Coordinate.hpp"
|
||||
|
||||
CCharEvent& CCharEvent::operator=(const EVENT_DATA_CHAR& data) {
|
||||
this->ch = data.ch;
|
||||
this->metaKeyState = data.metaKeyState;
|
||||
this->repeat = data.repeat;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CKeyEvent& CKeyEvent::operator=(const EVENT_DATA_KEY& data) {
|
||||
this->key = data.key;
|
||||
this->metaKeyState = data.metaKeyState;
|
||||
this->repeat = data.repeat;
|
||||
this->time = data.time;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CMouseEvent& CMouseEvent::operator=(const EVENT_DATA_MOUSE& data) {
|
||||
this->mode = data.mode;
|
||||
this->button = data.button;
|
||||
this->buttonState = data.buttonState;
|
||||
this->metaKeyState = data.metaKeyState;
|
||||
this->flags = data.flags;
|
||||
this->time = data.time;
|
||||
this->wheelDistance = data.wheelDistance;
|
||||
|
||||
NDCToDDC(data.x, data.y, &this->x, &this->y);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSizeEvent& CSizeEvent::operator=(const EVENT_DATA_SIZE& data) {
|
||||
this->w = data.w;
|
||||
this->h = data.h;
|
||||
|
||||
return *this;
|
||||
}
|
||||
39
src/event/CEvent.hpp
Normal file
39
src/event/CEvent.hpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef EVENT_C_EVENT_HPP
|
||||
#define EVENT_C_EVENT_HPP
|
||||
|
||||
#include "event/Types.hpp"
|
||||
#include <cstdint>
|
||||
#include <common/Ref.hpp>
|
||||
|
||||
class CEvent : public TRefCnt {
|
||||
public:
|
||||
// Member variables
|
||||
uint32_t id;
|
||||
void* param;
|
||||
};
|
||||
|
||||
class CCharEvent : public CEvent, public EVENT_DATA_CHAR {
|
||||
public:
|
||||
// Member functions
|
||||
CCharEvent& operator=(const EVENT_DATA_CHAR&);
|
||||
};
|
||||
|
||||
class CKeyEvent : public CEvent, public EVENT_DATA_KEY {
|
||||
public:
|
||||
// Member functions
|
||||
CKeyEvent& operator=(const EVENT_DATA_KEY&);
|
||||
};
|
||||
|
||||
class CMouseEvent : public CEvent, public EVENT_DATA_MOUSE {
|
||||
public:
|
||||
// Member functions
|
||||
CMouseEvent& operator=(const EVENT_DATA_MOUSE&);
|
||||
};
|
||||
|
||||
class CSizeEvent : public CEvent, public EVENT_DATA_SIZE {
|
||||
public:
|
||||
// Member functions
|
||||
CSizeEvent& operator=(const EVENT_DATA_SIZE&);
|
||||
};
|
||||
|
||||
#endif
|
||||
27
src/event/CMakeLists.txt
Normal file
27
src/event/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
file(GLOB PRIVATE_SOURCES "*.cpp")
|
||||
|
||||
if(WHOA_SYSTEM_MAC)
|
||||
file(GLOB MAC_SOURCES
|
||||
"mac/*.cpp"
|
||||
"mac/*.mm"
|
||||
)
|
||||
list(APPEND PRIVATE_SOURCES ${MAC_SOURCES})
|
||||
endif()
|
||||
|
||||
add_library(event STATIC
|
||||
${PRIVATE_SOURCES}
|
||||
)
|
||||
|
||||
target_include_directories(event
|
||||
PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
target_link_libraries(event
|
||||
PRIVATE
|
||||
gx
|
||||
PUBLIC
|
||||
common
|
||||
storm
|
||||
tempest
|
||||
)
|
||||
112
src/event/Context.cpp
Normal file
112
src/event/Context.cpp
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
#include "event/Context.hpp"
|
||||
#include "event/Event.hpp"
|
||||
#include "event/EvtThread.hpp"
|
||||
#include <common/Time.hpp>
|
||||
#include <storm/Atomic.hpp>
|
||||
|
||||
HEVENTCONTEXT AttachContextToThread(EvtContext* context) {
|
||||
SInterlockedIncrement(&Event::s_threadListContention);
|
||||
Event::s_threadListCritsect.Enter();
|
||||
|
||||
// Select the thread with the highest weight total
|
||||
EvtThread* thread = nullptr;
|
||||
EvtThread* t = Event::s_threadList.Head();
|
||||
|
||||
while (t) {
|
||||
if (!thread || t->m_weightTotal < thread->m_weightTotal) {
|
||||
thread = t;
|
||||
}
|
||||
|
||||
t = t->Next();
|
||||
}
|
||||
|
||||
if (thread) {
|
||||
TSingletonInstanceId<EvtContext, offsetof(EvtContext, m_id)>::s_idTable.Insert(context);
|
||||
|
||||
uint32_t v13 = OsGetAsyncTimeMs();
|
||||
|
||||
if (v13 != context->m_schedNextWakeTime.m_val) {
|
||||
context->m_schedNextWakeTime.m_val = v13;
|
||||
context->m_schedNextWakeTime.Relink();
|
||||
}
|
||||
|
||||
Event::s_threadSlotCritsects[thread->m_threadSlot].Enter();
|
||||
|
||||
thread->m_contextQueue.Enqueue(context);
|
||||
|
||||
Event::s_threadSlotCritsects[thread->m_threadSlot].Leave();
|
||||
|
||||
thread->m_wakeEvent.Set();
|
||||
|
||||
uint32_t v14 = context->m_schedWeight + thread->m_weightTotal;
|
||||
uint32_t v15 = thread->m_contextCount + 1;
|
||||
thread->m_contextCount = v15;
|
||||
thread->m_weightTotal = v14;
|
||||
thread->m_weightAvg = v14 / v15;
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
|
||||
Event::s_threadListCritsect.Leave();
|
||||
SInterlockedDecrement(&Event::s_threadListContention);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void DetachContextFromThread(uint32_t a1, EvtContext* a2) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
EvtContext* GetNextContext(uint32_t hThread) {
|
||||
EvtContext* context;
|
||||
|
||||
Event::s_threadSlotCritsects[hThread].Enter();
|
||||
|
||||
context = Event::s_threadSlots[hThread]->m_contextQueue.Dequeue();
|
||||
|
||||
Event::s_threadSlotCritsects[hThread].Leave();
|
||||
|
||||
if (hThread == Event::s_mainThread) {
|
||||
Event::s_currentEvtContext = context;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void PutContext(uint32_t nextWakeTime, uint32_t newSmoothWeight, EvtContext* context, uint32_t hThread) {
|
||||
if (nextWakeTime != context->m_schedNextWakeTime.m_val) {
|
||||
context->m_schedNextWakeTime.m_val = nextWakeTime;
|
||||
context->m_schedNextWakeTime.Relink();
|
||||
}
|
||||
|
||||
if (context->m_schedSmoothWeight != newSmoothWeight) {
|
||||
uint32_t v8 = context->m_schedWeight;
|
||||
context->m_schedSmoothWeight = newSmoothWeight;
|
||||
|
||||
int32_t v9;
|
||||
|
||||
if (newSmoothWeight <= v8) {
|
||||
v9 = v8 - newSmoothWeight;
|
||||
} else {
|
||||
v9 = newSmoothWeight - v8;
|
||||
}
|
||||
|
||||
context->m_schedRebalance = v9 >= v8 >> 3;
|
||||
}
|
||||
|
||||
if (!SInterlockedIncrement(&Event::s_threadListContention)) {
|
||||
Event::s_threadListCritsect.Enter();
|
||||
|
||||
// TODO
|
||||
|
||||
Event::s_threadListCritsect.Leave();
|
||||
}
|
||||
|
||||
SInterlockedDecrement(&Event::s_threadListContention);
|
||||
|
||||
if (hThread < Event::s_threadSlotCount) {
|
||||
Event::s_threadSlotCritsects[hThread].Enter();
|
||||
Event::s_threadSlots[hThread]->m_contextQueue.Enqueue(context);
|
||||
Event::s_threadSlotCritsects[hThread].Leave();
|
||||
}
|
||||
}
|
||||
17
src/event/Context.hpp
Normal file
17
src/event/Context.hpp
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef EVENT_CONTEXT_HPP
|
||||
#define EVENT_CONTEXT_HPP
|
||||
|
||||
#include "event/Types.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class EvtContext;
|
||||
|
||||
HEVENTCONTEXT AttachContextToThread(EvtContext* context);
|
||||
|
||||
void DetachContextFromThread(uint32_t a1, EvtContext* a2);
|
||||
|
||||
EvtContext* GetNextContext(uint32_t hThread);
|
||||
|
||||
void PutContext(uint32_t nextWakeTime, uint32_t newSmoothWeight, EvtContext* context, uint32_t hThread);
|
||||
|
||||
#endif
|
||||
136
src/event/Event.cpp
Normal file
136
src/event/Event.cpp
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
#include "event/Event.hpp"
|
||||
#include "event/EvtContext.hpp"
|
||||
#include "event/EvtThread.hpp"
|
||||
#include "event/Input.hpp"
|
||||
#include "event/Queue.hpp"
|
||||
#include "event/Scheduler.hpp"
|
||||
#include <cstring>
|
||||
#include <common/Prop.hpp>
|
||||
#include <common/Time.hpp>
|
||||
#include <storm/String.hpp>
|
||||
|
||||
SEvent Event::s_startEvent = SEvent(1, 0);
|
||||
SEvent Event::s_shutdownEvent = SEvent(1, 0);
|
||||
int32_t Event::s_netServer;
|
||||
int32_t Event::s_threadSlotCount;
|
||||
SCritSect* Event::s_threadSlotCritsects;
|
||||
EvtThread** Event::s_threadSlots;
|
||||
uint32_t Event::s_mainThread;
|
||||
TSGrowableArray<SThread*> Event::s_schedulerThreads;
|
||||
ATOMIC32 Event::s_threadListContention { -1 };
|
||||
SCritSect Event::s_threadListCritsect;
|
||||
TSList<EvtThread, TSGetLink<EvtThread>> Event::s_threadList;
|
||||
EvtContext* Event::s_currentEvtContext;
|
||||
ATOMIC32 Event::s_interactiveCount;
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
bool Event::s_shouldLoopTerminate;
|
||||
#endif
|
||||
|
||||
void OsNetPump(uint32_t timeout) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void EventInitialize(int32_t threadCount, int32_t netServer) {
|
||||
IEvtInputInitialize();
|
||||
|
||||
int32_t v2 = threadCount;
|
||||
|
||||
if (threadCount < 1) {
|
||||
v2 = 1;
|
||||
}
|
||||
|
||||
IEvtSchedulerInitialize(v2, netServer);
|
||||
|
||||
// TODO
|
||||
// OsInputSetEventPollProc(&sub_47DCA0);
|
||||
}
|
||||
|
||||
int32_t EventIsControlKeyDown() {
|
||||
return EventIsKeyDown(KEY_LCONTROL) || EventIsKeyDown(KEY_RCONTROL);
|
||||
}
|
||||
|
||||
int32_t EventIsKeyDown(KEY key) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t EventIsShiftKeyDown() {
|
||||
return EventIsKeyDown(KEY_LSHIFT) || EventIsKeyDown(KEY_RSHIFT);
|
||||
}
|
||||
|
||||
HEVENTCONTEXT EventCreateContextEx(int32_t interactive, int32_t (*initializeHandler)(const void*, void*), int32_t (*destroyHandler)(const void*, void*), uint32_t idleTime, uint32_t debugFlags) {
|
||||
return IEvtSchedulerCreateContext(interactive, initializeHandler, destroyHandler, idleTime, debugFlags);
|
||||
}
|
||||
|
||||
void EventDoMessageLoop() {
|
||||
IEvtSchedulerProcess();
|
||||
}
|
||||
|
||||
void EventPostCloseEx(HEVENTCONTEXT contextHandle) {
|
||||
if (!contextHandle) {
|
||||
contextHandle = PropGet(PROP_EVENTCONTEXT);
|
||||
}
|
||||
|
||||
if (contextHandle) {
|
||||
uint32_t contextId = *reinterpret_cast<uint32_t*>(contextHandle);
|
||||
int32_t findMask;
|
||||
EvtContext* context = TSingletonInstanceId<EvtContext, offsetof(EvtContext, m_id)>::s_idTable.Ptr(
|
||||
contextId,
|
||||
0,
|
||||
&findMask
|
||||
);
|
||||
|
||||
if (context) {
|
||||
context->m_critsect.Enter();
|
||||
|
||||
if (context->m_schedState == EvtContext::SCHEDSTATE_ACTIVE) {
|
||||
context->m_schedState = EvtContext::SCHEDSTATE_CLOSED;
|
||||
}
|
||||
|
||||
context->m_critsect.Leave();
|
||||
|
||||
if (findMask != -1) {
|
||||
TSingletonInstanceId<EvtContext, offsetof(EvtContext, m_id)>::s_idTable.Unlock(
|
||||
findMask & (INSTANCE_TABLE_SLOT_COUNT - 1),
|
||||
findMask >= INSTANCE_TABLE_SLOT_COUNT
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EventRegister(EVENTID id, EVENTHANDLERFUNC handler) {
|
||||
EventRegisterEx(id, handler, nullptr, 0.0f);
|
||||
}
|
||||
|
||||
void EventRegisterEx(EVENTID id, EVENTHANDLERFUNC handler, void* param, float priority) {
|
||||
if (id < 0 || id > EVENTIDS || handler == nullptr) {
|
||||
// TODO
|
||||
// SErrSetLastError(0x57u);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
HEVENTCONTEXT hContext = PropGet(PROP_EVENTCONTEXT);
|
||||
|
||||
uint32_t contextId = *reinterpret_cast<uint32_t*>(hContext);
|
||||
int32_t findMask;
|
||||
|
||||
EvtContext* context = TSingletonInstanceId<EvtContext, offsetof(EvtContext, m_id)>::s_idTable.Ptr(
|
||||
contextId,
|
||||
0,
|
||||
&findMask
|
||||
);
|
||||
|
||||
if (context) {
|
||||
IEvtQueueRegister(context, id, handler, param, priority);
|
||||
|
||||
if (findMask != -1) {
|
||||
TSingletonInstanceId<EvtContext, offsetof(EvtContext, m_id)>::s_idTable.Unlock(
|
||||
findMask & (INSTANCE_TABLE_SLOT_COUNT - 1),
|
||||
findMask >= INSTANCE_TABLE_SLOT_COUNT
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
56
src/event/Event.hpp
Normal file
56
src/event/Event.hpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef EVENT_EVENT_HPP
|
||||
#define EVENT_EVENT_HPP
|
||||
|
||||
#include "event/CEvent.hpp"
|
||||
#include "event/Types.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/Array.hpp>
|
||||
#include <storm/Atomic.hpp>
|
||||
#include <storm/List.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
class EvtContext;
|
||||
class EvtThread;
|
||||
|
||||
namespace Event {
|
||||
extern SEvent s_startEvent;
|
||||
extern SEvent s_shutdownEvent;
|
||||
extern int32_t s_netServer;
|
||||
extern int32_t s_originalThreadPriority;
|
||||
extern int32_t s_threadSlotCount;
|
||||
extern SCritSect* s_threadSlotCritsects;
|
||||
extern EvtThread** s_threadSlots;
|
||||
extern uint32_t s_mainThread;
|
||||
extern TSGrowableArray<SThread*> s_schedulerThreads;
|
||||
extern ATOMIC32 s_threadListContention;
|
||||
extern SCritSect s_threadListCritsect;
|
||||
extern TSList<EvtThread, TSGetLink<EvtThread>> s_threadList;
|
||||
extern EvtContext* s_currentEvtContext;
|
||||
extern ATOMIC32 s_interactiveCount;
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
extern bool s_shouldLoopTerminate;
|
||||
#endif
|
||||
}
|
||||
|
||||
HEVENTCONTEXT EventCreateContextEx(int32_t interactive, int32_t (*initializeHandler)(const void*, void*), int32_t (*destroyHandler)(const void*, void*), uint32_t idleTime, uint32_t debugFlags);
|
||||
|
||||
void EventDoMessageLoop();
|
||||
|
||||
void EventInitialize(int32_t threadCount, int32_t netServer);
|
||||
|
||||
int32_t EventIsControlKeyDown();
|
||||
|
||||
int32_t EventIsKeyDown(KEY key);
|
||||
|
||||
int32_t EventIsShiftKeyDown();
|
||||
|
||||
void EventPostCloseEx(HEVENTCONTEXT contextHandle);
|
||||
|
||||
void EventRegister(EVENTID id, int32_t (*handler)(const void*, void*));
|
||||
|
||||
void EventRegisterEx(EVENTID id, int32_t (*handler)(const void*, void*), void* param, float priority);
|
||||
|
||||
void OsNetPump(uint32_t timeout);
|
||||
|
||||
#endif
|
||||
30
src/event/EvtContext.cpp
Normal file
30
src/event/EvtContext.cpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#include "event/EvtContext.hpp"
|
||||
#include <common/Time.hpp>
|
||||
|
||||
EvtContext::EvtContext(uint32_t flags, uint32_t idleTime, uint32_t schedWeight, void* callContext, int32_t startWatchdog) :
|
||||
TSingletonInstanceId<EvtContext, offsetof(TInstanceId<EvtContext>, m_id)>(),
|
||||
m_critsect(),
|
||||
m_schedNextWakeTime(),
|
||||
m_queueHandlerList(),
|
||||
m_queueMessageList(),
|
||||
m_queueSyncKeyDownList()
|
||||
// TODO
|
||||
// m_timerIdTable()
|
||||
{
|
||||
this->m_currTime = 0;
|
||||
this->m_schedState = SCHEDSTATE_ACTIVE;
|
||||
this->m_schedLastIdle = OsGetAsyncTimeMs();
|
||||
this->m_schedFlags = flags;
|
||||
this->m_schedIdleTime = idleTime;
|
||||
this->m_schedInitialIdleTime = idleTime;
|
||||
this->m_schedWeight = schedWeight;
|
||||
this->m_schedSmoothWeight = schedWeight;
|
||||
this->m_schedRebalance = 0;
|
||||
this->m_queueSyncButtonState = 0;
|
||||
this->m_propContext = PropCreateContext();
|
||||
this->m_callContext = callContext;
|
||||
this->m_startWatchdog = startWatchdog;
|
||||
}
|
||||
|
||||
EvtContextQueue::EvtContextQueue() : TSPriorityQueue<EvtContext>(offsetof(EvtContext, m_schedNextWakeTime)) {
|
||||
}
|
||||
57
src/event/EvtContext.hpp
Normal file
57
src/event/EvtContext.hpp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef EVENT_EVT_CONTEXT_HPP
|
||||
#define EVENT_EVT_CONTEXT_HPP
|
||||
|
||||
#include "event/EvtHandler.hpp"
|
||||
#include "event/EvtKeyDown.hpp"
|
||||
#include "event/EvtMessage.hpp"
|
||||
#include "event/EvtTimer.hpp"
|
||||
#include "event/Types.hpp"
|
||||
#include <cstdint>
|
||||
#include <common/Instance.hpp>
|
||||
#include <common/Prop.hpp>
|
||||
#include <storm/Queue.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
class EvtContext : public TSingletonInstanceId<EvtContext, offsetof(TInstanceId<EvtContext>, m_id)> {
|
||||
public:
|
||||
// Types
|
||||
enum SCHEDSTATE {
|
||||
SCHEDSTATE_ACTIVE = 0x0,
|
||||
SCHEDSTATE_CLOSED = 0x1,
|
||||
SCHEDSTATE_DESTROYED = 0x2,
|
||||
_UNIQUE_SYMBOL_SCHEDSTATE_96 = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
// Member variables
|
||||
SCritSect m_critsect;
|
||||
uint32_t m_currTime;
|
||||
SCHEDSTATE m_schedState;
|
||||
TSTimerPriority<uint32_t> m_schedNextWakeTime;
|
||||
uint32_t m_schedLastIdle;
|
||||
uint32_t m_schedFlags;
|
||||
uint32_t m_schedIdleTime;
|
||||
uint32_t m_schedInitialIdleTime;
|
||||
uint32_t m_schedWeight;
|
||||
uint32_t m_schedSmoothWeight;
|
||||
int32_t m_schedRebalance;
|
||||
TSExplicitList<EvtHandler, offsetof(EvtHandler, link)> m_queueHandlerList[EVENTIDS];
|
||||
TSExplicitList<EvtMessage, offsetof(EvtMessage, link)> m_queueMessageList;
|
||||
uint32_t m_queueSyncButtonState;
|
||||
TSExplicitList<EvtKeyDown, offsetof(EvtKeyDown, link)> m_queueSyncKeyDownList;
|
||||
// TODO
|
||||
// EvtIdTable<EvtTimer*> m_timerIdTable;
|
||||
EvtTimerQueue m_timerQueue;
|
||||
HPROPCONTEXT m_propContext;
|
||||
void* m_callContext;
|
||||
uint32_t m_startWatchdog;
|
||||
|
||||
// Member functions
|
||||
EvtContext(uint32_t, uint32_t, uint32_t, void*, int32_t);
|
||||
};
|
||||
|
||||
class EvtContextQueue : public TSPriorityQueue<EvtContext> {
|
||||
public:
|
||||
EvtContextQueue();
|
||||
};
|
||||
|
||||
#endif
|
||||
17
src/event/EvtHandler.hpp
Normal file
17
src/event/EvtHandler.hpp
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef EVENT_EVT_HANDLER_HPP
|
||||
#define EVENT_EVT_HANDLER_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class EvtHandler {
|
||||
public:
|
||||
// Member variables
|
||||
TSLink<EvtHandler> link;
|
||||
int32_t (*func)(const void*, void*);
|
||||
void* param;
|
||||
float priority;
|
||||
int32_t marker;
|
||||
};
|
||||
|
||||
#endif
|
||||
14
src/event/EvtKeyDown.hpp
Normal file
14
src/event/EvtKeyDown.hpp
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef EVENT_EVT_KEY_DOWN_HPP
|
||||
#define EVENT_EVT_KEY_DOWN_HPP
|
||||
|
||||
#include "event/Types.hpp"
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class EvtKeyDown {
|
||||
public:
|
||||
// Member variables
|
||||
TSLink<EvtKeyDown> link;
|
||||
KEY key;
|
||||
};
|
||||
|
||||
#endif
|
||||
16
src/event/EvtMessage.hpp
Normal file
16
src/event/EvtMessage.hpp
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef EVENT_EVT_MESSAGE_HPP
|
||||
#define EVENT_EVT_MESSAGE_HPP
|
||||
|
||||
#include "event/Types.hpp"
|
||||
#include <common/Instance.hpp>
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class EvtMessage : public TExtraInstanceRecyclable<EvtMessage> {
|
||||
public:
|
||||
// Member variables
|
||||
TSLink<EvtMessage> link;
|
||||
EVENTID id;
|
||||
char data[4];
|
||||
};
|
||||
|
||||
#endif
|
||||
4
src/event/EvtThread.cpp
Normal file
4
src/event/EvtThread.cpp
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#include "event/EvtThread.hpp"
|
||||
|
||||
EvtThread::EvtThread() : TSLinkedNode<EvtThread>() {
|
||||
}
|
||||
25
src/event/EvtThread.hpp
Normal file
25
src/event/EvtThread.hpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef EVENT_EVT_THREAD_HPP
|
||||
#define EVENT_EVT_THREAD_HPP
|
||||
|
||||
#include "event/EvtContext.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/List.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
class EvtThread : public TSLinkedNode<EvtThread> {
|
||||
public:
|
||||
// Member variables
|
||||
uint32_t m_threadSlot;
|
||||
uint32_t m_threadCount;
|
||||
uint32_t m_weightTotal;
|
||||
uint32_t m_weightAvg;
|
||||
uint32_t m_contextCount;
|
||||
uint32_t m_rebalance;
|
||||
SEvent m_wakeEvent = SEvent(0, 0);
|
||||
EvtContextQueue m_contextQueue;
|
||||
|
||||
// Member functions
|
||||
EvtThread();
|
||||
};
|
||||
|
||||
#endif
|
||||
27
src/event/EvtTimer.hpp
Normal file
27
src/event/EvtTimer.hpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef EVENT_EVT_TIMER_HPP
|
||||
#define EVENT_EVT_TIMER_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <storm/Queue.hpp>
|
||||
|
||||
class EvtTimer {
|
||||
public:
|
||||
// Member variables
|
||||
uint32_t id;
|
||||
TSTimerPriority<uint32_t> targetTime;
|
||||
float timeout;
|
||||
int32_t (*handler)(const void*, void*);
|
||||
void* param;
|
||||
int32_t (*guidHandler)(const void*, uint64_t, void*);
|
||||
uint64_t guidParam;
|
||||
void* guidParam2;
|
||||
};
|
||||
|
||||
class EvtTimerQueue : public TSPriorityQueue<EvtTimer> {
|
||||
public:
|
||||
EvtTimerQueue()
|
||||
: TSPriorityQueue<EvtTimer>(offsetof(EvtTimer, targetTime))
|
||||
{};
|
||||
};
|
||||
|
||||
#endif
|
||||
686
src/event/Input.cpp
Normal file
686
src/event/Input.cpp
Normal file
|
|
@ -0,0 +1,686 @@
|
|||
#include "event/Input.hpp"
|
||||
#include "event/EvtContext.hpp"
|
||||
#include "event/Queue.hpp"
|
||||
#include "gx/Window.hpp"
|
||||
#include <common/Time.hpp>
|
||||
#include <storm/String.hpp>
|
||||
#include <storm/Unicode.hpp>
|
||||
#include <tempest/Rect.hpp>
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
#include "app/mac/MacClient.h"
|
||||
#endif
|
||||
|
||||
namespace Input {
|
||||
CRect s_boundingRect;
|
||||
int32_t s_queueHead;
|
||||
int32_t s_queueTail;
|
||||
OSEVENT s_queue[32];
|
||||
|
||||
MOUSEBUTTON s_buttonConversion[16] = {
|
||||
MOUSE_BUTTON_NONE,
|
||||
MOUSE_BUTTON_LEFT,
|
||||
MOUSE_BUTTON_RIGHT,
|
||||
MOUSE_BUTTON_MIDDLE,
|
||||
MOUSE_BUTTON_XBUTTON1,
|
||||
MOUSE_BUTTON_XBUTTON2,
|
||||
MOUSE_BUTTON_XBUTTON3,
|
||||
MOUSE_BUTTON_XBUTTON4,
|
||||
MOUSE_BUTTON_XBUTTON5,
|
||||
MOUSE_BUTTON_XBUTTON6,
|
||||
MOUSE_BUTTON_XBUTTON7,
|
||||
MOUSE_BUTTON_XBUTTON8,
|
||||
MOUSE_BUTTON_XBUTTON9,
|
||||
MOUSE_BUTTON_XBUTTON10,
|
||||
MOUSE_BUTTON_XBUTTON11,
|
||||
MOUSE_BUTTON_XBUTTON12,
|
||||
};
|
||||
}
|
||||
|
||||
int32_t Input::s_buttonDown[16];
|
||||
uint32_t Input::s_buttonState;
|
||||
C2iVector Input::s_currentMouse;
|
||||
uint32_t Input::s_mouseHoldButton;
|
||||
MOUSEMODE Input::s_mouseMode;
|
||||
int32_t Input::s_numlockState;
|
||||
int32_t Input::s_simulatedRightButtonClick;
|
||||
uint32_t Input::s_metaKeyState;
|
||||
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
int32_t Input::s_savedMouseSpeed;
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
double Input::s_savedMouseSpeed;
|
||||
#endif
|
||||
|
||||
void PostChar(EvtContext* context, int32_t ch, int32_t repeat) {
|
||||
EVENT_DATA_CHAR data;
|
||||
|
||||
data.ch = ch;
|
||||
data.metaKeyState = Input::s_metaKeyState;
|
||||
data.repeat = repeat;
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_CHAR, &data);
|
||||
}
|
||||
|
||||
void PostKeyDown(EvtContext* context, int32_t key, int32_t repeat, int32_t time) {
|
||||
if (key <= KEY_LASTMETAKEY) {
|
||||
if ((1 << key) & Input::s_metaKeyState) {
|
||||
return;
|
||||
}
|
||||
|
||||
Input::s_metaKeyState |= 1 << key;
|
||||
}
|
||||
|
||||
EVENT_DATA_KEY data;
|
||||
|
||||
data.key = static_cast<KEY>(key);
|
||||
data.metaKeyState = Input::s_metaKeyState;
|
||||
data.repeat = repeat;
|
||||
data.time = time;
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_KEYDOWN, &data);
|
||||
}
|
||||
|
||||
void PostKeyUp(EvtContext* context, int32_t key, int32_t repeat, int32_t time) {
|
||||
if (key <= KEY_LASTMETAKEY) {
|
||||
if ( !((1 << key) & Input::s_metaKeyState) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Input::s_metaKeyState &= ~(1 << key);
|
||||
}
|
||||
|
||||
EVENT_DATA_KEY data;
|
||||
|
||||
data.key = static_cast<KEY>(key);
|
||||
data.metaKeyState = Input::s_metaKeyState;
|
||||
data.repeat = repeat;
|
||||
data.time = time;
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_KEYUP, &data);
|
||||
}
|
||||
|
||||
void PostMouseDown(EvtContext* context, MOUSEBUTTON button, int32_t x, int32_t y, int32_t time) {
|
||||
Input::s_buttonState |= button;
|
||||
|
||||
EVENT_DATA_MOUSE data;
|
||||
|
||||
data.mode = Input::s_mouseMode;
|
||||
data.button = button;
|
||||
data.buttonState = Input::s_buttonState;
|
||||
data.metaKeyState = Input::s_metaKeyState;
|
||||
data.flags = GenerateMouseFlags();
|
||||
data.time = time;
|
||||
|
||||
ConvertPosition(x, y, &data.x, &data.y);
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_MOUSEDOWN, &data);
|
||||
}
|
||||
|
||||
void PostMouseMove(EvtContext* context, int32_t x, int32_t y, int32_t time) {
|
||||
EVENT_DATA_MOUSE data;
|
||||
|
||||
data.mode = Input::s_mouseMode;
|
||||
data.button = MOUSE_BUTTON_NONE;
|
||||
data.buttonState = Input::s_buttonState;
|
||||
data.metaKeyState = Input::s_metaKeyState;
|
||||
data.flags = GenerateMouseFlags();
|
||||
data.time = time;
|
||||
|
||||
ConvertPosition(x, y, &data.x, &data.y);
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_MOUSEMOVE, &data);
|
||||
}
|
||||
|
||||
void PostMouseUp(EvtContext* context, MOUSEBUTTON button, int32_t x, int32_t y, uint32_t flags, int32_t time) {
|
||||
Input::s_buttonState &= ~button;
|
||||
|
||||
EVENT_DATA_MOUSE data;
|
||||
|
||||
data.mode = Input::s_mouseMode;
|
||||
data.button = button;
|
||||
data.buttonState = Input::s_buttonState;
|
||||
data.metaKeyState = Input::s_metaKeyState;
|
||||
data.flags = flags | GenerateMouseFlags();
|
||||
data.time = time;
|
||||
|
||||
ConvertPosition(x, y, &data.x, &data.y);
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_MOUSEUP, &data);
|
||||
|
||||
CheckMouseModeState();
|
||||
}
|
||||
|
||||
void PostSize(EvtContext* context, int32_t w, int32_t h) {
|
||||
EVENT_DATA_SIZE data;
|
||||
|
||||
data.w = w;
|
||||
data.h = h;
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_SIZE, &data);
|
||||
}
|
||||
|
||||
void ProcessInput(const int32_t param[], OSINPUT id, int32_t* shutdown, EvtContext* context) {
|
||||
if (!context) {
|
||||
// TODO
|
||||
// nullsub_3();
|
||||
// SErrSetLastError(0x57u);
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case OS_INPUT_CAPTURE_CHANGED:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_CHAR:
|
||||
PostChar(
|
||||
context,
|
||||
param[0],
|
||||
param[1]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case OS_INPUT_STRING:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_IME:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_SIZE:
|
||||
PostSize(
|
||||
context,
|
||||
param[0],
|
||||
param[1]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case OS_INPUT_CLOSE:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_FOCUS:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_KEY_DOWN:
|
||||
PostKeyDown(
|
||||
context,
|
||||
param[0],
|
||||
param[1],
|
||||
param[3]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case OS_INPUT_KEY_UP:
|
||||
PostKeyUp(
|
||||
context,
|
||||
param[0],
|
||||
param[1],
|
||||
param[3]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case OS_INPUT_MOUSE_DOWN:
|
||||
PostMouseDown(
|
||||
context,
|
||||
static_cast<MOUSEBUTTON>(param[0]),
|
||||
param[1],
|
||||
param[2],
|
||||
param[3]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case OS_INPUT_MOUSE_MOVE:
|
||||
PostMouseMove(
|
||||
context,
|
||||
param[1],
|
||||
param[2],
|
||||
param[3]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case OS_INPUT_MOUSE_WHEEL:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_MOUSE_MOVE_RELATIVE:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_MOUSE_UP:
|
||||
PostMouseUp(
|
||||
context,
|
||||
static_cast<MOUSEBUTTON>(param[0]),
|
||||
param[1],
|
||||
param[2],
|
||||
0,
|
||||
param[3]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case OS_INPUT_14:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_15:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_16:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_17:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_18:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case OS_INPUT_SHUTDOWN:
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckMouseModeState() {
|
||||
if (Input::s_mouseHoldButton) {
|
||||
if (Input::s_mouseHoldButton != (Input::s_mouseHoldButton & Input::s_buttonState)) {
|
||||
// TODO
|
||||
// EventSetMouseMode(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MOUSEBUTTON ConvertButtonNumberToMOUSEBUTTON(int32_t buttonNumber) {
|
||||
return Input::s_buttonConversion[buttonNumber];
|
||||
}
|
||||
|
||||
void ConvertPosition(int32_t clientx, int32_t clienty, float* x, float* y) {
|
||||
if (Input::s_boundingRect.maxX - Input::s_boundingRect.minX != 0.0 && Input::s_boundingRect.maxY - Input::s_boundingRect.minY != 0.0) {
|
||||
C2Vector pt = {
|
||||
static_cast<float>(clientx),
|
||||
static_cast<float>(clienty)
|
||||
};
|
||||
|
||||
if (!Input::s_boundingRect.IsPointInside(pt)) {
|
||||
// TODO
|
||||
// - handle out of bounds positions
|
||||
}
|
||||
}
|
||||
|
||||
tagRECT windowDim;
|
||||
OsGetDefaultWindowRect(&windowDim);
|
||||
|
||||
*x = static_cast<float>(clientx) / static_cast<float>(windowDim.right - windowDim.left);
|
||||
*y = 1.0 - (static_cast<float>(clienty) / static_cast<float>(windowDim.bottom - windowDim.top));
|
||||
}
|
||||
|
||||
uint32_t GenerateMouseFlags() {
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (Input::s_mouseMode == MOUSE_MODE_RELATIVE) {
|
||||
flags |= 0x2;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
const char* GetButtonName(int32_t button) {
|
||||
switch (button) {
|
||||
case 0x1:
|
||||
return "LeftButton";
|
||||
case 0x2:
|
||||
return "MiddleButton";
|
||||
case 0x4:
|
||||
return "RightButton";
|
||||
case 0x8:
|
||||
return "Button4";
|
||||
case 0x10:
|
||||
return "Button5";
|
||||
case 0x20:
|
||||
return "Button6";
|
||||
case 0x40:
|
||||
return "Button7";
|
||||
case 0x80:
|
||||
return "Button8";
|
||||
case 0x100:
|
||||
return "Button9";
|
||||
case 0x200:
|
||||
return "Button10";
|
||||
case 0x400:
|
||||
return "Button11";
|
||||
case 0x800:
|
||||
return "Button12";
|
||||
case 0x1000:
|
||||
return "Button13";
|
||||
case 0x2000:
|
||||
return "Button14";
|
||||
case 0x4000:
|
||||
return "Button15";
|
||||
case 0x8000:
|
||||
return "Button16";
|
||||
case 0x10000:
|
||||
return "Button17";
|
||||
case 0x20000:
|
||||
return "Button18";
|
||||
case 0x40000:
|
||||
return "Button19";
|
||||
case 0x80000:
|
||||
return "Button20";
|
||||
case 0x100000:
|
||||
return "Button21";
|
||||
case 0x200000:
|
||||
return "Button22";
|
||||
case 0x400000:
|
||||
return "Button23";
|
||||
case 0x800000:
|
||||
return "Button24";
|
||||
case 0x1000000:
|
||||
return "Button25";
|
||||
case 0x2000000:
|
||||
return "Button26";
|
||||
case 0x4000000:
|
||||
return "Button27";
|
||||
case 0x8000000:
|
||||
return "Button28";
|
||||
case 0x10000000:
|
||||
return "Button29";
|
||||
case 0x20000000:
|
||||
return "Button30";
|
||||
case 0x40000000:
|
||||
return "Button31";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
void IEvtInputInitialize() {
|
||||
OsInputInitialize();
|
||||
}
|
||||
|
||||
int32_t IEvtInputProcess(EvtContext* context, int32_t* shutdown) {
|
||||
if (context) {
|
||||
// TODO
|
||||
// nullsub_3();
|
||||
|
||||
int32_t v4 = 0;
|
||||
OSINPUT id;
|
||||
int32_t param[4];
|
||||
|
||||
while (OsInputGet(&id, ¶m[0], ¶m[1], ¶m[2], ¶m[3])) {
|
||||
v4 = 1;
|
||||
ProcessInput(param, id, shutdown, context);
|
||||
}
|
||||
|
||||
return v4;
|
||||
} else {
|
||||
// TODO
|
||||
// nullsub_3();
|
||||
// SErrSetLastError(0x57u);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char* KeyCodeToString(KEY key) {
|
||||
static char charBuf[8];
|
||||
|
||||
if (key - 33 <= 222) {
|
||||
SUniSPutUTF8(key, charBuf);
|
||||
return charBuf;
|
||||
}
|
||||
|
||||
if (key <= KEY_SPACE) {
|
||||
switch (key) {
|
||||
case KEY_NONE:
|
||||
return "NONE";
|
||||
case KEY_LSHIFT:
|
||||
return "LSHIFT";
|
||||
case KEY_RSHIFT:
|
||||
return "RSHIFT";
|
||||
case KEY_LCONTROL:
|
||||
return "LCTRL";
|
||||
case KEY_RCONTROL:
|
||||
return "RCTRL";
|
||||
case KEY_LALT:
|
||||
return "LALT";
|
||||
case KEY_RALT:
|
||||
return "RALT";
|
||||
case KEY_SPACE:
|
||||
return "SPACE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
if (key <= KEY_ESCAPE) {
|
||||
switch (key) {
|
||||
case KEY_NUMPAD0:
|
||||
case KEY_NUMPAD1:
|
||||
case KEY_NUMPAD2:
|
||||
case KEY_NUMPAD3:
|
||||
case KEY_NUMPAD4:
|
||||
case KEY_NUMPAD5:
|
||||
case KEY_NUMPAD6:
|
||||
case KEY_NUMPAD7:
|
||||
case KEY_NUMPAD8:
|
||||
case KEY_NUMPAD9:
|
||||
SStrPrintf(charBuf, sizeof(charBuf), "NUMPAD%d", key);
|
||||
return charBuf;
|
||||
case KEY_NUMPAD_PLUS:
|
||||
return "NUMPADPLUS";
|
||||
case KEY_NUMPAD_MINUS:
|
||||
return "NUMPADMINUS";
|
||||
case KEY_NUMPAD_MULTIPLY:
|
||||
return "NUMPADMULTIPLY";
|
||||
case KEY_NUMPAD_DIVIDE:
|
||||
return "NUMPADDIVIDE";
|
||||
case KEY_NUMPAD_DECIMAL:
|
||||
return "NUMPADDECIMAL";
|
||||
case KEY_ESCAPE:
|
||||
return "ESCAPE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
if (key <= KEY_PRINTSCREEN) {
|
||||
switch (key) {
|
||||
case KEY_ENTER:
|
||||
return "ENTER";
|
||||
case KEY_BACKSPACE:
|
||||
return "BACKSPACE";
|
||||
case KEY_TAB:
|
||||
return "TAB";
|
||||
case KEY_LEFT:
|
||||
return "LEFT";
|
||||
case KEY_UP:
|
||||
return "UP";
|
||||
case KEY_RIGHT:
|
||||
return "RIGHT";
|
||||
case KEY_DOWN:
|
||||
return "DOWN";
|
||||
case KEY_INSERT:
|
||||
return "INSERT";
|
||||
case KEY_DELETE:
|
||||
return "DELETE";
|
||||
case KEY_HOME:
|
||||
return "HOME";
|
||||
case KEY_END:
|
||||
return "END";
|
||||
case KEY_PAGEUP:
|
||||
return "PAGEUP";
|
||||
case KEY_PAGEDOWN:
|
||||
return "PAGEDOWN";
|
||||
case KEY_CAPSLOCK:
|
||||
return "CAPSLOCK";
|
||||
case KEY_NUMLOCK:
|
||||
return "NUMLOCK";
|
||||
case KEY_PRINTSCREEN:
|
||||
return "PRINTSCREEN";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
if (key <= KEY_F12) {
|
||||
switch (key) {
|
||||
case KEY_F1:
|
||||
case KEY_F2:
|
||||
case KEY_F3:
|
||||
case KEY_F4:
|
||||
case KEY_F5:
|
||||
case KEY_F6:
|
||||
case KEY_F7:
|
||||
case KEY_F8:
|
||||
case KEY_F9:
|
||||
case KEY_F10:
|
||||
case KEY_F11:
|
||||
case KEY_F12:
|
||||
SStrPrintf(charBuf, sizeof(charBuf), "F%d", key - KEY_F1 + 1);
|
||||
return charBuf;
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
if (key == KEY_NUMPAD_EQUALS) {
|
||||
return "NUMPADEQUALS";
|
||||
}
|
||||
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
int32_t OsInputGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3) {
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
// TODO
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
// TODO
|
||||
// Unknown logic
|
||||
|
||||
if (!OsInputIsUsingCocoaEventLoop()) {
|
||||
// Legacy Carbon input handling
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// Steelseries WoW Mouse logic
|
||||
|
||||
if (Input::s_queueTail == Input::s_queueHead) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
OsQueueSetParam(3, OsGetAsyncTimeMs());
|
||||
|
||||
return OsQueueGet(id, param0, param1, param2, param3);
|
||||
#endif
|
||||
}
|
||||
|
||||
void OsInputInitialize() {
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
Input::s_numlockState = GetAsyncKeyState(144);
|
||||
PVOID pvParam = 10;
|
||||
SystemParametersInfoA(SPI_GETMOUSESPEED, 0, &pvParam, 0);
|
||||
Input::s_savedMouseSpeed = pvParam;
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
// Legacy Carbon input handling
|
||||
// if (!byte_143EFE0) {
|
||||
// Carbon_OsInputRegisterHICommandHandler(0x71756974, sub_A4F230);
|
||||
// }
|
||||
|
||||
MacClient::SetMouseCoalescingEnabled(true);
|
||||
Input::s_savedMouseSpeed = MacClient::GetMouseSpeed();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool OsInputIsUsingCocoaEventLoop() {
|
||||
// TODO
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OsInputPostEvent(OSINPUT id, int32_t param0, int32_t param1, int32_t param2, int32_t param3) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
int32_t OsQueueGet(OSINPUT* id, int32_t* param0, int32_t* param1, int32_t* param2, int32_t* param3) {
|
||||
if (Input::s_queueTail == Input::s_queueHead) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
OSEVENT event = Input::s_queue[Input::s_queueTail];
|
||||
|
||||
*id = event.id;
|
||||
*param0 = event.param[0];
|
||||
*param1 = event.param[1];
|
||||
*param2 = event.param[2];
|
||||
*param3 = event.param[3];
|
||||
|
||||
if (Input::s_queueTail == OS_QUEUE_SIZE - 1) {
|
||||
Input:: s_queueTail = 0;
|
||||
} else {
|
||||
++Input::s_queueTail;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void OsQueuePut(OSINPUT id, int32_t param0, int32_t param1, int32_t param2, int32_t param3) {
|
||||
int32_t nextTail = 0;
|
||||
int32_t nextHead = 0;
|
||||
|
||||
if (Input::s_queueHead != OS_QUEUE_SIZE - 1) {
|
||||
nextHead = Input::s_queueHead + 1;
|
||||
}
|
||||
|
||||
if (nextHead == Input::s_queueTail) {
|
||||
if (nextHead != OS_QUEUE_SIZE - 1) {
|
||||
nextTail = nextHead + 1;
|
||||
}
|
||||
|
||||
Input::s_queueTail = nextTail;
|
||||
}
|
||||
|
||||
OSEVENT* event = &Input::s_queue[Input::s_queueHead];
|
||||
|
||||
event->id = id;
|
||||
event->param[0] = param0;
|
||||
event->param[1] = param1;
|
||||
event->param[2] = param2;
|
||||
event->param[3] = param3;
|
||||
|
||||
Input::s_queueHead = nextHead;
|
||||
}
|
||||
|
||||
void OsQueueSetParam(int32_t index, int32_t param) {
|
||||
int32_t pos = Input::s_queueTail;
|
||||
|
||||
while (pos != Input::s_queueHead) {
|
||||
OSEVENT* event = &Input::s_queue[pos];
|
||||
event->param[index] = param;
|
||||
|
||||
if (pos == OS_QUEUE_SIZE - 1) {
|
||||
pos = 0;
|
||||
} else {
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
62
src/event/Input.hpp
Normal file
62
src/event/Input.hpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#ifndef EVENT_INPUT_HPP
|
||||
#define EVENT_INPUT_HPP
|
||||
|
||||
#include "event/Types.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
#define OS_QUEUE_SIZE 32
|
||||
|
||||
class C2iVector;
|
||||
class CRect;
|
||||
class EvtContext;
|
||||
|
||||
namespace Input {
|
||||
extern int32_t s_buttonDown[16];
|
||||
extern uint32_t s_buttonState;
|
||||
extern C2iVector s_currentMouse;
|
||||
extern uint32_t s_mouseHoldButton;
|
||||
extern MOUSEMODE s_mouseMode;
|
||||
extern int32_t s_numlockState;
|
||||
extern int32_t s_simulatedRightButtonClick;
|
||||
extern uint32_t s_metaKeyState;
|
||||
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
extern int32_t s_savedMouseSpeed;
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
extern double s_savedMouseSpeed;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CheckMouseModeState(void);
|
||||
|
||||
MOUSEBUTTON ConvertButtonNumberToMOUSEBUTTON(int32_t);
|
||||
|
||||
void ConvertPosition(int32_t, int32_t, float*, float*);
|
||||
|
||||
uint32_t GenerateMouseFlags(void);
|
||||
|
||||
const char* GetButtonName(int32_t);
|
||||
|
||||
void IEvtInputInitialize();
|
||||
|
||||
int32_t IEvtInputProcess(EvtContext* context, int32_t* shutdown);
|
||||
|
||||
const char* KeyCodeToString(KEY);
|
||||
|
||||
int32_t OsInputGet(OSINPUT*, int32_t*, int32_t*, int32_t*, int32_t*);
|
||||
|
||||
void OsInputInitialize(void);
|
||||
|
||||
bool OsInputIsUsingCocoaEventLoop(void);
|
||||
|
||||
void OsInputPostEvent(OSINPUT, int32_t, int32_t, int32_t, int32_t);
|
||||
|
||||
int32_t OsQueueGet(OSINPUT*, int32_t*, int32_t*, int32_t*, int32_t*);
|
||||
|
||||
void OsQueuePut(OSINPUT, int32_t, int32_t, int32_t, int32_t);
|
||||
|
||||
void OsQueueSetParam(int32_t, int32_t);
|
||||
|
||||
#endif
|
||||
74
src/event/Queue.cpp
Normal file
74
src/event/Queue.cpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#include "event/Queue.hpp"
|
||||
#include "event/EvtContext.hpp"
|
||||
#include "event/EvtHandler.hpp"
|
||||
#include <storm/Error.hpp>
|
||||
|
||||
void IEvtQueueDispatch(EvtContext* context, EVENTID id, const void* data) {
|
||||
STORM_ASSERT(context);
|
||||
|
||||
// TODO
|
||||
// UpdateSyncState(data, &id, context, v3);
|
||||
|
||||
// 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];
|
||||
|
||||
EvtHandler* evtHandler;
|
||||
|
||||
void* m = SMemAlloc(sizeof(EvtHandler), __FILE__, __LINE__, 0x8);
|
||||
|
||||
if (m) {
|
||||
evtHandler = new (m) EvtHandler();
|
||||
} else {
|
||||
evtHandler = nullptr;
|
||||
}
|
||||
|
||||
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, 1, h);
|
||||
}
|
||||
14
src/event/Queue.hpp
Normal file
14
src/event/Queue.hpp
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef EVENT_QUEUE_HPP
|
||||
#define EVENT_QUEUE_HPP
|
||||
|
||||
#include "event/Types.hpp"
|
||||
|
||||
class EvtContext;
|
||||
|
||||
void IEvtQueueDispatch(EvtContext* context, EVENTID id, const void* data);
|
||||
|
||||
void IEvtQueueDispatchAll(EvtContext* context);
|
||||
|
||||
void IEvtQueueRegister(EvtContext* context, EVENTID id, int32_t (*handler)(const void*, void*), void* param, float priority);
|
||||
|
||||
#endif
|
||||
382
src/event/Scheduler.cpp
Normal file
382
src/event/Scheduler.cpp
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
#include "event/Scheduler.hpp"
|
||||
#include "event/Context.hpp"
|
||||
#include "event/Event.hpp"
|
||||
#include "event/EvtContext.hpp"
|
||||
#include "event/EvtThread.hpp"
|
||||
#include "event/Input.hpp"
|
||||
#include "event/Queue.hpp"
|
||||
#include "event/Synthesize.hpp"
|
||||
#include "event/Timer.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <common/Call.hpp>
|
||||
#include <common/Prop.hpp>
|
||||
#include <common/Time.hpp>
|
||||
#include <storm/Memory.hpp>
|
||||
#include <storm/String.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
#include "event/mac/Event.h"
|
||||
#endif
|
||||
|
||||
void DestroySchedulerThread(uint32_t a1) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
HEVENTCONTEXT IEvtSchedulerCreateContext(int32_t interactive, int32_t (*initializeHandler)(const void*, void*), int32_t (*destroyHandler)(const void*, void*), uint32_t idleTime, uint32_t debugFlags) {
|
||||
if (idleTime < 1) {
|
||||
idleTime = 1;
|
||||
}
|
||||
|
||||
char contextName[256];
|
||||
void* callContext = nullptr;
|
||||
|
||||
if (debugFlags & 0x1) {
|
||||
SStrPrintf(contextName, 256, "Context: interactive = %u, idleTime = %u", interactive, idleTime);
|
||||
callContext = OsCallInitializeContext(contextName);
|
||||
}
|
||||
|
||||
void* m = SMemAlloc(sizeof(EvtContext), __FILE__, __LINE__, 0);
|
||||
|
||||
EvtContext* context;
|
||||
|
||||
if (m) {
|
||||
context = new (m) EvtContext(
|
||||
interactive != 0 ? 2 : 0,
|
||||
idleTime,
|
||||
interactive != 0 ? 1000 : 1,
|
||||
callContext,
|
||||
(debugFlags >> 1) & 1
|
||||
);
|
||||
} else {
|
||||
context = nullptr;
|
||||
}
|
||||
|
||||
if (interactive) {
|
||||
SInterlockedIncrement(&Event::s_interactiveCount);
|
||||
}
|
||||
|
||||
if (initializeHandler) {
|
||||
IEvtQueueRegister(context, EVENT_ID_INITIALIZE, initializeHandler, 0, 1000.0);
|
||||
}
|
||||
|
||||
if (destroyHandler) {
|
||||
IEvtQueueRegister(context, EVENT_ID_DESTROY, destroyHandler, 0, 1000.0);
|
||||
}
|
||||
|
||||
return AttachContextToThread(context);
|
||||
}
|
||||
|
||||
void IEvtSchedulerInitialize(int32_t threadCount, int32_t netServer) {
|
||||
if (Event::s_threadSlotCount) {
|
||||
// SErrDisplayAppFatal("IEvtScheduler already initialized");
|
||||
}
|
||||
|
||||
Event::s_netServer = netServer;
|
||||
|
||||
// TODO
|
||||
// Thread::s_originalThreadPriority = SGetCurrentThreadPriority();
|
||||
|
||||
int32_t threadSlotCount = 1;
|
||||
|
||||
while (threadSlotCount < threadCount) {
|
||||
threadSlotCount *= 2;
|
||||
}
|
||||
|
||||
Event::s_threadSlotCount = threadSlotCount;
|
||||
|
||||
// Allocate SCritSects for each thread slot
|
||||
int32_t v4 = sizeof(SCritSect) * threadSlotCount;
|
||||
|
||||
void* v5 = SMemAlloc((v4 + 4), ".\\EvtSched.cpp", 791, 0);
|
||||
|
||||
if (v5) {
|
||||
Event::s_threadSlotCritsects = new (v5) SCritSect[threadSlotCount];
|
||||
} else {
|
||||
Event::s_threadSlotCritsects = nullptr;
|
||||
}
|
||||
|
||||
// Allocate EvtThread pointers for each thread slot
|
||||
Event::s_threadSlots = static_cast<EvtThread**>(SMemAlloc(sizeof(EvtThread*) * threadSlotCount, __FILE__, __LINE__, 0));
|
||||
memset(Event::s_threadSlots, 0, sizeof(EvtThread*) * threadSlotCount);
|
||||
|
||||
Event::s_startEvent.Reset();
|
||||
Event::s_shutdownEvent.Reset();
|
||||
|
||||
Event::s_mainThread = InitializeSchedulerThread();
|
||||
|
||||
for (int32_t i = 0; i < threadCount - 1; ++i) {
|
||||
void* m = SMemAlloc(sizeof(SThread), __FILE__, __LINE__, 0);
|
||||
|
||||
SThread* thread;
|
||||
|
||||
if (m) {
|
||||
thread = new (m) SThread();
|
||||
} else {
|
||||
thread = nullptr;
|
||||
}
|
||||
|
||||
Event::s_schedulerThreads.SetCount(Event::s_schedulerThreads.Count() + 1);
|
||||
|
||||
Event::s_schedulerThreads[Event::s_schedulerThreads.Count() - 1] = thread;
|
||||
|
||||
char threadName[16];
|
||||
SStrPrintf(threadName, 16, "EvtSched#%d", i);
|
||||
|
||||
if (!SThread::Create(&SchedulerThreadProc, 0, *thread, threadName, 0)) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IEvtSchedulerProcess() {
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
Event::s_startEvent.Set();
|
||||
|
||||
SchedulerThreadProc(1);
|
||||
|
||||
Event::s_mainThread = 0;
|
||||
#endif
|
||||
|
||||
#if defined(WHOA_SYSTEM_MAC)
|
||||
Event::s_startEvent.Set();
|
||||
|
||||
if (OsInputIsUsingCocoaEventLoop()) {
|
||||
PropSelectContext(0);
|
||||
|
||||
Event::s_startEvent.Wait(0xFFFFFFFF);
|
||||
|
||||
uintptr_t v0 = SGetCurrentThreadId();
|
||||
char v2[64];
|
||||
SStrPrintf(v2, 64, "Engine %x", v0);
|
||||
|
||||
OsCallInitialize(v2);
|
||||
|
||||
RunCocoaEventLoop();
|
||||
|
||||
DestroySchedulerThread(Event::s_mainThread);
|
||||
OsCallDestroy();
|
||||
|
||||
Event::s_mainThread = 0;
|
||||
} else {
|
||||
// Legacy
|
||||
// sub_890180(1);
|
||||
// dword_141B3C8 = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void IEvtSchedulerShutdown() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
uint32_t InitializeSchedulerThread() {
|
||||
SInterlockedIncrement(&Event::s_threadListContention);
|
||||
|
||||
Event::s_threadListCritsect.Enter();
|
||||
|
||||
uint32_t slot = Event::s_threadSlotCount;
|
||||
|
||||
for (int32_t i = 0; i < Event::s_threadSlotCount; ++i) {
|
||||
if (slot == Event::s_threadSlotCount
|
||||
|| Event::s_threadSlots[i] == nullptr
|
||||
|| Event::s_threadSlots[i]->m_threadCount < Event::s_threadSlots[slot]->m_threadCount)
|
||||
{
|
||||
slot = i;
|
||||
|
||||
if (!Event::s_threadSlots[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EvtThread* v4 = Event::s_threadSlots[slot];
|
||||
|
||||
if (!v4) {
|
||||
v4 = Event::s_threadList.NewNode(1, 0, 0x8);
|
||||
|
||||
v4->m_threadCount = 0;
|
||||
v4->m_weightTotal = 0;
|
||||
v4->m_weightAvg = 0;
|
||||
v4->m_contextCount = 0;
|
||||
v4->m_rebalance = 0;
|
||||
v4->m_threadSlot = slot;
|
||||
|
||||
Event::s_threadSlotCritsects[slot].Enter();
|
||||
|
||||
Event::s_threadSlots[slot] = v4;
|
||||
|
||||
Event::s_threadSlotCritsects[slot].Leave();
|
||||
}
|
||||
|
||||
++v4->m_threadCount;
|
||||
|
||||
Event::s_threadListCritsect.Leave();
|
||||
|
||||
SInterlockedDecrement(&Event::s_threadListContention);
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
bool SchedulerMainProcess() {
|
||||
return SchedulerThreadProcProcess(Event::s_mainThread) != 0;
|
||||
}
|
||||
|
||||
uint32_t SchedulerThreadProc(void* mainThread) {
|
||||
uint32_t v1;
|
||||
|
||||
if (mainThread) {
|
||||
v1 = Event::s_mainThread;
|
||||
} else {
|
||||
v1 = InitializeSchedulerThread();
|
||||
}
|
||||
|
||||
PropSelectContext(0);
|
||||
|
||||
Event::s_startEvent.Wait(0xFFFFFFFF);
|
||||
|
||||
uintptr_t v2 = SGetCurrentThreadId();
|
||||
char v4[64];
|
||||
SStrPrintf(v4, 64, "Engine %x", v2);
|
||||
|
||||
OsCallInitialize(v4);
|
||||
|
||||
while (!SchedulerThreadProcProcess(v1));
|
||||
|
||||
DestroySchedulerThread(v1);
|
||||
OsCallDestroy();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t SchedulerThreadProcProcess(uint32_t a1) {
|
||||
// TODO
|
||||
// if (SGetCurrentThreadPriority() != Event::s_originalThreadPriority) {
|
||||
// SSetCurrentThreadPriority(Event::s_originalThreadPriority);
|
||||
// }
|
||||
|
||||
if (!Event::s_shutdownEvent.Wait(0)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
EvtContext* context = GetNextContext(a1);
|
||||
|
||||
int32_t v11;
|
||||
|
||||
if (context) {
|
||||
v11 = context->m_schedNextWakeTime.m_val - OsGetAsyncTimeMs();
|
||||
|
||||
if (v11 < 0) {
|
||||
v11 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t v14;
|
||||
|
||||
if (Event::s_netServer) {
|
||||
if (v11 == -1) {
|
||||
v11 = 100;
|
||||
}
|
||||
|
||||
OsNetPump(v11);
|
||||
|
||||
v14 = 258;
|
||||
} else {
|
||||
v14 = Event::s_threadSlots[a1]->m_wakeEvent.Wait(v11);
|
||||
}
|
||||
|
||||
if (!context) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PropSelectContext(context->m_propContext);
|
||||
PropSet(PROP_EVENTCONTEXT, &context->m_id);
|
||||
OsCallSetContext(context->m_callContext);
|
||||
|
||||
uint32_t currTime = OsGetAsyncTimeMs();
|
||||
uint32_t v19 = context->m_id;
|
||||
|
||||
if (v14 == 258) {
|
||||
if (SynthesizeInitialize(context)) {
|
||||
if (context->m_startWatchdog) {
|
||||
// nullsub_5(20, 1);
|
||||
// *a2 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t v9 = (currTime - context->m_schedLastIdle);
|
||||
context->m_schedLastIdle = currTime;
|
||||
double elapsedSec = v9 * 0.001;
|
||||
|
||||
// TODO
|
||||
// FrameTime::Update(currTime, elapsedSec);
|
||||
|
||||
IEvtTimerDispatch(context);
|
||||
|
||||
if (context->m_schedFlags & 0x2) {
|
||||
int32_t shutdown = 0;
|
||||
IEvtInputProcess(context, &shutdown);
|
||||
|
||||
if (shutdown) {
|
||||
context->m_critsect.Enter();
|
||||
|
||||
if (context->m_schedState == EvtContext::SCHEDSTATE_ACTIVE) {
|
||||
context->m_schedState = EvtContext::SCHEDSTATE_CLOSED;
|
||||
}
|
||||
|
||||
context->m_critsect.Leave();
|
||||
|
||||
IEvtSchedulerShutdown();
|
||||
}
|
||||
}
|
||||
|
||||
SynthesizePoll(context);
|
||||
IEvtQueueDispatchAll(context);
|
||||
SynthesizeIdle(context, currTime, elapsedSec);
|
||||
SynthesizePaint(context);
|
||||
}
|
||||
|
||||
if (a1 == Event::s_mainThread) {
|
||||
// TODO
|
||||
// dword_B417C4 = 0;
|
||||
}
|
||||
|
||||
context->m_critsect.Enter();
|
||||
|
||||
uint32_t closed = context->m_schedState == EvtContext::SCHEDSTATE_CLOSED;
|
||||
|
||||
context->m_critsect.Leave();
|
||||
|
||||
if (closed) {
|
||||
DetachContextFromThread(a1, context);
|
||||
SynthesizeDestroy(context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t nextDelay;
|
||||
|
||||
if (context->m_schedFlags & 0x4) {
|
||||
nextDelay = 0;
|
||||
} else {
|
||||
int32_t v15 = IEvtTimerGetNextTime(context, currTime);
|
||||
int32_t v16 = context->m_schedIdleTime;
|
||||
|
||||
nextDelay = v15;
|
||||
|
||||
if (v16 != context->m_schedInitialIdleTime) {
|
||||
nextDelay = context->m_schedIdleTime;
|
||||
}
|
||||
|
||||
nextDelay = std::min(
|
||||
nextDelay,
|
||||
std::max((uint32_t)0, v16 + context->m_schedLastIdle - currTime)
|
||||
);
|
||||
}
|
||||
|
||||
OsCallResetContext(context->m_callContext);
|
||||
PropSelectContext(nullptr);
|
||||
PutContext(nextDelay + currTime, context->m_schedSmoothWeight, context, a1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
25
src/event/Scheduler.hpp
Normal file
25
src/event/Scheduler.hpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef EVENT_SCHEDULER_HPP
|
||||
#define EVENT_SCHEDULER_HPP
|
||||
|
||||
#include "event/Types.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
void DestroySchedulerThread(uint32_t a1);
|
||||
|
||||
HEVENTCONTEXT IEvtSchedulerCreateContext(int32_t interactive, int32_t (*initializeHandler)(const void*, void*), int32_t (*destroyHandler)(const void*, void*), uint32_t idleTime, uint32_t debugFlags);
|
||||
|
||||
void IEvtSchedulerInitialize(int32_t threadCount, int32_t netServer);
|
||||
|
||||
void IEvtSchedulerProcess();
|
||||
|
||||
void IEvtSchedulerShutdown();
|
||||
|
||||
uint32_t InitializeSchedulerThread();
|
||||
|
||||
bool SchedulerMainProcess();
|
||||
|
||||
uint32_t SchedulerThreadProc(void* mainThread);
|
||||
|
||||
int32_t SchedulerThreadProcProcess(uint32_t a1);
|
||||
|
||||
#endif
|
||||
81
src/event/Synthesize.cpp
Normal file
81
src/event/Synthesize.cpp
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#include "event/Synthesize.hpp"
|
||||
#include "event/EvtContext.hpp"
|
||||
#include "event/Queue.hpp"
|
||||
#include <common/Time.hpp>
|
||||
|
||||
void SynthesizeDestroy(EvtContext* context) {
|
||||
// TODO
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void SynthesizeIdle(EvtContext* context, uint32_t currTime, float elapsedSec) {
|
||||
bool closed;
|
||||
|
||||
context->m_critsect.Enter();
|
||||
closed = context->m_schedState == EvtContext::SCHEDSTATE_CLOSED;
|
||||
context->m_critsect.Leave();
|
||||
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t schedFlags = context->m_schedFlags;
|
||||
|
||||
if (schedFlags & 0x2) {
|
||||
context->m_schedFlags = schedFlags | 0x4;
|
||||
}
|
||||
|
||||
EVENT_DATA_IDLE data;
|
||||
data.elapsedSec = elapsedSec;
|
||||
data.time = currTime;
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_IDLE, &data);
|
||||
}
|
||||
|
||||
int32_t SynthesizeInitialize(EvtContext* context) {
|
||||
uint32_t schedFlags = context->m_schedFlags;
|
||||
|
||||
if (schedFlags & 0x1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
context->m_schedFlags = schedFlags | 0x1;
|
||||
context->m_schedLastIdle = OsGetAsyncTimeMs();
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_INITIALIZE, nullptr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void SynthesizePaint(EvtContext* context) {
|
||||
bool closed;
|
||||
|
||||
context->m_critsect.Enter();
|
||||
closed = context->m_schedState == EvtContext::SCHEDSTATE_CLOSED;
|
||||
context->m_critsect.Leave();
|
||||
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t schedFlags = context->m_schedFlags;
|
||||
|
||||
if (schedFlags & 0x4) {
|
||||
context->m_schedFlags = schedFlags & ~0x4;
|
||||
IEvtQueueDispatch(context, EVENT_ID_PAINT, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void SynthesizePoll(EvtContext* context) {
|
||||
bool closed;
|
||||
|
||||
context->m_critsect.Enter();
|
||||
closed = context->m_schedState == EvtContext::SCHEDSTATE_CLOSED;
|
||||
context->m_critsect.Leave();
|
||||
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_POLL, nullptr);
|
||||
}
|
||||
18
src/event/Synthesize.hpp
Normal file
18
src/event/Synthesize.hpp
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef EVENT_SYNTHESIZE_HPP
|
||||
#define EVENT_SYNTHESIZE_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class EvtContext;
|
||||
|
||||
void SynthesizeDestroy(EvtContext* context);
|
||||
|
||||
void SynthesizeIdle(EvtContext* context, uint32_t currTime, float elapsedSec);
|
||||
|
||||
int32_t SynthesizeInitialize(EvtContext* context);
|
||||
|
||||
void SynthesizePaint(EvtContext* context);
|
||||
|
||||
void SynthesizePoll(EvtContext* context);
|
||||
|
||||
#endif
|
||||
29
src/event/Timer.cpp
Normal file
29
src/event/Timer.cpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#include "event/Timer.hpp"
|
||||
#include "event/EvtContext.hpp"
|
||||
#include "event/EvtTimer.hpp"
|
||||
#include <storm/Error.hpp>
|
||||
|
||||
int32_t IEvtTimerDispatch(EvtContext* context) {
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t IEvtTimerGetNextTime(EvtContext* context, uint32_t currTime) {
|
||||
STORM_ASSERT(context);
|
||||
|
||||
context->m_critsect.Enter();
|
||||
|
||||
uint32_t nextTime = -1;
|
||||
|
||||
if (context->m_timerQueue.Count()) {
|
||||
auto queue = static_cast<EvtTimer*>(context->m_timerQueue[0]);
|
||||
auto targetTime = queue->targetTime.m_val;
|
||||
nextTime = targetTime - currTime;
|
||||
nextTime = nextTime < 0 ? 0 : nextTime;
|
||||
}
|
||||
|
||||
context->m_critsect.Leave();
|
||||
|
||||
return nextTime;
|
||||
}
|
||||
12
src/event/Timer.hpp
Normal file
12
src/event/Timer.hpp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef EVENT_TIMER_HPP
|
||||
#define EVENT_TIMER_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class EvtContext;
|
||||
|
||||
int32_t IEvtTimerDispatch(EvtContext* context);
|
||||
|
||||
uint32_t IEvtTimerGetNextTime(EvtContext* context, uint32_t currTime);
|
||||
|
||||
#endif
|
||||
252
src/event/Types.hpp
Normal file
252
src/event/Types.hpp
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
#ifndef EVENT_TYPES_HPP
|
||||
#define EVENT_TYPES_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
typedef void* HEVENTCONTEXT;
|
||||
typedef int32_t (*EVENTHANDLERFUNC)(const void*, void*);
|
||||
|
||||
enum EVENTID {
|
||||
EVENT_ID_0 = 0,
|
||||
EVENT_ID_CHAR = 1,
|
||||
EVENT_ID_FOCUS = 2,
|
||||
EVENT_ID_3 = 3,
|
||||
EVENT_ID_DESTROY = 4,
|
||||
EVENT_ID_5 = 5,
|
||||
EVENT_ID_IDLE = 6,
|
||||
EVENT_ID_POLL = 7,
|
||||
EVENT_ID_INITIALIZE = 8,
|
||||
EVENT_ID_KEYDOWN = 9,
|
||||
EVENT_ID_KEYUP = 10,
|
||||
EVENT_ID_KEYDOWN_REPEATING = 11,
|
||||
EVENT_ID_MOUSEDOWN = 12,
|
||||
EVENT_ID_MOUSEMOVE = 13,
|
||||
EVENT_ID_MOUSEMOVE_RELATIVE = 14,
|
||||
EVENT_ID_MOUSEUP = 15,
|
||||
EVENT_ID_MOUSEMODE_CHANGED = 16,
|
||||
EVENT_ID_MOUSEWHEEL = 17,
|
||||
EVENT_ID_18 = 18,
|
||||
EVENT_ID_19 = 19,
|
||||
EVENT_ID_20 = 20,
|
||||
EVENT_ID_21 = 21,
|
||||
EVENT_ID_22 = 22,
|
||||
EVENT_ID_PAINT = 23,
|
||||
EVENT_ID_24 = 24,
|
||||
EVENT_ID_25 = 25,
|
||||
EVENT_ID_26 = 26,
|
||||
EVENT_ID_27 = 27,
|
||||
EVENT_ID_28 = 28,
|
||||
EVENT_ID_29 = 29,
|
||||
EVENT_ID_30 = 30,
|
||||
EVENT_ID_31 = 31,
|
||||
EVENT_ID_32 = 32,
|
||||
EVENT_ID_33 = 33,
|
||||
EVENT_ID_IME = 34,
|
||||
EVENT_ID_SIZE = 35,
|
||||
EVENTIDS = 36
|
||||
};
|
||||
|
||||
enum KEY {
|
||||
KEY_NONE = 0xFFFFFFFF,
|
||||
KEY_LSHIFT = 0x0,
|
||||
KEY_RSHIFT = 0x1,
|
||||
KEY_LCONTROL = 0x2,
|
||||
KEY_RCONTROL = 0x3,
|
||||
KEY_LALT = 0x4,
|
||||
KEY_RALT = 0x5,
|
||||
KEY_LASTMETAKEY = 0x5,
|
||||
KEY_SPACE = 0x20,
|
||||
KEY_0 = 0x30,
|
||||
KEY_1 = 0x31,
|
||||
KEY_2 = 0x32,
|
||||
KEY_3 = 0x33,
|
||||
KEY_4 = 0x34,
|
||||
KEY_5 = 0x35,
|
||||
KEY_6 = 0x36,
|
||||
KEY_7 = 0x37,
|
||||
KEY_8 = 0x38,
|
||||
KEY_9 = 0x39,
|
||||
KEY_A = 0x41,
|
||||
KEY_B = 0x42,
|
||||
KEY_C = 0x43,
|
||||
KEY_D = 0x44,
|
||||
KEY_E = 0x45,
|
||||
KEY_F = 0x46,
|
||||
KEY_G = 0x47,
|
||||
KEY_H = 0x48,
|
||||
KEY_I = 0x49,
|
||||
KEY_J = 0x4A,
|
||||
KEY_K = 0x4B,
|
||||
KEY_L = 0x4C,
|
||||
KEY_M = 0x4D,
|
||||
KEY_N = 0x4E,
|
||||
KEY_O = 0x4F,
|
||||
KEY_P = 0x50,
|
||||
KEY_Q = 0x51,
|
||||
KEY_R = 0x52,
|
||||
KEY_S = 0x53,
|
||||
KEY_T = 0x54,
|
||||
KEY_U = 0x55,
|
||||
KEY_V = 0x56,
|
||||
KEY_W = 0x57,
|
||||
KEY_X = 0x58,
|
||||
KEY_Y = 0x59,
|
||||
KEY_Z = 0x5A,
|
||||
KEY_TILDE = 0x60,
|
||||
KEY_NUMPAD0 = 0x100,
|
||||
KEY_NUMPAD1 = 0x101,
|
||||
KEY_NUMPAD2 = 0x102,
|
||||
KEY_NUMPAD3 = 0x103,
|
||||
KEY_NUMPAD4 = 0x104,
|
||||
KEY_NUMPAD5 = 0x105,
|
||||
KEY_NUMPAD6 = 0x106,
|
||||
KEY_NUMPAD7 = 0x107,
|
||||
KEY_NUMPAD8 = 0x108,
|
||||
KEY_NUMPAD9 = 0x109,
|
||||
KEY_NUMPAD_PLUS = 0x10A,
|
||||
KEY_NUMPAD_MINUS = 0x10B,
|
||||
KEY_NUMPAD_MULTIPLY = 0x10C,
|
||||
KEY_NUMPAD_DIVIDE = 0x10D,
|
||||
KEY_NUMPAD_DECIMAL = 0x10E,
|
||||
KEY_NUMPAD_EQUALS = 0x30C,
|
||||
KEY_PLUS = 0x3D,
|
||||
KEY_MINUS = 0x2D,
|
||||
KEY_BRACKET_OPEN = 0x5B,
|
||||
KEY_BRACKET_CLOSE = 0x5D,
|
||||
KEY_SLASH = 0x2F,
|
||||
KEY_BACKSLASH = 0x5C,
|
||||
KEY_SEMICOLON = 0x3B,
|
||||
KEY_APOSTROPHE = 0x27,
|
||||
KEY_COMMA = 0x2C,
|
||||
KEY_PERIOD = 0x2E,
|
||||
KEY_ESCAPE = 0x200,
|
||||
KEY_ENTER = 0x201,
|
||||
KEY_BACKSPACE = 0x202,
|
||||
KEY_TAB = 0x203,
|
||||
KEY_LEFT = 0x204,
|
||||
KEY_UP = 0x205,
|
||||
KEY_RIGHT = 0x206,
|
||||
KEY_DOWN = 0x207,
|
||||
KEY_INSERT = 0x208,
|
||||
KEY_DELETE = 0x209,
|
||||
KEY_HOME = 0x20A,
|
||||
KEY_END = 0x20B,
|
||||
KEY_PAGEUP = 0x20C,
|
||||
KEY_PAGEDOWN = 0x20D,
|
||||
KEY_CAPSLOCK = 0x20E,
|
||||
KEY_NUMLOCK = 0x20F,
|
||||
KEY_SCROLLLOCK = 0x210,
|
||||
KEY_PAUSE = 0x211,
|
||||
KEY_PRINTSCREEN = 0x212,
|
||||
KEY_F1 = 0x300,
|
||||
KEY_F2 = 0x301,
|
||||
KEY_F3 = 0x302,
|
||||
KEY_F4 = 0x303,
|
||||
KEY_F5 = 0x304,
|
||||
KEY_F6 = 0x305,
|
||||
KEY_F7 = 0x306,
|
||||
KEY_F8 = 0x307,
|
||||
KEY_F9 = 0x308,
|
||||
KEY_F10 = 0x309,
|
||||
KEY_F11 = 0x30A,
|
||||
KEY_F12 = 0x30B,
|
||||
KEY_F13 = 0x212,
|
||||
KEY_F14 = 0x30D,
|
||||
KEY_F15 = 0x30E,
|
||||
KEY_F16 = 0x30F,
|
||||
KEY_F17 = 0x310,
|
||||
KEY_F18 = 0x311,
|
||||
KEY_F19 = 0x312,
|
||||
KEY_LAST = 0x313
|
||||
};
|
||||
|
||||
enum MOUSEBUTTON {
|
||||
MOUSE_BUTTON_NONE = 0x0,
|
||||
MOUSE_BUTTON_LEFT = 0x1,
|
||||
MOUSE_BUTTON_MIDDLE = 0x2,
|
||||
MOUSE_BUTTON_RIGHT = 0x4,
|
||||
MOUSE_BUTTON_XBUTTON1 = 0x8,
|
||||
MOUSE_BUTTON_XBUTTON2 = 0x10,
|
||||
MOUSE_BUTTON_XBUTTON3 = 0x20,
|
||||
MOUSE_BUTTON_XBUTTON4 = 0x40,
|
||||
MOUSE_BUTTON_XBUTTON5 = 0x80,
|
||||
MOUSE_BUTTON_XBUTTON6 = 0x100,
|
||||
MOUSE_BUTTON_XBUTTON7 = 0x200,
|
||||
MOUSE_BUTTON_XBUTTON8 = 0x400,
|
||||
MOUSE_BUTTON_XBUTTON9 = 0x800,
|
||||
MOUSE_BUTTON_XBUTTON10 = 0x1000,
|
||||
MOUSE_BUTTON_XBUTTON11 = 0x2000,
|
||||
MOUSE_BUTTON_XBUTTON12 = 0x4000,
|
||||
MOUSE_BUTTON_ALL = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
enum MOUSEMODE {
|
||||
MOUSE_MODE_NORMAL = 0x0,
|
||||
MOUSE_MODE_RELATIVE = 0x1,
|
||||
MOUSE_MODES = 0x2
|
||||
};
|
||||
|
||||
enum OSINPUT {
|
||||
OS_INPUT_CAPTURE_CHANGED = 0,
|
||||
OS_INPUT_CHAR = 1,
|
||||
OS_INPUT_STRING = 2,
|
||||
OS_INPUT_IME = 3,
|
||||
OS_INPUT_SIZE = 4,
|
||||
OS_INPUT_CLOSE = 5,
|
||||
OS_INPUT_FOCUS = 6,
|
||||
OS_INPUT_KEY_DOWN = 7,
|
||||
OS_INPUT_KEY_UP = 8,
|
||||
OS_INPUT_MOUSE_DOWN = 9,
|
||||
OS_INPUT_MOUSE_MOVE = 10,
|
||||
OS_INPUT_MOUSE_WHEEL = 11,
|
||||
OS_INPUT_MOUSE_MOVE_RELATIVE = 12,
|
||||
OS_INPUT_MOUSE_UP = 13,
|
||||
OS_INPUT_14 = 14,
|
||||
OS_INPUT_15 = 15,
|
||||
OS_INPUT_16 = 16,
|
||||
OS_INPUT_17 = 17,
|
||||
OS_INPUT_18 = 18,
|
||||
OS_INPUT_SHUTDOWN = 19
|
||||
};
|
||||
|
||||
struct OSEVENT {
|
||||
OSINPUT id;
|
||||
int32_t param[4];
|
||||
};
|
||||
|
||||
struct EVENT_DATA_CHAR {
|
||||
int32_t ch;
|
||||
uint32_t metaKeyState;
|
||||
uint32_t repeat;
|
||||
};
|
||||
|
||||
struct EVENT_DATA_IDLE {
|
||||
float elapsedSec;
|
||||
uint32_t time;
|
||||
};
|
||||
|
||||
struct EVENT_DATA_KEY {
|
||||
KEY key;
|
||||
uint32_t metaKeyState;
|
||||
uint32_t repeat;
|
||||
uint32_t time;
|
||||
};
|
||||
|
||||
struct EVENT_DATA_MOUSE {
|
||||
MOUSEMODE mode;
|
||||
MOUSEBUTTON button;
|
||||
uint32_t buttonState;
|
||||
uint32_t metaKeyState;
|
||||
uint32_t flags;
|
||||
float x;
|
||||
float y;
|
||||
int32_t wheelDistance;
|
||||
uint32_t time;
|
||||
};
|
||||
|
||||
struct EVENT_DATA_SIZE {
|
||||
int32_t w;
|
||||
int32_t h;
|
||||
};
|
||||
|
||||
#endif
|
||||
6
src/event/mac/Event.h
Normal file
6
src/event/mac/Event.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef EVENT_MAC_EVENT_H
|
||||
#define EVENT_MAC_EVENT_H
|
||||
|
||||
void RunCocoaEventLoop();
|
||||
|
||||
#endif
|
||||
9
src/event/mac/Event.mm
Normal file
9
src/event/mac/Event.mm
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#include "event/mac/Event.h"
|
||||
#include "event/Event.hpp"
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
void RunCocoaEventLoop() {
|
||||
if (!Event::s_shouldLoopTerminate) {
|
||||
[NSApp run];
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue