This class wraps an internal Ogre::Timer and provides a handy function to delay the execution of callbacks.

 Note

Uses boost::function, but feel free to edit TimedCallback, and use function pointers or whatever...


Example usage:

// 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();


Timer.h

#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


Timer.cpp

#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();
}