reman3/Rayman_X/cpa/tempgrp/ITF/devtimer.hpp

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