From 14fc0d0f71e1cb682473b7f7bbc959cfa70d163d Mon Sep 17 00:00:00 2001 From: Treeki Date: Sun, 8 Jan 2012 05:26:39 +0100 Subject: finally, a proper state API! hopefully this didn't break anything --- include/game.h | 63 ++++++++++----------- include/statelib.h | 159 +++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 163 insertions(+), 59 deletions(-) (limited to 'include') diff --git a/include/game.h b/include/game.h index 465bbd4..3b2876d 100755 --- a/include/game.h +++ b/include/game.h @@ -1092,53 +1092,54 @@ class dActorState_c; class dActorMultiState_c; -class AcStateMgrBase { +template +class dStateWrapperBase_c { public: - virtual ~AcStateMgrBase(); - - u32 cls1, cls2, cls3; - dActorMultiState_c *owner; - u32 unkZero; - - dStateMgr_c manager; - - // All these are passed straight through to the manager - virtual void _vfC(); - virtual void _vf10(); - virtual void _vf14(); - virtual void _vf18(); - virtual void _vf1C(); - virtual void _vf20(); - virtual void _vf24(); - virtual void _vf28(); - virtual void _vf2C(); + virtual ~dStateWrapperBase_c() { } + + dStatePointless_c pointless; + dStateExecutor_c executor; + + dStateMgr_c manager; + + // All these are passed straight through to the manager, todo: name them and arguments + virtual void ensureStateHasBegun(); + virtual void execute(); + virtual void endCurrentState(); + virtual void setState(dStateBase_c *pNewState); + virtual void executeNextStateThisTick(); + virtual dStateMethodExecutorBase_c *getCurrentStateMethodExecutor(); + virtual dStateBase_c *getNextState(); + virtual dStateBase_c *getCurrentState(); + virtual dStateBase_c *getPreviousState(); }; -class AcStateMgr : public AcStateMgrBase { +template +class dStateWrapper_c : public dStateWrapperBase_c { public: - ~AcStateMgr(); + ~dStateWrapper_c() { } }; class MultiStateMgrBase { public: virtual ~MultiStateMgrBase(); - AcStateMgr s1, s2; - AcStateMgr *ptrToStateMgr; + dStateWrapper_c s1, s2; + dStateWrapper_c *ptrToStateMgr; - virtual void _vfC(); // calls vfC on ptrToStateMgr + virtual void ensureStateHasBegun(); // calls vfC on ptrToStateMgr virtual void execute(); // calls vf10 on ptrToStateMgr - virtual void _vf14(); // if (isSecondStateMgr()) { disableSecond(); } else { ptrToStateMgr->_vf14(); } + virtual void endCurrentState(); // if (isSecondStateMgr()) { disableSecond(); } else { ptrToStateMgr->_vf14(); } virtual void setState(dStateBase_c *state); // calls vf18 on ptrToStateMgr - virtual void _vf1C(); // calls vf1C on ptrToStateMgr - virtual void _vf20(); // calls vf20 on ptrToStateMgr - virtual void _vf24(); // calls vf24 on ptrToStateMgr + virtual void executeNextStateThisTick(); // calls vf1C on ptrToStateMgr + virtual dStateMethodExecutorBase_c *getCurrentStateMethodExecutor(); // calls vf20 on ptrToStateMgr + virtual dStateBase_c *getNextState(); // calls vf24 on ptrToStateMgr virtual dStateBase_c *getCurrentState(); // calls vf28 on ptrToStateMgr - virtual void _vf2C(); // calls vf2C on ptrToStateMgr - virtual void enableSecond(); // sets ptrToStateMgr to s2, calls vf18 on it + virtual dStateBase_c *getPreviousState(); // calls vf2C on ptrToStateMgr + virtual void enableSecondWithState(dStateBase_c *state); // sets ptrToStateMgr to s2, calls vf18 on it virtual void disableSecond(); // if (isSecondStateMgr()) { ptrToStateMgr->vf14(); ptrToStateMgr = &s1; } virtual bool isSecondStateMgr(); - virtual void _vf3C(); // calls vf28 on s1 + virtual dStateBase_c *getCurrentStateFromFirst(); // calls vf28 on s1 }; class MultiStateMgr : public MultiStateMgrBase { diff --git a/include/statelib.h b/include/statelib.h index c039934..d387f02 100644 --- a/include/statelib.h +++ b/include/statelib.h @@ -24,6 +24,7 @@ private: static int mLastID; }; + /******************************************************************************/ // dState_c : dStateBase_c class /******************************************************************************/ @@ -49,6 +50,8 @@ public: funcPtr mBegin; funcPtr mExecute; funcPtr mEnd; + + void *mBaseState; }; template @@ -83,51 +86,151 @@ void dState_c::doEnd(TOwner *owner) { } /******************************************************************************/ -// dStateMgrBase_c class +// A Very Useless Class +/******************************************************************************/ +class dStatePointless_c { + public: + virtual ~dStatePointless_c(); + virtual int returnsOne(); // Does exactly what it says on the tin. +}; + +/******************************************************************************/ +// Executor Interfaces +/******************************************************************************/ +class dStateMethodExecutorBase_c { + public: + virtual ~dStateMethodExecutorBase_c() = 0; + + virtual void callBegin() = 0; + virtual void callExecute() = 0; + virtual void callEnd() = 0; +}; + +class dStateExecutorBase_c { + public: + virtual ~dStateExecutorBase_c() = 0; + + virtual dStateMethodExecutorBase_c *getMethodExecutorForState(dStateBase_c *state) = 0; + virtual void clearMethodExecutor(dStateMethodExecutorBase_c **ptrToPtrToExecutor) = 0; +}; + +/******************************************************************************/ +// Executor Implementations /******************************************************************************/ +template +class dStateMethodExecutor_c : public dStateMethodExecutorBase_c { + public: + ~dStateMethodExecutor_c(); + + void callBegin(); + void callExecute(); + void callEnd(); + + TOwner *mOwningObject; + dState_c *mState; +}; + +template +class dStateExecutor_c : public dStateExecutorBase_c { + public: + ~dStateExecutor_c(); + + dStateMethodExecutorBase_c *getMethodExecutorForState(dStateBase_c *state); + void clearMethodExecutor(dStateMethodExecutorBase_c **ptrToPtrToExecutor); + + private: + dStateMethodExecutor_c mStockExecutor; +}; + + + + +template +dStateMethodExecutorBase_c *dStateExecutor_c::getMethodExecutorForState(dStateBase_c *state) { + if (!state->isInvalid()) { + mStockExecutor.mState = static_cast*>(state); + return &mStockExecutor; + } else { + return 0; + } +} + +template +void dStateExecutor_c::clearMethodExecutor(dStateMethodExecutorBase_c **ptrToPtrToExecutor) { + *ptrToPtrToExecutor = 0; +} + + +template +void dStateMethodExecutor_c::callBegin() { mState->doBegin(mOwningObject); } +template +void dStateMethodExecutor_c::callExecute() { mState->doExecute(mOwningObject); } +template +void dStateMethodExecutor_c::callEnd() { mState->doEnd(mOwningObject); } + +/******************************************************************************/ +// dStateMgrBase_c class +/******************************************************************************/ class dStateMgrBase_c { public: - dStateMgrBase_c(void *one, void *two, dStateBase_c *pInitState); + dStateMgrBase_c(dStatePointless_c *pPointlessClass, dStateExecutorBase_c *pStateExecutor, dStateBase_c *pInitState); virtual ~dStateMgrBase_c(); - virtual void _vf0C(); + virtual void ensureStateHasBegun(); virtual void execute(); - virtual void _vf14(); + virtual void endCurrentState(); virtual void setState(dStateBase_c *pNewState); - virtual void setField10ToOne(); - virtual dStateBase_c *getField20(); - virtual dStateBase_c *getField14(); - virtual dStateBase_c *getCurrentState_maybe(); - virtual dStateBase_c *getField18(); - virtual bool _vf30() = 0; - virtual void _vf34() = 0; - virtual void _vf38() = 0; - virtual void _vf3C(dStateBase_c *pState) = 0; -private: - void *m04, *m08; - bool m0C, m0D, m0E, m0F, m10; - dStateBase_c *m14, *m18, *m1C; - dStateBase_c *m20; // maybe not a dStateBase_c? + virtual void executeNextStateThisTick() { + mExecuteNextStateThisTick = true; + } + + virtual dStateMethodExecutorBase_c *getCurrentStateMethodExecutor() { + return mCurrentStateMethodExecutor; + } + + virtual dStateBase_c *getNextState() { + return mNextState; + } + + virtual dStateBase_c *getCurrentState() { + return mCurrentState; + } + + virtual dStateBase_c *getPreviousState() { + return mPreviousState; + } + + virtual bool callBeginOnState() = 0; + virtual void callExecuteOnState() = 0; + virtual void callEndOnState() = 0; + virtual void doSwitchToNextState(dStateBase_c *pState/*unused*/) = 0; + +protected: + dStatePointless_c *mPointlessClass; + dStateExecutorBase_c *mStateExecutor; + + bool mIsStateBeginningOrEnding, mIsStateExecuting; + bool mStateIsCurrentlyActive, mStateChangeHasOccurred; + bool mExecuteNextStateThisTick; + + dStateBase_c *mNextState, *mPreviousState, *mCurrentState; + dStateMethodExecutorBase_c *mCurrentStateMethodExecutor; }; /******************************************************************************/ -// dStateMgr_c : dStateMgrBase_c class +// dStateMgr_c : dStateMgrBase_c class /******************************************************************************/ - -template class dStateMgr_c : public dStateMgrBase_c { public: - dStateMgr_c(void *one, void *two, dStateBase_c *pInitState); + dStateMgr_c(dStatePointless_c *pPointlessClass, dStateExecutorBase_c *pStateExecutor, dStateBase_c *pInitState); ~dStateMgr_c(); - bool _vf30(); - void _vf34(); - void _vf38(); - void _vf3C(dStateBase_c *pState); + bool callBeginOnState(); + void callExecuteOnState(); + void callEndOnState(); + void doSwitchToNextState(dStateBase_c *pState/*unused*/); }; -// TODO: add template methods - -- cgit v1.2.3