Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "ttimer.h"
Toshihiro Shimizu 890ddd
#include "texception.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <windows.h></windows.h>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//moto strano: se togliamo l'include della glut non linka
Toshihiro Shimizu 890ddd
#include <gl glut.h=""></gl>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CALLBACK ElapsedTimeCB(UINT uID, UINT uMsg,
Toshihiro Shimizu 890ddd
							DWORD dwUser, DWORD dw1,
Toshihiro Shimizu 890ddd
							DWORD dw2);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class TTimer::Imp
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 3bfa54
	Imp(std::string name, UINT timerRes, TTimer::Type type, TTimer *timer);
Toshihiro Shimizu 890ddd
	~Imp();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void start(UINT delay)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_started)
Toshihiro Shimizu 890ddd
			throw TException("The timer is already started");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_timerID = timeSetEvent(delay, m_timerRes,
Toshihiro Shimizu 890ddd
								 (LPTIMECALLBACK)ElapsedTimeCB, (DWORD) this,
Toshihiro Shimizu 890ddd
								 m_type | TIME_CALLBACK_FUNCTION);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_delay = delay;
Toshihiro Shimizu 890ddd
		m_ticks = 0;
Toshihiro Shimizu 890ddd
		if (m_timerID == NULL)
Toshihiro Shimizu 890ddd
			throw TException("Unable to start timer");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_started = true;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void stop()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_started)
Toshihiro Shimizu 890ddd
			timeKillEvent(m_timerID);
Toshihiro Shimizu 890ddd
		m_started = false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::string getName() { return m_name; }
Toshihiro Shimizu 890ddd
	TUINT64 getTicks() { return m_ticks; }
