]> git.localhorst.tv Git - l2e.git/blob - src/app/Timer.h
added hit tracking to timers
[l2e.git] / src / app / Timer.h
1 /*
2  * Timer.h
3  *
4  *  Created on: Aug 10, 2012
5  *      Author: holy
6  */
7
8 #ifndef APP_TIMER_H_
9 #define APP_TIMER_H_
10
11 #include <algorithm>
12 #include <list>
13 #include <cmath>
14
15 namespace app {
16
17 template<class Time>
18 struct TimerData {
19
20         TimerData() : time(0), target(0), refCount(0), justHit(false) { }
21         TimerData(Time target) : time(0), target(target), refCount(0), justHit(false) { }
22
23         Time time;
24         Time target;
25         int refCount;
26         bool justHit;
27
28 };
29
30
31 template<class Time>
32 class Timer {
33
34 public:
35         Timer() : data(0) { }
36         ~Timer() { if (data) --data->refCount; }
37         Timer(TimerData<Time> *data) : data(data) { ++data->refCount; }
38         Timer(const Timer<Time> &other)
39         : data(other.data) { if (data) ++(data->refCount); }
40         Timer<Time> &operator =(const Timer<Time> &other) {
41                 Timer<Time> temp(other);
42                 Swap(temp);
43                 return *this;
44         }
45         void Swap(Timer<Time> &other) {
46                 std::swap(data, other.data);
47         }
48
49 public:
50         bool Running() const {
51                 return data;
52         }
53         bool Finished() const {
54                 return data ? data->time >= data->target : false;
55         }
56         Time Elapsed() const {
57                 return data ? data->time : Time();
58         }
59         Time Remaining() const {
60                 return data ? (data->target - data->time) : Time();
61         }
62         int Iteration() const {
63                 return (data && data->target > 0) ? std::floor(data->time / data->target) : 0;
64         }
65         bool JustHit() const {
66                 return data && data->justHit;
67         }
68
69         void Reset() {
70                 if (data) data->time = 0;
71         }
72         void Restart() {
73                 if (data) {
74                         if (data->target > 0 && data->justHit) {
75                                 data->time -= data->target;
76                         } else {
77                                 data->time = 0;
78                         }
79                 }
80         }
81
82 private:
83         TimerData<Time> *data;
84
85 };
86
87
88 template<class Time>
89 class Timers {
90
91 public:
92         Timers() { }
93
94 public:
95         void Update(Time delta) {
96                 for (typename std::list<TimerData<Time> >::iterator i(data.begin()), end(data.end()); i != end;) {
97                         if (i->target > 0) {
98                                 Time intervalTime(i->time);
99                                 while (intervalTime > i->target) intervalTime -= i->target;
100                                 i->justHit = intervalTime < i->target && intervalTime + delta >= i->target;
101                         }
102                         i->time += delta;
103                         if (i->refCount <= 0) {
104                                 i = data.erase(i);
105                         } else {
106                                 ++i;
107                         }
108                 }
109         }
110         Timer<Time> StartTimer() {
111                 data.push_back(TimerData<Time>());
112                 return Timer<Time>(&data.back());
113         }
114         Timer<Time> StartCountdown(Time duration) {
115                 data.push_back(TimerData<Time>(duration));
116                 return Timer<Time>(&data.back());
117         }
118
119 private:
120         std::list<TimerData<Time> > data;
121
122 };
123
124 }
125
126 #endif /* APP_TIMER_H_ */