From 42a4c8cc213ba86e47d2dcb2234ca12cca58c7e3 Mon Sep 17 00:00:00 2001 From: Brendan Dougherty Date: Tue, 4 Jul 2023 22:23:03 -0500 Subject: [PATCH] MxNotificationManager initial work. --- LEGO1/mxcore.h | 5 ++ LEGO1/mxnotificationmanager.cpp | 144 ++++++++++++++++++++++++++++++-- LEGO1/mxnotificationmanager.h | 37 +++++++- 3 files changed, 176 insertions(+), 10 deletions(-) diff --git a/LEGO1/mxcore.h b/LEGO1/mxcore.h index 5e6586ba..c3e944a7 100644 --- a/LEGO1/mxcore.h +++ b/LEGO1/mxcore.h @@ -30,6 +30,11 @@ class MxCore return !strcmp(name, MxCore::ClassName()); } + inline GetId() + { + return m_id; + } + private: unsigned int m_id; diff --git a/LEGO1/mxnotificationmanager.cpp b/LEGO1/mxnotificationmanager.cpp index 472c87b5..e3a8f263 100644 --- a/LEGO1/mxnotificationmanager.cpp +++ b/LEGO1/mxnotificationmanager.cpp @@ -1,15 +1,147 @@ +#include "legoomni.h" +#include "mxautolocker.h" #include "mxnotificationmanager.h" +#include "mxtypes.h" -// OFFSET: LEGO1 0x100ac450 STUB +// OFFSET: LEGO1 0x100ac220 STUB +MxNotification::MxNotification(MxCore *p_destination, void *p_vtable) +{ + m_destination = p_destination; + // TODO: Call p_vtable+0x4, assign result to m_param. + m_param = NULL; +} + +// OFFSET: LEGO1 0x100ac240 STUB +MxNotification::~MxNotification() +{ + // TODO + //delete m_param; +} + +// OFFSET: LEGO1 0x100ac250 +MxNotificationManager::MxNotificationManager() : MxCore(), m_lock(), m_listenerIds() +{ + m_unk2c = 0; + m_queue = NULL; + m_active = TRUE; + m_sendList = NULL; +} + +// OFFSET: LEGO1 0x100ac450 MxNotificationManager::~MxNotificationManager() +{ + MxAutoLocker lock(&m_lock); + Tickle(); + delete m_queue; + m_queue = NULL; + + MxTickleManager *tickleManager = TickleManager(); + // TODO + //tickleManager->Unregister(this); + tickleManager->vtable18(); +} + +// OFFSET: LEGO1 0x100ac800 +long MxNotificationManager::Tickle() +{ + m_sendList = new List(); + if (m_sendList == NULL) { + return FAILURE; + } + else { + { + MxAutoLocker lock(&m_lock); + swap(m_queue, m_sendList); + } + + while (m_sendList->size() != 0) { + MxNotification *notif = m_sendList->front(); + m_sendList->pop_front(); + notif->m_destination->Notify(*notif->m_param); + delete notif; + } + + delete m_sendList; + m_sendList = NULL; + return SUCCESS; + } +} + +// OFFSET: LEGO1 0x100ac600 +MxResult MxNotificationManager::Create(int p_unk1, int p_unk2) +{ + MxResult result = SUCCESS; + m_queue = new List(); + + if (m_queue == NULL) { + result = FAILURE; + } + else { + MxTickleManager *tickleManager = TickleManager(); + // TODO + //tickleManager->Register(this, 10); + tickleManager->vtable14(); + } + + return result; +} + +// OFFSET: LEGO1 0x100acd20 +void MxNotificationManager::Register(MxCore *p_listener) +{ + unsigned int listenerId; + List::iterator it; + MxAutoLocker lock(&m_lock); + + listenerId = p_listener->GetId(); + it = find(m_listenerIds.begin(), m_listenerIds.end(), listenerId); + if (it != m_listenerIds.end()) + return; + + m_listenerIds.push_back(listenerId); +} + +// OFFSET: LEGO1 0x100acdf0 +void MxNotificationManager::Unregister(MxCore *p_listener) +{ + MxAutoLocker lock(&m_lock); + + unsigned int listenerId = p_listener->GetId(); + List::iterator it = find(m_listenerIds.begin(), m_listenerIds.end(), listenerId); + + if (it != m_listenerIds.end()) { + m_listenerIds.erase(it); + FlushPending(p_listener); + } +} + +// OFFSET: LEGO1 0x100ac990 STUB +void MxNotificationManager::FlushPending(MxCore *p_listener) { // TODO } -// OFFSET: LEGO1 0x100ac800 STUB -MxLong MxNotificationManager::Tickle() +// OFFSET: LEGO1 0x100ac6c0 +MxResult MxNotificationManager::Send(MxCore *p_listener, void *p_vtable) { - // TODO + MxAutoLocker lock(&m_lock); - return 0; -} \ No newline at end of file + if (m_active == FALSE) { + return FAILURE; + } + else { + List::iterator it = find(m_listenerIds.begin(), m_listenerIds.end(), p_listener->GetId()); + if (it == m_listenerIds.end()) { + return FAILURE; + } + else { + MxNotification *notif = new MxNotification(p_listener, p_vtable); + if (notif != NULL) { + m_queue->push_back(notif); + return SUCCESS; + } + } + } + + return FAILURE; +} diff --git a/LEGO1/mxnotificationmanager.h b/LEGO1/mxnotificationmanager.h index 86cb4f00..89c7374d 100644 --- a/LEGO1/mxnotificationmanager.h +++ b/LEGO1/mxnotificationmanager.h @@ -1,17 +1,46 @@ #ifndef MXNOTIFICATIONMANAGER_H #define MXNOTIFICATIONMANAGER_H +#include + #include "mxcore.h" +#include "mxcriticalsection.h" +#include "mxtypes.h" + +class MxNotification +{ + public: + MxCore *m_destination; + MxParam *m_param; + + MxNotification(MxCore *p_destination, void *p_vtable); + ~MxNotification(); +}; // VTABLE 0x100dc078 class MxNotificationManager : public MxCore { -public: - virtual ~MxNotificationManager(); // vtable+0x0 + private: + List *m_queue; + List *m_sendList; + MxCriticalSection m_lock; + int m_unk2c; + List m_listenerIds; + MxBool m_active; - virtual MxLong Tickle(); // vtable+0x8 + public: + MxNotificationManager(); + virtual ~MxNotificationManager(); // vtable+0x0 - // 0x10: MxCriticalSection + virtual long Tickle(); // vtable+0x8 + // TODO: Where does this method come from? + virtual MxResult Create(int p_unk1, int p_unk2); // vtable+0x14 + void Register(MxCore *p_listener); + void Unregister(MxCore *p_listener); + MxResult Send(MxCore *p_listener, void *p_vtable); + + private: + void FlushPending(MxCore *p_listener); }; #endif // MXNOTIFICATIONMANAGER_H