239 lines
6.8 KiB
C++
239 lines
6.8 KiB
C++
/*=========================================================================
|
|
*
|
|
* 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 CWndDerivedClass>
|
|
class clVectorNode
|
|
{
|
|
//friend class CWndDerivedClass;
|
|
friend class DEV_Timer<CWndDerivedClass>;
|
|
|
|
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 CWndDerivedClass>
|
|
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<CWndDerivedClass> *m_p_oGetVectorHead() { return m_p_oVectorHead; };
|
|
unsigned int m_uiTimerId;
|
|
clVectorNode<CWndDerivedClass> *m_p_oVectorHead;
|
|
CWndDerivedClass *m_p_oOwner;
|
|
};
|
|
|
|
/*===========================================================================
|
|
constructor / destructor
|
|
=========================================================================*/
|
|
|
|
template <class CWndDerivedClass>
|
|
DEV_Timer<CWndDerivedClass>::DEV_Timer<CWndDerivedClass>(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 <class CWndDerivedClass>
|
|
DEV_Timer<CWndDerivedClass>::~DEV_Timer<CWndDerivedClass>()
|
|
{
|
|
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 <class CWndDerivedClass>
|
|
void DEV_Timer<CWndDerivedClass>::m_vSuspendTimer()
|
|
{
|
|
if ( m_p_oOwner )
|
|
{
|
|
if ( m_uiTimerId && m_p_oOwner->KillTimer(m_uiTimerId) )
|
|
m_uiTimerId = 0;
|
|
}
|
|
}
|
|
|
|
/*===========================================================================
|
|
start the timer
|
|
=========================================================================*/
|
|
|
|
template <class CWndDerivedClass>
|
|
void DEV_Timer<CWndDerivedClass>::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 <class CWndDerivedClass>
|
|
void DEV_Timer<CWndDerivedClass>::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<CWndDerivedClass> *p_oVectorNode = new clVectorNode<CWndDerivedClass>;
|
|
if ( p_oVectorNode )
|
|
{
|
|
clVectorNode<CWndDerivedClass> *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 <class CWndDerivedClass>
|
|
BOOL DEV_Timer<CWndDerivedClass>::m_bRemoveHandler(tdfn_vTimerVector fn_vVectorHandler)
|
|
{
|
|
BOOL bRetVal = FALSE;
|
|
|
|
if ( m_p_oOwner && m_p_oVectorHead )
|
|
{
|
|
clVectorNode<CWndDerivedClass> *p_oCurrentNode = m_p_oVectorHead;
|
|
clVectorNode<CWndDerivedClass> *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 <class CWndDerivedClass>
|
|
void DEV_Timer<CWndDerivedClass>::m_vOnTimer(CWndDerivedClass *p_oOwner)
|
|
{
|
|
clVectorNode<CWndDerivedClass> *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
|
|
|
|
|