Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "ttimer.h"
Campbell Barton 3191db
#include "tthreadmessage.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>
Shinya Kitaoka d4642c
#include <mmsystem.h></mmsystem.h>
Shinya Kitaoka d4642c
#include <cstdlib></cstdlib>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// 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
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void CALLBACK ElapsedTimeCB(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1,
Shinya Kitaoka 120a6e
                            DWORD dw2);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TTimer::Imp {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  Imp(std::string name, UINT timerRes, TTimer::Type type, TTimer *timer);
Shinya Kitaoka 120a6e
  ~Imp();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void start(UINT delay) {
Shinya Kitaoka 120a6e
    if (m_started) throw TException("The timer is already started");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_timerID = timeSetEvent(delay, m_timerRes, (LPTIMECALLBACK)ElapsedTimeCB,
Shinya Kitaoka 120a6e
                             (DWORD)this, m_type | TIME_CALLBACK_FUNCTION);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_delay = delay;
Shinya Kitaoka 120a6e
    m_ticks = 0;
Shinya Kitaoka 120a6e
    if (m_timerID == NULL) throw TException("Unable to start timer");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_started = true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void stop() {
Shinya Kitaoka 120a6e
    if (m_started) timeKillEvent(m_timerID);
Shinya Kitaoka 120a6e
    m_started = false;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::string getName() { return m_name; }
Shinya Kitaoka 120a6e
  TUINT64 getTicks() { return m_ticks; }
Shinya Kitaoka 120a6e
  UINT getDelay() { return m_delay; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::string m_name;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UINT m_timerRes;
Shinya Kitaoka 120a6e
  UINT m_type;
Shinya Kitaoka 120a6e
  TTimer *m_timer;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UINT m_timerID;
Shinya Kitaoka 120a6e
  UINT m_delay;
Shinya Kitaoka 120a6e
  TUINT64 m_ticks;
Shinya Kitaoka 120a6e
  bool m_started;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TGenericTimerAction *m_action;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TTimer::Imp::Imp(std::string name, UINT timerRes, TTimer::Type type,
Shinya Kitaoka 120a6e
                 TTimer *timer)
Shinya Kitaoka 120a6e
    : m_name(name)
Shinya Kitaoka 120a6e
    , m_timerRes(timerRes)
Shinya Kitaoka 120a6e
    , m_timer(timer)
Shinya Kitaoka 120a6e
    , m_type(type)
Shinya Kitaoka 120a6e
    , m_timerID(NULL)
Shinya Kitaoka 120a6e
    , m_ticks(0)
Shinya Kitaoka 120a6e
    , m_delay(0)
Shinya Kitaoka 120a6e
    , m_started(false)
Shinya Kitaoka 120a6e
    , m_action(0) {
Shinya Kitaoka 120a6e
  TIMECAPS tc;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) {
Shinya Kitaoka 120a6e
    throw TException("Unable to create timer");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_timerRes = std::min((int)std::max((int)tc.wPeriodMin, (int)m_timerRes),
Shinya Kitaoka 120a6e
                        (int)tc.wPeriodMax);
Shinya Kitaoka 120a6e
  timeBeginPeriod(m_timerRes);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (type) {
Shinya Kitaoka 120a6e
  case TTimer::OneShot:
Shinya Kitaoka 120a6e
    m_type = TIME_ONESHOT;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TTimer::Periodic:
Shinya Kitaoka 120a6e
    m_type = TIME_PERIODIC;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    throw TException("Unexpected timer type");
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TTimer::Imp::~Imp() {
Shinya Kitaoka 120a6e
  stop();
Shinya Kitaoka 120a6e
  timeEndPeriod(m_timerRes);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_action) delete m_action;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void CALLBACK ElapsedTimeCB(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1,
Shinya Kitaoka 120a6e
                            DWORD dw2) {
Shinya Kitaoka 120a6e
  TTimer::Imp *imp = reinterpret_cast<ttimer::imp *="">(dwUser);</ttimer::imp>
Shinya Kitaoka 120a6e
  imp->m_ticks++;
Shinya Kitaoka 120a6e
  if (imp->m_action) 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"
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Uint32 ElapsedTimeCB(Uint32 interval, void *param);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TTimer::Imp {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  Imp(std::string name, UINT timerRes, TTimer::Type type, TTimer *timer)
Shinya Kitaoka 120a6e
      : m_action(0), m_ticks(0) {}
Shinya Kitaoka 120a6e
  ~Imp() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void start(UINT delay) {
Shinya Kitaoka 120a6e
    static bool first = true;
Shinya Kitaoka 120a6e
    if (first) {
Shinya Kitaoka 120a6e
      SDL_Init(SDL_INIT_TIMER);
Shinya Kitaoka 120a6e
      first = false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    m_timerID = SDL_AddTimer(delay, ElapsedTimeCB, this);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void stop() { SDL_RemoveTimer(m_timerID); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string getName() { return m_name; }
Shinya Kitaoka 120a6e
  TUINT64 getTicks() { return m_ticks; }
Shinya Kitaoka 120a6e
  UINT getDelay() { return m_delay; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string m_name;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UINT m_timerRes;
Shinya Kitaoka 120a6e
  UINT m_type;
Shinya Kitaoka 120a6e
  TTimer *m_timer;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  SDL_TimerID m_timerID;
Shinya Kitaoka 120a6e
  UINT m_delay;
Shinya Kitaoka 120a6e
  TUINT64 m_ticks;
Shinya Kitaoka 120a6e
  bool m_started;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TGenericTimerAction *m_action;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class SendCommandMSG : public TThread::Message {
Shinya Kitaoka 120a6e
  TTimer::Imp *m_ztimp;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  SendCommandMSG(TTimer::Imp *ztimp) : TThread::Message(), m_ztimp(ztimp) {}
Shinya Kitaoka 120a6e
  ~SendCommandMSG() {}
Shinya Kitaoka 120a6e
  TThread::Message *clone() const { return new SendCommandMSG(*this); }
Shinya Kitaoka 120a6e
  void onDeliver() {
Shinya Kitaoka 120a6e
    if (m_ztimp->m_action) m_ztimp->m_action->sendCommand(m_ztimp->m_ticks);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
Uint32 ElapsedTimeCB(Uint32 interval, void *param) {
Shinya Kitaoka 120a6e
  TTimer::Imp *imp = reinterpret_cast<ttimer::imp *="">(param);</ttimer::imp>
Shinya Kitaoka 120a6e
  imp->m_ticks++;
Shinya Kitaoka 120a6e
  SendCommandMSG(imp).send();
Shinya Kitaoka 120a6e
  return interval;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#elif __sgi
Shinya Kitaoka 120a6e
class TTimer::Imp {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  Imp(std::string name, UINT timerRes, TTimer::Type type, TTimer *timer)
Shinya Kitaoka 120a6e
      : m_action(0) {}
Shinya Kitaoka 120a6e
  ~Imp() {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void start(UINT delay) {
Shinya Kitaoka 120a6e
    if (m_started) throw TException("The timer is already started");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_started = true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void stop() { m_started = false; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::string getName() { return m_name; }
Shinya Kitaoka 120a6e
  TUINT64 getTicks() { return m_ticks; }
Shinya Kitaoka 120a6e
  UINT getDelay() { return m_delay; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::string m_name;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UINT m_timerRes;
Shinya Kitaoka 120a6e
  UINT m_type;
Shinya Kitaoka 120a6e
  TTimer *m_timer;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UINT m_timerID;
Shinya Kitaoka 120a6e
  UINT m_delay;
Shinya Kitaoka 120a6e
  TUINT64 m_ticks;
Shinya Kitaoka 120a6e
  bool m_started;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TGenericTimerAction *m_action;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
#elif MACOSX
Shinya Kitaoka 120a6e
class TTimer::Imp {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  Imp(std::string name, UINT timerRes, TTimer::Type type, TTimer *timer)
Shinya Kitaoka 120a6e
      : m_action(0) {}
Shinya Kitaoka 120a6e
  ~Imp() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void start(UINT delay) {
Shinya Kitaoka 120a6e
    if (m_started) throw TException("The timer is already started");
Shinya Kitaoka 120a6e
    throw TException("The timer is not yet available under MAC :(");
Shinya Kitaoka 120a6e
    m_started = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void stop() { m_started = false; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string getName() { return m_name; }
Shinya Kitaoka 120a6e
  TUINT64 getTicks() { return m_ticks; }
Shinya Kitaoka 120a6e
  UINT getDelay() { return m_delay; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string m_name;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UINT m_timerRes;
Shinya Kitaoka 120a6e
  UINT m_type;
Shinya Kitaoka 120a6e
  TTimer *m_timer;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UINT m_timerID;
Shinya Kitaoka 120a6e
  UINT m_delay;
Shinya Kitaoka 120a6e
  TUINT64 m_ticks;
Shinya Kitaoka 120a6e
  bool m_started;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  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 120a6e
    : m_imp(new TTimer::Imp(name, timerRes, type, this)) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TTimer::~TTimer() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTimer::start(UINT delay) { m_imp->start(delay); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TTimer::isStarted() const { return m_imp->m_started; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTimer::stop() { m_imp->stop(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
std::string TTimer::getName() const { return m_imp->getName(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TUINT64 TTimer::getTicks() const { return m_imp->getTicks(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UINT TTimer::getDelay() const { return m_imp->getDelay(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TTimer::setAction(TGenericTimerAction *action) {
Shinya Kitaoka 120a6e
  if (m_imp->m_action) delete m_imp->m_action;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->m_action = action;
Toshihiro Shimizu 890ddd
}