mirror of
https://github.com/isledecomp/isle.git
synced 2025-04-20 18:44:27 -04: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:
parent
2ffe227d82
commit
4a50a9ff56
9 changed files with 250 additions and 12 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,3 +4,4 @@ Release/
|
|||
ISLE.EXE
|
||||
LEGO1.DLL
|
||||
build/
|
||||
*.swp
|
||||
|
|
|
@ -135,6 +135,7 @@ add_library(lego1 SHARED
|
|||
LEGO1/mxomnicreateparam.cpp
|
||||
LEGO1/mxomnicreateparambase.cpp
|
||||
LEGO1/mxpalette.cpp
|
||||
LEGO1/mxparam.cpp
|
||||
LEGO1/mxpresenter.cpp
|
||||
LEGO1/mxscheduler.cpp
|
||||
LEGO1/mxsemaphore.cpp
|
||||
|
|
|
@ -11,6 +11,19 @@
|
|||
#define COMPAT_CONST
|
||||
#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,
|
||||
// however this keyword was added in C++11, so we define it as empty for
|
||||
// compatibility with older compilers.
|
||||
|
|
|
@ -31,8 +31,13 @@ public:
|
|||
return !strcmp(name, MxCore::ClassName());
|
||||
}
|
||||
|
||||
inline MxU32 GetId()
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
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 "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()
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ac800 STUB
|
||||
MxLong MxNotificationManager::Tickle()
|
||||
// OFFSET: LEGO1 0x100ac6c0
|
||||
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
|
||||
|
||||
#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
|
||||
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:
|
||||
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
|
||||
|
|
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 const char *ClassName() const;
|
||||
virtual MxBool IsA(const char *name) const;
|
||||
virtual void vtable14();
|
||||
virtual void vtable18();
|
||||
virtual void Register(MxCore *p_listener, int p_milliseconds);
|
||||
virtual void Unregister(MxCore *p_listener);
|
||||
virtual void vtable1c(void *v, int p);
|
||||
virtual void vtable20();
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue