2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
|
|
|
|
#include "ttimer.h"
|
2016-04-24 18:28:19 +12:00
|
|
|
#include "tthreadmessage.h"
|
2016-03-19 06:57:51 +13:00
|
|
|
#include "texception.h"
|
|
|
|
|
2016-04-15 17:11:23 +12:00
|
|
|
#ifdef _WIN32
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
#include <windows.h>
|
2016-05-13 22:49:17 +12:00
|
|
|
#include <mmsystem.h>
|
|
|
|
#include <cstdlib>
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// moto strano: se togliamo l'include della glut non linka
|
2016-03-19 06:57:51 +13:00
|
|
|
#include <GL/glut.h>
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
namespace {
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
void CALLBACK ElapsedTimeCB(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1,
|
|
|
|
DWORD dw2);
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
class TTimer::Imp {
|
2016-03-19 06:57:51 +13:00
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
Imp(std::string name, UINT timerRes, TTimer::Type type, TTimer *timer);
|
|
|
|
~Imp();
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
void start(UINT delay) {
|
|
|
|
if (m_started) throw TException("The timer is already started");
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
m_timerID = timeSetEvent(delay, m_timerRes, (LPTIMECALLBACK)ElapsedTimeCB,
|
|
|
|
(DWORD)this, m_type | TIME_CALLBACK_FUNCTION);
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
m_delay = delay;
|
|
|
|
m_ticks = 0;
|
|
|
|
if (m_timerID == NULL) throw TException("Unable to start timer");
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
m_started = true;
|
|
|
|
}
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
void stop() {
|
|
|
|
if (m_started) timeKillEvent(m_timerID);
|
|
|
|
m_started = false;
|
|
|
|
}
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
std::string getName() { return m_name; }
|
|
|
|
TUINT64 getTicks() { return m_ticks; }
|
|
|
|
UINT getDelay() { return m_delay; }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
std::string m_name;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
UINT m_timerRes;
|
|
|
|
UINT m_type;
|
|
|
|
TTimer *m_timer;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
UINT m_timerID;
|
|
|
|
UINT m_delay;
|
|
|
|
TUINT64 m_ticks;
|
|
|
|
bool m_started;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
TGenericTimerAction *m_action;
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
TTimer::Imp::Imp(std::string name, UINT timerRes, TTimer::Type type,
|
|
|
|
TTimer *timer)
|
|
|
|
: 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) {
|
|
|
|
TIMECAPS tc;
|
|
|
|
|
|
|
|
if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) {
|
|
|
|
throw TException("Unable to create timer");
|
|
|
|
}
|
|
|
|
|
|
|
|
m_timerRes = std::min((int)std::max((int)tc.wPeriodMin, (int)m_timerRes),
|
|
|
|
(int)tc.wPeriodMax);
|
|
|
|
timeBeginPeriod(m_timerRes);
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case TTimer::OneShot:
|
|
|
|
m_type = TIME_ONESHOT;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TTimer::Periodic:
|
|
|
|
m_type = TIME_PERIODIC;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
throw TException("Unexpected timer type");
|
|
|
|
break;
|
|
|
|
}
|
2016-03-19 06:57:51 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
TTimer::Imp::~Imp() {
|
|
|
|
stop();
|
|
|
|
timeEndPeriod(m_timerRes);
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
if (m_action) delete m_action;
|
2016-03-19 06:57:51 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
void CALLBACK ElapsedTimeCB(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1,
|
|
|
|
DWORD dw2) {
|
|
|
|
TTimer::Imp *imp = reinterpret_cast<TTimer::Imp *>(dwUser);
|
|
|
|
imp->m_ticks++;
|
|
|
|
if (imp->m_action) imp->m_action->sendCommand(imp->m_ticks);
|
2016-03-19 06:57:51 +13:00
|
|
|
}
|
|
|
|
};
|
|
|
|
#elif LINUX
|
|
|
|
|
2016-06-30 20:55:55 +12:00
|
|
|
#include <SDL_timer.h>
|
|
|
|
#include <SDL.h>
|
2016-03-19 06:57:51 +13:00
|
|
|
#include "tthread.h"
|
2016-06-15 18:43:10 +12:00
|
|
|
namespace {
|
2016-03-19 06:57:51 +13:00
|
|
|
Uint32 ElapsedTimeCB(Uint32 interval, void *param);
|
|
|
|
}
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
class TTimer::Imp {
|
2016-03-19 06:57:51 +13:00
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
Imp(std::string name, UINT timerRes, TTimer::Type type, TTimer *timer)
|
|
|
|
: m_action(0), m_ticks(0) {}
|
|
|
|
~Imp() {}
|
|
|
|
|
|
|
|
void start(UINT delay) {
|
|
|
|
static bool first = true;
|
|
|
|
if (first) {
|
|
|
|
SDL_Init(SDL_INIT_TIMER);
|
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
m_timerID = SDL_AddTimer(delay, ElapsedTimeCB, this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void stop() { SDL_RemoveTimer(m_timerID); }
|
|
|
|
|
|
|
|
std::string getName() { return m_name; }
|
|
|
|
TUINT64 getTicks() { return m_ticks; }
|
|
|
|
UINT getDelay() { return m_delay; }
|
|
|
|
|
|
|
|
std::string m_name;
|
|
|
|
|
|
|
|
UINT m_timerRes;
|
|
|
|
UINT m_type;
|
|
|
|
TTimer *m_timer;
|
|
|
|
|
|
|
|
SDL_TimerID m_timerID;
|
|
|
|
UINT m_delay;
|
|
|
|
TUINT64 m_ticks;
|
|
|
|
bool m_started;
|
|
|
|
|
|
|
|
TGenericTimerAction *m_action;
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
2016-06-29 18:17:12 +12:00
|
|
|
class SendCommandMSG final : public TThread::Message {
|
2016-06-15 18:43:10 +12:00
|
|
|
TTimer::Imp *m_ztimp;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
SendCommandMSG(TTimer::Imp *ztimp) : TThread::Message(), m_ztimp(ztimp) {}
|
|
|
|
~SendCommandMSG() {}
|
|
|
|
TThread::Message *clone() const { return new SendCommandMSG(*this); }
|
|
|
|
void onDeliver() {
|
|
|
|
if (m_ztimp->m_action) m_ztimp->m_action->sendCommand(m_ztimp->m_ticks);
|
|
|
|
}
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
namespace {
|
|
|
|
Uint32 ElapsedTimeCB(Uint32 interval, void *param) {
|
|
|
|
TTimer::Imp *imp = reinterpret_cast<TTimer::Imp *>(param);
|
|
|
|
imp->m_ticks++;
|
|
|
|
SendCommandMSG(imp).send();
|
|
|
|
return interval;
|
2016-03-19 06:57:51 +13:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-30 14:21:07 +12:00
|
|
|
#elif defined(__sgi)
|
2016-06-15 18:43:10 +12:00
|
|
|
class TTimer::Imp {
|
2016-03-19 06:57:51 +13:00
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
Imp(std::string name, UINT timerRes, TTimer::Type type, TTimer *timer)
|
|
|
|
: m_action(0) {}
|
|
|
|
~Imp() {}
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
void start(UINT delay) {
|
|
|
|
if (m_started) throw TException("The timer is already started");
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
m_started = true;
|
|
|
|
}
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
void stop() { m_started = false; }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
std::string getName() { return m_name; }
|
|
|
|
TUINT64 getTicks() { return m_ticks; }
|
|
|
|
UINT getDelay() { return m_delay; }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
std::string m_name;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
UINT m_timerRes;
|
|
|
|
UINT m_type;
|
|
|
|
TTimer *m_timer;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
UINT m_timerID;
|
|
|
|
UINT m_delay;
|
|
|
|
TUINT64 m_ticks;
|
|
|
|
bool m_started;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
TGenericTimerAction *m_action;
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
2016-06-30 14:21:07 +12:00
|
|
|
#elif defined(MACOSX)
|
2016-06-15 18:43:10 +12:00
|
|
|
class TTimer::Imp {
|
2016-03-19 06:57:51 +13:00
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
Imp(std::string name, UINT timerRes, TTimer::Type type, TTimer *timer)
|
|
|
|
: m_action(0) {}
|
|
|
|
~Imp() {}
|
|
|
|
|
|
|
|
void start(UINT delay) {
|
|
|
|
if (m_started) throw TException("The timer is already started");
|
|
|
|
throw TException("The timer is not yet available under MAC :(");
|
|
|
|
m_started = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void stop() { m_started = false; }
|
|
|
|
|
|
|
|
std::string getName() { return m_name; }
|
|
|
|
TUINT64 getTicks() { return m_ticks; }
|
|
|
|
UINT getDelay() { return m_delay; }
|
|
|
|
|
|
|
|
std::string m_name;
|
|
|
|
|
|
|
|
UINT m_timerRes;
|
|
|
|
UINT m_type;
|
|
|
|
TTimer *m_timer;
|
|
|
|
|
|
|
|
UINT m_timerID;
|
|
|
|
UINT m_delay;
|
|
|
|
TUINT64 m_ticks;
|
|
|
|
bool m_started;
|
|
|
|
|
|
|
|
TGenericTimerAction *m_action;
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//===============================================================================
|
|
|
|
//
|
|
|
|
// TTimer
|
|
|
|
//
|
|
|
|
//===============================================================================
|
|
|
|
|
2016-04-19 19:32:17 +12:00
|
|
|
TTimer::TTimer(const std::string &name, UINT timerRes, Type type)
|
2016-06-15 18:43:10 +12:00
|
|
|
: m_imp(new TTimer::Imp(name, timerRes, type, this)) {}
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
TTimer::~TTimer() {}
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
void TTimer::start(UINT delay) { m_imp->start(delay); }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
bool TTimer::isStarted() const { return m_imp->m_started; }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
void TTimer::stop() { m_imp->stop(); }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
std::string TTimer::getName() const { return m_imp->getName(); }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
TUINT64 TTimer::getTicks() const { return m_imp->getTicks(); }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
UINT TTimer::getDelay() const { return m_imp->getDelay(); }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
void TTimer::setAction(TGenericTimerAction *action) {
|
|
|
|
if (m_imp->m_action) delete m_imp->m_action;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
m_imp->m_action = action;
|
2016-03-19 06:57:51 +13:00
|
|
|
}
|