#ifndef MXLIST_H #define MXLIST_H #include "mxtypes.h" #include "mxcore.h" template // SIZE 0xc class MxListEntry { public: MxListEntry() {} MxListEntry(T *p_obj, MxListEntry *p_prev) { m_obj = p_obj; m_prev = p_prev; m_next = NULL; } T *m_obj; MxListEntry *m_prev; MxListEntry *m_next; }; // VTABLE 0x100d6350 // SIZE 0x10 template class MxListParent : public MxCore { public: MxListParent() { m_count = 0; m_customDestructor = Destroy; } // OFFSET: LEGO1 0x1001cdd0 virtual ~MxListParent() {} // OFFSET: LEGO1 0x1001cd30 static void Destroy(T *) {}; // OFFSET: LEGO1 0x1001cd20 virtual MxS8 Compare(T *, T *) = 0; protected: MxU32 m_count; // +0x8 void (*m_customDestructor)(T *); // +0xc }; // VTABLE 0x100d6368 // SIZE 0x18 template class MxList : protected MxListParent { public: MxList() { m_last = NULL; m_first = NULL; } virtual ~MxList(); void Append(T*); friend class MxListCursor; protected: MxListEntry *m_first; // +0x10 MxListEntry *m_last; // +0x14 }; // VTABLE 0x100d6488 template class MxListCursor : public MxCore { public: MxListCursor(MxList *p_list) { m_list = p_list; m_match = NULL; } MxBool Find(T *p_obj); void Detach(); MxBool Next(T*& p_obj); private: MxList *m_list; MxListEntry *m_match; }; // Unclear purpose // VTABLE 0x100d6530 template class MxListCursorChild : public MxListCursor { public: MxListCursorChild(MxList *p_list) : MxListCursor(p_list) {} }; // Unclear purpose // VTABLE 0x100d6470 template class MxListCursorChildChild : public MxListCursorChild { public: MxListCursorChildChild(MxList *p_list) : MxListCursorChild(p_list) {} }; template // OFFSET: LEGO1 0x1001ce20 MxList::~MxList() { for (MxListEntry *t = m_first;;) { if (!t) break; MxListEntry *next = t->m_next; m_customDestructor(t->m_obj); delete t; t = next; } m_count = 0; m_last = NULL; m_first = NULL; } template inline void MxList::Append(T *p_newobj) { MxListEntry *currentLast = this->m_last; MxListEntry *newEntry = new MxListEntry(p_newobj, currentLast); if (currentLast) currentLast->m_next = newEntry; else this->m_first = newEntry; this->m_last = newEntry; this->m_count++; } template inline MxBool MxListCursor::Find(T *p_obj) { for (m_match = m_list->m_first; m_match && m_list->Compare(m_match->m_obj, p_obj); m_match = m_match->m_next); return m_match != NULL; } template inline void MxListCursor::Detach() { MxListEntry *m_prev = m_match->m_prev; MxListEntry *m_next = m_match->m_next; if (m_prev) m_prev->m_next = m_next; else m_list->m_first = m_next; if (m_next) m_next->m_prev = m_prev; else m_list->m_last = m_prev; delete m_match; m_list->m_count--; m_match = NULL; } template inline MxBool MxListCursor::Next(T*& p_obj) { if (!m_match) m_match = m_list->m_first; else m_match = m_match->m_next; if (m_match) p_obj = m_match->m_obj; return m_match != NULL; } #endif // MXLIST_H