History: Timer class with queued callbacks
Source of version: 3 (current)
Copy to clipboard
This class wraps an internal Ogre::Timer and provides a handy function to delay the execution of callbacks.
{REMARKSBOX(type="note",title="Note")}Uses boost::function, but feel free to edit TimedCallback, and use function pointers or whatever...{REMARKSBOX}
Example usage:
{CODE(wrap="1", colors="c++")}
// the callback
void foo(void) { cout << "bar" << endl; }
// delay
::Timer::getInstance()->delay(&foo, 1000);
// somewhere, in your main-loop if using renderOneFrame(), or a framelistener's frameStarted()...
...
::Timer::getInstance()->processQueue();
{CODE}
Timer.h
{CODE(wrap="1", colors="c++")}#ifndef TIMER_H
#define TIMER_H
#include <OgreTimer.h>
#include <vector>
#include <queue>
#include <utility>
#include <boost/function.hpp>
typedef std::pair< unsigned long, boost::function<void ()> > TimedCallback;
class PrioritizeCallbacks
{
public:
bool operator() ( const TimedCallback& lhs, const TimedCallback& rhs ) const
{
return rhs.first < lhs.first;
}
};
typedef std::priority_queue< TimedCallback, std::vector<TimedCallback>, PrioritizeCallbacks > TimedCallbackQueue;
class Timer
{
public:
static Timer* getInstance();
static void Release();
/**
* \return Milliseconds since timer started
*/
unsigned long getTime() { return mTimer->getMilliseconds(); }
/**
* \return Microseconds since timer started
*/
unsigned long getMicroTime() { return mTimer->getMicroseconds(); }
/**
* \brief Delayed execution of a callback
* \param cb
*/
inline void delay(TimedCallback cb) { mQueue.push(cb); }
/**
* \brief Delayed execution of a callback
* \param func the callback to execute
* \param time to delay execution of callback
*/
void delay(boost::function<void ()> func, unsigned long time);
/**
* \brief Process the callback queue, executes pending functions
* \note Have to call this manually, at shortest possible intervals,
* If using Ogre::Root::startRendering() for example, this would be on every
* onFrameStarted().
*/
void processQueue();
/**
* \brief Clears the queue
*/
void clearQueue();
private:
Timer();
virtual ~Timer();
protected:
Ogre::Timer* mTimer;
TimedCallbackQueue mQueue;
static Timer* ms_instance;
};
#endif // TIMER_H
{CODE}
Timer.cpp
{CODE(wrap="1", colors="c++")}#include "Timer.h"
Timer* Timer::ms_instance = 0;
Timer::Timer()
{
mTimer = new Ogre::Timer();
}
Timer::~Timer()
{
delete mTimer;
}
Timer* Timer::getInstance()
{
if(ms_instance == 0)
{
ms_instance = new Timer();
}
return ms_instance;
}
void Timer::Release()
{
if(ms_instance)
{
delete ms_instance;
}
ms_instance = 0;
}
void Timer::delay(boost::function<void ()> func, unsigned long time)
{
TimedCallback cb(getTime() + time, func);
delay(cb);
}
void Timer::processQueue()
{
while(!mQueue.empty())
{
const TimedCallback &cb = mQueue.top();
long delta = cb.first - getTime();
if(delta>0) return;
cb.second();
mQueue.pop();
}
}
void Timer::clearQueue()
{
mQueue = TimedCallbackQueue();
}
{CODE}