Classe Timer

4 02 2008

Uma classe indispensável durante a programação de um jogo ou engine, que seja responsável pelas chamadas de métodos em determinado intervalo de tempo durante a execução do aplicativo, que forneça uma maneira passiva e rápida de callbacks, orientada à objetos. Aqui segue um exemplo de tal classe usando o timer da SDL

Declaração da classe Timer

#include "SDL.h"

class Timer
{
   public:
      Timer();

      explicit Timer(Uint32 interval);

      virtual ~Timer();

      // Adcionamos um timer
      // interval O intervalo de tempo do timer
      void addTimer(Uint32 interval);

      // Remove o timer
      void removeTimer();

      // Seta um novo intervalo de tempo
      void setInterval(Uint32 interval);

      // Retorna o valor do intervalo do timer
      Uint32 Timer::getInterval() const;

      //
      // Método puro abstrato chamado em todo
      // intervalo definido pelo timer.
      // Deve ser implementado na classe filha.
      //
      virtual void onTimer() = 0;

   private:
      // Usado internamente, o ponto de entrada do SDL_Timer
      static Uint32 entryPoint(Uint32 interval, void* param);

      Uint32 mInterval;
      SDL_TimerID mTimerID;
};

Vamos à implementação

#include "Timer.h"

Timer::Timer()
: mInterval(0)
{
   if (SDL_WasInit(SDL_INIT_TIMER) == 0)
   {
      SDL_InitSubSystem(SDL_INIT_TIMER);
   }
}

Timer::Timer(Uint32 interval)
: mInterval(0)
{
   if (SDL_WasInit(SDL_INIT_TIMER) == 0)
   {
      SDL_InitSubSystem(SDL_INIT_TIMER);
   }

   addTimer(interval);
}

Timer::~Timer()
{
   SDL_RemoveTimer(mTimerID);
}

void Timer::addTimer(Uint32 interval)
{
   mInterval = interval;
   mTimerID = SDL_AddTimer(mInterval, entryPoint, this);
}

void Timer::removeTimer()
{
   SDL_RemoveTimer(mTimerID);
}

void Timer::setInterval(Uint32 interval)
{
   mInterval = interval;
}

Uint32 Timer::getInterval() const
{
   return mInterval;
}

Uint32 Timer::entryPoint(Uint32 interval, void* param)
{
   Timer* ptr = reinterpret_cast<Timer*>(param);
   ptr->onTimer();
   return ptr->mInterval;
}

Exemplo de uso:

#include <iostream>
#include <boost/scoped_ptr.hpp>

#include "SDL.h"
#include "Timer.h"

using std::cout;
using std::endl;
using boost::scoped_ptr;

class Tick : public Timer
{
   public:
      Tick()
      {
         // Adicionamos um timer de 1 Segundo
         addTimer(1000);
      }

      ~Tick() { }

   protected:

      // onTImer método puro abstrato
      // herdado de Timer, ele será chamado
      // todo intervalo definido no timer
      void onTimer()
      {
         cout << "Tick::onTimer() chamado em " << SDL_GetTick() << endl;
      }
};

int main()
{
   // Criamos a classe Tick
   // usamos aqui scoped_ptr para
   // que o ponteiro seja deletado
   // automaticamente ao sair do escopo
   scoped_ptr<Tick> tick(new Tick);

   // Aguardamos uns 5 segundos
   // enquanto isso o timer já esta rodando
   // e imprimindo a saida no console ou no stdout.txt
   SDL_Delay(5000);

   // Agora vamos mudar o intervalo de tempo
   // para meio segundo
   tick->setInterval(500);

   // Aguardamos mais ums 5 segundos
   // O timer continua rodando, mais agora com o
   // intervalo de meio segundo e não 1 segundo
   SDL_Delay(5000);

   // O resultado poderá ser visto no stdout.txt
   // ou na saida do console

   // Isso mantem o compilador feliz...
   return 0;
}

Espero que tenha gostado, em breve eu posto as classes Thread, ThreadJob, ThreadGroup e Mutex baseadas nas Threads da SDL (até la vou ter aprendido mais sobre SDL semáforos), sintan-se à vontade de usá-las apenas mantenham os créditos ;D


Ações

Informações

Uma resposta

8 02 2008
Diogo_RBG

Acho que essa deve ser a classe Timer do Witermoon Framework.
Estou à procura de como criar a minha e isto irá me ajudar muito, vlw !

Deixe um comentário