diff --git a/LEGO1/mxcompositepresenter.cpp b/LEGO1/mxcompositepresenter.cpp index 43ad4cc1..7685fe57 100644 --- a/LEGO1/mxcompositepresenter.cpp +++ b/LEGO1/mxcompositepresenter.cpp @@ -1,7 +1,6 @@ #include "mxcompositepresenter.h" #include "decomp.h" -#include "mxactionnotificationparam.h" #include "mxautolocker.h" #include "mxdsmultiaction.h" #include "mxnotificationmanager.h" @@ -112,25 +111,93 @@ MxLong MxCompositePresenter::Notify(MxParam& p_param) switch (((MxNotificationParam&) p_param).GetNotification()) { case c_notificationEndAction: - VTable0x58(p_param); + VTable0x58((MxEndActionNotificationParam&) p_param); break; case MXPRESENTER_NOTIFICATION: - VTable0x5c(p_param); + VTable0x5c((MxNotificationParam&) p_param); } return 0; } -// STUB: LEGO1 0x100b67f0 -void MxCompositePresenter::VTable0x58(MxParam& p_param) +// FUNCTION: LEGO1 0x100b67f0 +void MxCompositePresenter::VTable0x58(MxEndActionNotificationParam& p_param) { - // TODO + MxPresenter* presenter = (MxPresenter*) p_param.GetSender(); + MxDSAction* action = p_param.GetAction(); + MxCompositePresenterList::iterator it; + + if (!m_list.empty()) { + for (it = m_list.begin(); it != m_list.end(); it++) { + if (*it == presenter) { + m_list.erase(it++); + break; + } + } + } + + if (m_action) { + MxDSActionList* actions = ((MxDSMultiAction*) m_action)->GetActionList(); + MxDSActionListCursor cursor(actions); + + if (cursor.Find(action)) + cursor.Detach(); + } + + if (presenter) + delete presenter; + + if (action) + delete action; + + if (m_list.empty()) { + EndAction(); + } + else { + if (m_action->IsA("MxDSSerialAction") && it != m_list.end()) { + MxPresenter* presenter = *it; + if (presenter->GetCurrentTickleState() == TickleState_Idle) + presenter->SetTickleState(TickleState_Ready); + } + } } -// STUB: LEGO1 0x100b69b0 -void MxCompositePresenter::VTable0x5c(MxParam& p_param) +// FUNCTION: LEGO1 0x100b69b0 +void MxCompositePresenter::VTable0x5c(MxNotificationParam& p_param) { - // TODO + if (!m_list.empty()) { + MxPresenter* presenter = (MxPresenter*) p_param.GetSender(); + + for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) { + if (*it == presenter) { + m_list.erase(it++); + + if (presenter->GetCurrentTickleState() == TickleState_Idle) + presenter->SetTickleState(TickleState_Ready); + + MxDSActionList* actions = ((MxDSMultiAction*) m_action)->GetActionList(); + MxDSActionListCursor cursor(actions); + + if (cursor.Find(presenter->GetAction())) + cursor.Detach(); + + if (m_list.empty()) { + EndAction(); + } + else { + if (m_action->IsA("MxDSSerialAction")) { + MxPresenter* presenter = *it; + if (presenter->GetCurrentTickleState() == TickleState_Idle) + presenter->SetTickleState(TickleState_Ready); + } + } + + return; + } + } + + NotificationManager()->Send(this, &p_param); + } } // FUNCTION: LEGO1 0x100b6b40 @@ -152,21 +219,40 @@ void MxCompositePresenter::VTable0x60(MxPresenter* p_presenter) } } -// STUB: LEGO1 0x100b6bc0 +// FUNCTION: LEGO1 0x100b6bc0 void MxCompositePresenter::SetTickleState(TickleState p_tickleState) { - // TODO + m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState; + m_currentTickleState = p_tickleState; + + for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) { + MxPresenter* presenter = *it; + presenter->SetTickleState(p_tickleState); + + if (m_action->IsA("MxDSSerialAction") && p_tickleState == TickleState_Ready) + return; + } } -// STUB: LEGO1 0x100b6c30 +// FUNCTION: LEGO1 0x100b6c30 void MxCompositePresenter::Enable(MxBool p_enable) { - // TODO + MxPresenter::Enable(p_enable); + + for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) { + MxPresenter* presenter = *it; + presenter->Enable(p_enable); + } } -// STUB: LEGO1 0x100b6c80 +// FUNCTION: LEGO1 0x100b6c80 MxBool MxCompositePresenter::HasTickleStatePassed(TickleState p_tickleState) { - // TODO + for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) { + MxPresenter* presenter = *it; + if (!presenter->HasTickleStatePassed(p_tickleState)) + return FALSE; + } + return TRUE; } diff --git a/LEGO1/mxcompositepresenter.h b/LEGO1/mxcompositepresenter.h index 5ce6b84f..30dc170d 100644 --- a/LEGO1/mxcompositepresenter.h +++ b/LEGO1/mxcompositepresenter.h @@ -1,6 +1,7 @@ #ifndef MXCOMPOSITEPRESENTER_H #define MXCOMPOSITEPRESENTER_H +#include "mxactionnotificationparam.h" #include "mxpresenter.h" #include "mxstl/stlcompat.h" @@ -28,15 +29,15 @@ class MxCompositePresenter : public MxPresenter { return !strcmp(p_name, MxCompositePresenter::ClassName()) || MxPresenter::IsA(p_name); } - virtual MxResult StartAction(MxStreamController*, MxDSAction* p_action) override; // vtable+0x3c - virtual void EndAction() override; // vtable+0x40 - virtual void SetTickleState(TickleState p_tickleState) override; // vtable+0x44 - virtual MxBool HasTickleStatePassed(TickleState p_tickleState) override; // vtable+0x48 - virtual void Enable(MxBool p_enable) override; // vtable+0x54 - virtual void VTable0x58(MxParam& p_param); // vtable+0x58 - virtual void VTable0x5c(MxParam& p_param); // vtable+0x5c - virtual void VTable0x60(MxPresenter* p_presenter); // vtable+0x60 - virtual MxBool VTable0x64(undefined4 p_undefined); // vtable+0x64 + virtual MxResult StartAction(MxStreamController* p_controller, MxDSAction* p_action) override; // vtable+0x3c + virtual void EndAction() override; // vtable+0x40 + virtual void SetTickleState(TickleState p_tickleState) override; // vtable+0x44 + virtual MxBool HasTickleStatePassed(TickleState p_tickleState) override; // vtable+0x48 + virtual void Enable(MxBool p_enable) override; // vtable+0x54 + virtual void VTable0x58(MxEndActionNotificationParam& p_param); // vtable+0x58 + virtual void VTable0x5c(MxNotificationParam& p_param); // vtable+0x5c + virtual void VTable0x60(MxPresenter* p_presenter); // vtable+0x60 + virtual MxBool VTable0x64(undefined4 p_undefined); // vtable+0x64 private: MxCompositePresenterList m_list; // 0x40 @@ -57,4 +58,7 @@ class MxCompositePresenter : public MxPresenter { // TEMPLATE: LEGO1 0x100b6340 // List::~List +// TEMPLATE: LEGO1 0x100b6cd0 +// MxList::_DeleteEntry + #endif // MXCOMPOSITEPRESENTER_H