Toshihiro Shimizu 890ddd
	UINT getDelay() { return m_delay; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::string m_name;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UINT m_timerRes;
Toshihiro Shimizu 890ddd
	UINT m_type;
Toshihiro Shimizu 890ddd
	TTimer *m_timer;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UINT m_timerID;
Toshihiro Shimizu 890ddd
	UINT m_delay;
Toshihiro Shimizu 890ddd
	TUINT64 m_ticks;
Toshihiro Shimizu 890ddd
	bool m_started;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TGenericTimerAction *m_action;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
TTimer::Imp::Imp(std::string name, UINT timerRes, TTimer::Type type, TTimer *timer)
Toshihiro Shimizu 890ddd
	: m_name(name), m_timerRes(timerRes), m_timer(timer), m_type(type), m_timerID(NULL), m_ticks(0), m_delay(0), m_started(false), m_action(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TIMECAPS tc;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) {
Toshihiro Shimizu 890ddd
		throw TException("Unable to create timer");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_timerRes = tmin((int)tmax((int)tc.wPeriodMin, (int)m_timerRes), (int)tc.wPeriodMax);
Toshihiro Shimizu 890ddd
	timeBeginPeriod(m_timerRes);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	switch (type) {
Toshihiro Shimizu 890ddd
	case TTimer::OneShot:
Toshihiro Shimizu 890ddd
		m_type = TIME_ONESHOT;
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	case TTimer::Periodic:
Toshihiro Shimizu 890ddd
		m_type = TIME_PERIODIC;
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	default:
Toshihiro Shimizu 890ddd
		throw TException("Unexpected timer type");
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TTimer::Imp::~Imp()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	stop();
Toshihiro Shimizu 890ddd
	timeEndPeriod(m_timerRes);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_action)
Toshihiro Shimizu 890ddd
		delete m_action;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void CALLBACK ElapsedTimeCB(UINT uID, UINT uMsg,
Toshihiro Shimizu 890ddd
							DWORD dwUser, DWORD dw1,
Toshihiro Shimizu 890ddd
							DWORD dw2)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTimer::Imp *imp = reinterpret_cast<ttimer::imp *="">(dwUser);</ttimer::imp>
Toshihiro Shimizu 890ddd
	imp->m_ticks++;
Toshihiro Shimizu 890ddd
	if (imp->m_action)
Toshihiro Shimizu 890ddd
		imp->m_action->sendCommand(imp->m_ticks);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
#elif LINUX
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <sdl sdl_timer.h=""></sdl>
Toshihiro Shimizu 890ddd
#include <sdl sdl.h=""></sdl>
Toshihiro Shimizu 890ddd
#include "tthread.h"
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Uint32 ElapsedTimeCB(Uint32 interval, void *param);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class TTimer::Imp
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 3bfa54
	Imp(std::string name, UINT timerRes, TTimer::Type type, TTimer *timer)
Toshihiro Shimizu 890ddd
		: m_action(0), m_ticks(0)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	~Imp() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void start(UINT delay)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		static bool first = true;
Toshihiro Shimizu 890ddd
		if (first) {
Toshihiro Shimizu 890ddd
			SDL_Init(SDL_INIT_TIMER);
Toshihiro Shimizu 890ddd
			first = false;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		m_timerID = SDL_AddTimer(delay, ElapsedTimeCB, this);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void stop()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		SDL_RemoveTimer(m_timerID);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::string getName() { return m_name; }
Toshihiro Shimizu 890ddd
	TUINT64 getTicks() { return m_ticks; }
Toshihiro Shimizu 890ddd
	UINT getDelay() { return m_delay; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::string m_name;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UINT m_timerRes;
Toshihiro Shimizu 890ddd
	UINT m_type;
Toshihiro Shimizu 890ddd
	TTimer *m_timer;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	SDL_TimerID m_timerID;
Toshihiro Shimizu 890ddd
	UINT m_delay;
Toshihiro Shimizu 890ddd
	TUINT64 m_ticks;
Toshihiro Shimizu 890ddd
	bool m_started;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TGenericTimerAction *m_action;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class SendCommandMSG : public TThread::Msg
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTimer::Imp *m_ztimp;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	SendCommandMSG(TTimer::Imp *ztimp) : TThread::Msg(), m_ztimp(ztimp)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	~SendCommandMSG() {}
Toshihiro Shimizu 890ddd
	TThread::Msg *clone() const { return new SendCommandMSG(*this); }
Toshihiro Shimizu 890ddd
	void onDeliver()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_ztimp->m_action)
Toshihiro Shimizu 890ddd
			m_ztimp->m_action->sendCommand(m_ztimp->m_ticks);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Uint32 ElapsedTimeCB(Uint32 interval, void *param)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTimer::Imp *imp = reinterpret_cast<ttimer::imp *="">(param);</ttimer::imp>
Toshihiro Shimizu 890ddd
	imp->m_ticks++;
Toshihiro Shimizu 890ddd
	SendCommandMSG(imp).send();
Toshihiro Shimizu 890ddd
	return interval;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#elif __sgi
Toshihiro Shimizu 890ddd
class TTimer::Imp
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 3bfa54
	Imp(std::string name, UINT timerRes, TTimer::Type type, TTimer *timer)
Toshihiro Shimizu 890ddd
		: m_action(0) {}
Toshihiro Shimizu 890ddd
	~Imp() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void start(UINT delay)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_started)
Toshihiro Shimizu 890ddd
			throw TException("The timer is already started");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_started = true;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void stop()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_started = false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::string getName() { return m_name; }
Toshihiro Shimizu 890ddd
	TUINT64 getTicks() { return m_ticks; }
Toshihiro Shimizu 890ddd
	UINT getDelay() { return m_delay; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::string m_name;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UINT m_timerRes;
Toshihiro Shimizu 890ddd
	UINT m_type;
Toshihiro Shimizu 890ddd
	TTimer *m_timer;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UINT m_timerID;
Toshihiro Shimizu 890ddd
	UINT m_delay;
Toshihiro Shimizu 890ddd
	TUINT64 m_ticks;
Toshihiro Shimizu 890ddd
	bool m_started;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TGenericTimerAction *m_action;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
#elif MACOSX
Toshihiro Shimizu 890ddd
class TTimer::Imp
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 3bfa54
	Imp(std::string name, UINT timerRes, TTimer::Type type, TTimer *timer)
Toshihiro Shimizu 890ddd
		: m_action(0) {}
Toshihiro Shimizu 890ddd
	~Imp() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void start(UINT delay)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (m_started)
Toshihiro Shimizu 890ddd
			throw TException("The timer is already started");
Toshihiro Shimizu 890ddd
		throw TException("The timer is not yet available under MAC :(");
Toshihiro Shimizu 890ddd
		m_started = true;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void stop()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_started = false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::string getName() { return m_name; }
Toshihiro Shimizu 890ddd
	TUINT64 getTicks() { return m_ticks; }
Toshihiro Shimizu 890ddd
	UINT getDelay() { return m_delay; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::string m_name;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UINT m_timerRes;
Toshihiro Shimizu 890ddd
	UINT m_type;
Toshihiro Shimizu 890ddd
	TTimer *m_timer;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UINT m_timerID;
Toshihiro Shimizu 890ddd
	UINT m_delay;
Toshihiro Shimizu 890ddd
	TUINT64 m_ticks;
Toshihiro Shimizu 890ddd
	bool m_started;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TGenericTimerAction *m_action;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//  TTimer
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//===============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
TTimer::TTimer(const std::string &name, UINT timerRes, Type type)
Shinya Kitaoka 262a92
	: m_imp(new TTimer::Imp(name, timerRes, type, this))
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TTimer::~TTimer()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TTimer::start(UINT delay)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->start(delay);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TTimer::isStarted() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->m_started;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TTimer::stop()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->stop();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
std::string TTimer::getName() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->getName();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TUINT64 TTimer::getTicks() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->getTicks();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
UINT TTimer::getDelay() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->getDelay();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TTimer::setAction(TGenericTimerAction *action)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_imp->m_action)
Toshihiro Shimizu 890ddd
		delete m_imp->m_action;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_imp->m_action = action;
Toshihiro Shimizu 890ddd
}