mirror of
https://github.com/isledecomp/isle.git
synced 2025-10-22 16:04:17 +00:00
MxNotificationManager and MxParam initial work. (#78)
* MxNotificationManager initial work. * Add .swp files to .gitignore. * Checkpoint before anything too crazy with param * Cleanup and add MxParam. * Checkpoint for everything except MxNotificationManager::Register. * Add int return type to MxCore::GetId instead of relying on implicit function nonsense. * Add stlcompat.h so this can still be built on modern compilers, fix affected type size asserts. * Switch to Mx types * Add BUILD_COMPAT option to CMake so the project can still be built with modern compilers. * Change vtable14 and vtable18 to Register and Unregister in MxTickleManager. * Remove last unsigned int reference to id type. * Remove MxList, use one inherited class per type. Improves accuracy again. * Address compiler compatibility code review. * Match MxNotificationManager::Register. * Re-enable MxNotificationManager DECOMP_SIZE_ASSERT.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,3 +4,4 @@ Release/
|
|||||||
ISLE.EXE
|
ISLE.EXE
|
||||||
LEGO1.DLL
|
LEGO1.DLL
|
||||||
build/
|
build/
|
||||||
|
*.swp
|
||||||
|
@@ -135,6 +135,7 @@ add_library(lego1 SHARED
|
|||||||
LEGO1/mxomnicreateparam.cpp
|
LEGO1/mxomnicreateparam.cpp
|
||||||
LEGO1/mxomnicreateparambase.cpp
|
LEGO1/mxomnicreateparambase.cpp
|
||||||
LEGO1/mxpalette.cpp
|
LEGO1/mxpalette.cpp
|
||||||
|
LEGO1/mxparam.cpp
|
||||||
LEGO1/mxpresenter.cpp
|
LEGO1/mxpresenter.cpp
|
||||||
LEGO1/mxscheduler.cpp
|
LEGO1/mxscheduler.cpp
|
||||||
LEGO1/mxsemaphore.cpp
|
LEGO1/mxsemaphore.cpp
|
||||||
|
@@ -11,6 +11,19 @@
|
|||||||
#define COMPAT_CONST
|
#define COMPAT_CONST
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MSVC420_VERSION 1020
|
||||||
|
|
||||||
|
// STL compatibility.
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER <= MSVC420_VERSION
|
||||||
|
#include <STL.H>
|
||||||
|
#else
|
||||||
|
#include <algorithm>
|
||||||
|
#include <list>
|
||||||
|
using namespace std;
|
||||||
|
template <class T>
|
||||||
|
using List = list<T>;
|
||||||
|
#endif
|
||||||
|
|
||||||
// We use `override` so newer compilers can tell us our vtables are valid,
|
// We use `override` so newer compilers can tell us our vtables are valid,
|
||||||
// however this keyword was added in C++11, so we define it as empty for
|
// however this keyword was added in C++11, so we define it as empty for
|
||||||
// compatibility with older compilers.
|
// compatibility with older compilers.
|
||||||
|
@@ -31,8 +31,13 @@ public:
|
|||||||
return !strcmp(name, MxCore::ClassName());
|
return !strcmp(name, MxCore::ClassName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline MxU32 GetId()
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int m_id;
|
MxU32 m_id;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,15 +1,143 @@
|
|||||||
|
#include "legoomni.h"
|
||||||
|
#include "mxautolocker.h"
|
||||||
|
#include "mxcore.h"
|
||||||
#include "mxnotificationmanager.h"
|
#include "mxnotificationmanager.h"
|
||||||
|
#include "mxparam.h"
|
||||||
|
#include "mxtypes.h"
|
||||||
|
|
||||||
// OFFSET: LEGO1 0x100ac450 STUB
|
#include "compat.h"
|
||||||
|
#include "decomp.h"
|
||||||
|
|
||||||
|
DECOMP_SIZE_ASSERT(MxNotification, 0x8);
|
||||||
|
DECOMP_SIZE_ASSERT(MxNotificationManager, 0x40);
|
||||||
|
|
||||||
|
// OFFSET: LEGO1 0x100ac220
|
||||||
|
MxNotification::MxNotification(MxCore *p_target, MxParam *p_param)
|
||||||
|
{
|
||||||
|
m_target = p_target;
|
||||||
|
m_param = p_param->Clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
// OFFSET: LEGO1 0x100ac240
|
||||||
|
MxNotification::~MxNotification()
|
||||||
|
{
|
||||||
|
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()
|
MxNotificationManager::~MxNotificationManager()
|
||||||
|
{
|
||||||
|
MxAutoLocker lock(&m_lock);
|
||||||
|
Tickle();
|
||||||
|
delete m_queue;
|
||||||
|
m_queue = NULL;
|
||||||
|
|
||||||
|
TickleManager()->Unregister(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// OFFSET: LEGO1 0x100ac800
|
||||||
|
MxResult MxNotificationManager::Tickle()
|
||||||
|
{
|
||||||
|
m_sendList = new MxNotificationPtrList();
|
||||||
|
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->GetTarget()->Notify(*notif->GetParam());
|
||||||
|
delete notif;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete m_sendList;
|
||||||
|
m_sendList = NULL;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OFFSET: LEGO1 0x100ac600
|
||||||
|
MxResult MxNotificationManager::Create(MxS32 p_unk1, MxS32 p_unk2)
|
||||||
|
{
|
||||||
|
MxResult result = SUCCESS;
|
||||||
|
m_queue = new MxNotificationPtrList();
|
||||||
|
|
||||||
|
if (m_queue == NULL) {
|
||||||
|
result = FAILURE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TickleManager()->Register(this, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// OFFSET: LEGO1 0x100acd20
|
||||||
|
void MxNotificationManager::Register(MxCore *p_listener)
|
||||||
|
{
|
||||||
|
MxAutoLocker lock(&m_lock);
|
||||||
|
|
||||||
|
MxIdList::iterator it = find(m_listenerIds.begin(), m_listenerIds.end(), p_listener->GetId());
|
||||||
|
if (it != m_listenerIds.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_listenerIds.push_back(p_listener->GetId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// OFFSET: LEGO1 0x100acdf0
|
||||||
|
void MxNotificationManager::Unregister(MxCore *p_listener)
|
||||||
|
{
|
||||||
|
MxAutoLocker lock(&m_lock);
|
||||||
|
|
||||||
|
MxIdList::iterator it = find(m_listenerIds.begin(), m_listenerIds.end(), p_listener->GetId());
|
||||||
|
|
||||||
|
if (it != m_listenerIds.end()) {
|
||||||
|
m_listenerIds.erase(it);
|
||||||
|
FlushPending(p_listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OFFSET: LEGO1 0x100ac990 STUB
|
||||||
|
void MxNotificationManager::FlushPending(MxCore *p_listener)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
// OFFSET: LEGO1 0x100ac800 STUB
|
// OFFSET: LEGO1 0x100ac6c0
|
||||||
MxLong MxNotificationManager::Tickle()
|
MxResult MxNotificationManager::Send(MxCore *p_listener, MxParam *p_param)
|
||||||
{
|
{
|
||||||
// TODO
|
MxAutoLocker lock(&m_lock);
|
||||||
|
|
||||||
return 0;
|
if (m_active == FALSE) {
|
||||||
}
|
return FAILURE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
MxIdList::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_param);
|
||||||
|
if (notif != NULL) {
|
||||||
|
m_queue->push_back(notif);
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
@@ -2,16 +2,62 @@
|
|||||||
#define MXNOTIFICATIONMANAGER_H
|
#define MXNOTIFICATIONMANAGER_H
|
||||||
|
|
||||||
#include "mxcore.h"
|
#include "mxcore.h"
|
||||||
|
#include "mxcriticalsection.h"
|
||||||
|
#include "mxtypes.h"
|
||||||
|
|
||||||
|
#include "compat.h"
|
||||||
|
|
||||||
|
class MxNotification
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MxNotification(MxCore *p_target, MxParam *p_param);
|
||||||
|
~MxNotification();
|
||||||
|
|
||||||
|
inline MxCore *GetTarget()
|
||||||
|
{
|
||||||
|
return m_target;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline MxParam *GetParam()
|
||||||
|
{
|
||||||
|
return m_param;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MxCore *m_target; // 0x0
|
||||||
|
MxParam *m_param; // 0x4
|
||||||
|
};
|
||||||
|
|
||||||
|
class MxIdList : public List<MxU32>
|
||||||
|
{};
|
||||||
|
|
||||||
|
class MxNotificationPtrList : public List<MxNotification *>
|
||||||
|
{};
|
||||||
|
|
||||||
// VTABLE 0x100dc078
|
// VTABLE 0x100dc078
|
||||||
class MxNotificationManager : public MxCore
|
class MxNotificationManager : public MxCore
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
MxNotificationPtrList *m_queue; // 0x8
|
||||||
|
MxNotificationPtrList *m_sendList; // 0xc
|
||||||
|
MxCriticalSection m_lock; // 0x10
|
||||||
|
MxS32 m_unk2c; // 0x2c
|
||||||
|
MxIdList m_listenerIds; // 0x30
|
||||||
|
MxBool m_active; // 0x3c
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~MxNotificationManager(); // vtable+0x0
|
MxNotificationManager();
|
||||||
|
virtual ~MxNotificationManager(); // vtable+0x0 (scalar deleting destructor)
|
||||||
|
|
||||||
virtual MxLong Tickle(); // vtable+0x8
|
virtual MxResult Tickle(); // vtable+0x8
|
||||||
|
// TODO: Where does this method come from?
|
||||||
|
virtual MxResult Create(MxS32 p_unk1, MxS32 p_unk2); // vtable+0x14
|
||||||
|
void Register(MxCore *p_listener);
|
||||||
|
void Unregister(MxCore *p_listener);
|
||||||
|
MxResult Send(MxCore *p_listener, MxParam *p_param);
|
||||||
|
|
||||||
// 0x10: MxCriticalSection
|
private:
|
||||||
|
void FlushPending(MxCore *p_listener);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MXNOTIFICATIONMANAGER_H
|
#endif // MXNOTIFICATIONMANAGER_H
|
||||||
|
11
LEGO1/mxparam.cpp
Normal file
11
LEGO1/mxparam.cpp
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#include "mxparam.h"
|
||||||
|
|
||||||
|
#include "decomp.h"
|
||||||
|
|
||||||
|
DECOMP_SIZE_ASSERT(MxParam, 0xc);
|
||||||
|
|
||||||
|
// OFFSET: LEGO1 0x10010390
|
||||||
|
MxParam* MxParam::Clone()
|
||||||
|
{
|
||||||
|
return new MxParam(m_type, m_sender);
|
||||||
|
}
|
33
LEGO1/mxparam.h
Normal file
33
LEGO1/mxparam.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef MXPARAM_H
|
||||||
|
#define MXPARAM_H
|
||||||
|
|
||||||
|
#include "mxomnicreateparambase.h"
|
||||||
|
#include "mxtypes.h"
|
||||||
|
|
||||||
|
class MxCore;
|
||||||
|
|
||||||
|
// VTABLE 0x100d56e0
|
||||||
|
class MxParam : public MxOmniCreateParamBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline MxParam(MxS32 p_type, MxCore *p_sender) : MxOmniCreateParamBase(), m_type(p_type), m_sender(p_sender){}
|
||||||
|
|
||||||
|
virtual ~MxParam(){}; // vtable+0x0 (scalar deleting destructor)
|
||||||
|
virtual MxParam *Clone(); // vtable+0x4
|
||||||
|
|
||||||
|
inline MxS32 GetType() const
|
||||||
|
{
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline MxCore *GetSender() const
|
||||||
|
{
|
||||||
|
return m_sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MxS32 m_type; // 0x4
|
||||||
|
MxCore *m_sender; // 0x8
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MXPARAM_H
|
@@ -12,8 +12,8 @@ public:
|
|||||||
virtual MxLong Tickle();
|
virtual MxLong Tickle();
|
||||||
virtual const char *ClassName() const;
|
virtual const char *ClassName() const;
|
||||||
virtual MxBool IsA(const char *name) const;
|
virtual MxBool IsA(const char *name) const;
|
||||||
virtual void vtable14();
|
virtual void Register(MxCore *p_listener, int p_milliseconds);
|
||||||
virtual void vtable18();
|
virtual void Unregister(MxCore *p_listener);
|
||||||
virtual void vtable1c(void *v, int p);
|
virtual void vtable1c(void *v, int p);
|
||||||
virtual void vtable20();
|
virtual void vtable20();
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user