/*========================================================================= * * DEVTimer.hpp (PRIVATE HEADER): class DEV_Timer * * * Version 1.0 * Creation date 97/01/15 * Revision date * * Benoit Germain *=======================================================================*/ #ifdef ACTIVE_EDITOR #include "stdafx.h" #ifndef __DEVTIMER_HPP__ #define __DEVTIMER_HPP__ #include "acp_base.h" //************************************** #ifndef CPA_EXPORT #if defined(CPA_WANTS_IMPORT) #define CPA_EXPORT __declspec(dllimport) #elif defined(CPA_WANTS_EXPORT) #define CPA_EXPORT __declspec(dllexport) #else #define CPA_EXPORT #endif #endif //************************************** ///////////////////////////////////////////////////////////////////////////// // DEV_TimerXXX class ///////////////////////////////////////////////////////////////////////////// #define C_ulDefaultTimerElapse 100 //pointer to a function of the timer vector array of handlers typedef void (*tdfn_vTimerVector)(void *); template class clVectorNode { //friend class CWndDerivedClass; friend class DEV_Timer; private: tdfn_vTimerVector m_fn_vVectorHandler; CWndDerivedClass *m_p_oOwner; //tdfn_vTimerVector fn_vVectorHandler; clVectorNode *m_p_oNext; public: void m_vCallVector() { if ( m_fn_vVectorHandler ) m_fn_vVectorHandler(m_p_oOwner); }; clVectorNode *m_p_oGetNext() { return m_p_oNext; }; }; template class DEV_Timer { friend class CWndDerivedClass; public: DEV_Timer(CWndDerivedClass *p_oOwner, unsigned long ulMilliseconds = C_ulDefaultTimerElapse); ~DEV_Timer(); void m_vAddHandler(CWndDerivedClass *p_oOwner, tdfn_vTimerVector fn_vVectorHandler); BOOL m_bRemoveHandler(tdfn_vTimerVector fn_vVectorHandler); void m_vRestartTimer(unsigned long ulMilliseconds = C_ulDefaultTimerElapse); void m_vSuspendTimer(); void m_vOnTimer(CWndDerivedClass *p_oOwner); protected: private: clVectorNode *m_p_oGetVectorHead() { return m_p_oVectorHead; }; unsigned int m_uiTimerId; clVectorNode *m_p_oVectorHead; CWndDerivedClass *m_p_oOwner; }; /*=========================================================================== constructor / destructor =========================================================================*/ template DEV_Timer::DEV_Timer(CWndDerivedClass *p_oOwner, unsigned long ulMilliseconds) { if ( m_p_oOwner = p_oOwner ) { m_p_oVectorHead = NULL; // no timer yet m_uiTimerId = 0; // start it m_vRestartTimer(ulMilliseconds); } } /*===========================================================================*/ template DEV_Timer::~DEV_Timer() { if ( m_p_oOwner ) { // stop the timer event queue processing m_vSuspendTimer(); // remove all the handler nodes while ( m_p_oVectorHead && m_bRemoveHandler(m_p_oVectorHead->m_fn_vVectorHandler)); } } /*=========================================================================== stop the timer =========================================================================*/ template void DEV_Timer::m_vSuspendTimer() { if ( m_p_oOwner ) { if ( m_uiTimerId && m_p_oOwner->KillTimer(m_uiTimerId) ) m_uiTimerId = 0; } } /*=========================================================================== start the timer =========================================================================*/ template void DEV_Timer::m_vRestartTimer(unsigned long ulMilliseconds) { if ( m_p_oOwner ) { // stop the timer before restarting in case this is just a timeout change m_vSuspendTimer(); if ( ulMilliseconds ) m_uiTimerId = m_p_oOwner->SetTimer(1, ulMilliseconds, NULL); } } /*=========================================================================== add a handler to the list of handlers =========================================================================*/ template void DEV_Timer::m_vAddHandler(CWndDerivedClass *p_oOwner, tdfn_vTimerVector fn_vVectorHandler) { //TODO-BBB: I hope that no OnTimer scanning method is currently scanning the list... if ( m_p_oOwner && m_p_oOwner == p_oOwner ) { // remove the handler if it already existed m_bRemoveHandler(fn_vVectorHandler); if ( fn_vVectorHandler ) { //allocate a new node clVectorNode *p_oVectorNode = new clVectorNode; if ( p_oVectorNode ) { clVectorNode *p_oOldHead = m_p_oVectorHead; // set it p_oVectorNode->m_fn_vVectorHandler = fn_vVectorHandler; p_oVectorNode->m_p_oOwner = p_oOwner; // insert it in the list m_p_oVectorHead = p_oVectorNode; m_p_oVectorHead->m_p_oNext = p_oOldHead; } } } } /*=========================================================================== remove a handler from the queue if it exists, returns TRUE if a handler is removed, else FALSE =========================================================================*/ template BOOL DEV_Timer::m_bRemoveHandler(tdfn_vTimerVector fn_vVectorHandler) { BOOL bRetVal = FALSE; if ( m_p_oOwner && m_p_oVectorHead ) { clVectorNode *p_oCurrentNode = m_p_oVectorHead; clVectorNode *p_oPrevNode = m_p_oVectorHead; // stalk the list, stop when we find a handler that is ours while ( p_oCurrentNode ) if ( p_oCurrentNode->m_fn_vVectorHandler == fn_vVectorHandler ) { if ( p_oPrevNode == p_oCurrentNode ) // if we remove the head m_p_oVectorHead = p_oCurrentNode->m_p_oNext; // make the head point to the next item else p_oPrevNode->m_p_oNext = p_oCurrentNode->m_p_oNext; // make the list skip the found node // destroy the node delete p_oCurrentNode; p_oCurrentNode = NULL; bRetVal = TRUE; } else { p_oPrevNode = p_oCurrentNode; p_oCurrentNode = p_oCurrentNode->m_p_oNext; } } return bRetVal; } template void DEV_Timer::m_vOnTimer(CWndDerivedClass *p_oOwner) { clVectorNode *p_oCurrentNode = m_p_oGetVectorHead(); // if the world, the event editor and the current editor agree to it if ( p_oCurrentNode && M_VGetParentMultiDevice3DOf(p_oOwner)->GetWorld()->fn_bAcceptToRunTimerEngine() && M_VGetParentMultiDevice3DOf(p_oOwner)->GetInterface()->GetMainWorld()->GetCurrentEditor()->fn_bAcceptToRunTimerEngine() && M_VGetParentMultiDevice3DOf(p_oOwner)->GetInterface()->GetEditor()->fn_bAcceptToRunTimerEngine() ) // call all the handlers is sequence while( p_oCurrentNode ) { p_oCurrentNode->m_vCallVector(); p_oCurrentNode = p_oCurrentNode->m_p_oGetNext(); } } #undef TIMERCLASS_TEMPLATE #endif //__DEVTIMER_HPP__ #endif // ACTIVE_EDITOR