void Application::Loop() {
Uint32 now(SDL_GetTicks());
Uint32 deltaT(now - last);
+ GlobalTimers().Update(deltaT);
if (deltaT > 34) deltaT = 34;
+ if (CurrentState()) {
+ CurrentState()->GraphicsTimers().Update(deltaT);
+ }
HandleEvents();
if (!StateChangePending()) {
UpdateWorld(deltaT);
void Application::UpdateWorld(Uint32 deltaT) {
if (!CurrentState()) return;
for (Uint32 i(0); i < deltaT; ++i) {
+ CurrentState()->PhysicsTimers().Update(0.001f);
CurrentState()->UpdateWorld(0.001f);
}
}
#define APP_APPLICATION_H_
#include "Input.h"
+#include "Timer.h"
#include "../sdl/InitScreen.h"
#include <stack>
void Quit();
Input &Buttons() { return input; }
const Input &Buttons() const { return input; }
+ Timers<Uint32> &GlobalTimers() { return globalTimers; }
private:
struct StateCommand {
sdl::InitScreen *screen;
std::stack<State *> states;
std::queue<StateCommand> stateChanges;
+ Timers<Uint32> globalTimers;
Input input;
Uint32 last;
#ifndef APP_APPLICATIONSTATE_H_
#define APP_APPLICATIONSTATE_H_
+#include "Timer.h"
+
#include <SDL.h>
namespace app {
virtual void UpdateWorld(float deltaT) = 0;
virtual void Render(SDL_Surface *) = 0;
+public:
+ Timers<Uint32> &GraphicsTimers() { return graphicsTimers; }
+ Timers<float> &PhysicsTimers() { return physicsTimers; }
+
+private:
+ Timers<Uint32> graphicsTimers;
+ Timers<float> physicsTimers;
+
};
}
--- /dev/null
+/*
+ * Timer.h
+ *
+ * Created on: Aug 10, 2012
+ * Author: holy
+ */
+
+#ifndef APP_TIMER_H_
+#define APP_TIMER_H_
+
+#include <algorithm>
+#include <list>
+
+namespace app {
+
+template<class Time>
+struct TimerData {
+
+ TimerData() : time(0), target(0), refCount(0) { }
+ TimerData(Time target) : time(0), target(target), refCount(0) { }
+
+ Time time;
+ Time target;
+ int refCount;
+
+};
+
+
+template<class Time>
+class Timer {
+
+public:
+ Timer() : data(0) { }
+ ~Timer() { if (data) --data->refCount; }
+ Timer(TimerData<Time> *data) : data(data) { ++data->refCount; }
+ Timer(const Timer<Time> &other)
+ : data(other.data) { if (data) ++(data->refCount); }
+ Timer<Time> &operator =(const Timer<Time> &other) {
+ Timer<Time> temp(other);
+ Swap(temp);
+ return *this;
+ }
+ void Swap(Timer<Time> &other) {
+ std::swap(data, other.data);
+ }
+
+public:
+ bool Running() const {
+ return data;
+ }
+ bool Finished() const {
+ return data ? data->time >= data->target : false;
+ }
+ Time Elapsed() const {
+ return data ? data->time : Time();
+ }
+ Time Remaining() const {
+ return data ? (data->target - data->time) : Time();
+ }
+
+private:
+ TimerData<Time> *data;
+
+};
+
+
+template<class Time>
+class Timers {
+
+public:
+ Timers() { }
+
+public:
+ void Update(Time delta) {
+ for (typename std::list<TimerData<Time> >::iterator i(data.begin()), end(data.end()); i != end;) {
+ i->time += delta;
+ if (i->refCount <= 0) {
+ i = data.erase(i);
+ } else {
+ ++i;
+ }
+ }
+ }
+ Timer<Time> StartTimer() {
+ data.push_back(TimerData<Time>());
+ return Timer<Time>(&data.back());
+ }
+ Timer<Time> StartCountdown(Time duration) {
+ data.push_back(TimerData<Time>(duration));
+ return Timer<Time>(&data.back());
+ }
+
+private:
+ std::list<TimerData<Time> > data;
+
+};
+
+}
+
+#endif /* APP_TIMER_H_ */