]> git.localhorst.tv Git - l2e.git/blob - src/app/Timer.h
added clear timer function
[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 Clear() {
70                 if (data) {
71                         --data->refCount;
72                         data = 0;
73                 }
74         }
75         void Reset() {
76                 if (data) data->time = 0;
77         }
78         void Restart() {
79                 if (data) {
80                         if (data->target > 0 && data->justHit) {
81                                 data->time -= data->target;
82                         } else {
83                                 data->time = 0;
84                         }
85                 }
86         }
87
88 private:
89         TimerData<Time> *data;
90
91 };
92
93
94 template<class Time>
95 class Timers {
96
97 public:
98         Timers() { }
99
100 public:
101         void Update(Time delta) {
102                 for (typename std::list<TimerData<Time> >::iterator i(data.begin()), end(data.end()); i != end;) {
103                         if (i->target > 0) {
104                                 Time intervalTime(i->time);
105                                 while (intervalTime > i->target) intervalTime -= i->target;
106                                 i->justHit = intervalTime < i->target && intervalTime + delta >= i->target;
107                         }
108                         i->time += delta;
109                         if (i->refCount <= 0) {
110                                 i = data.erase(i);
111                         } else {
112                                 ++i;
113                         }
114                 }
115         }
116         Timer<Time> StartTimer() {
117                 data.push_back(TimerData<Time>());
118                 return Timer<Time>(&data.back());
119         }
120         Timer<Time> StartCountdown(Time duration) {
121                 data.push_back(TimerData<Time>(duration));
122                 return Timer<Time>(&data.back());
123         }
124         Timer<Time> StartInterval(Time duration) {
125                 data.push_back(TimerData<Time>(duration));
126                 return Timer<Time>(&data.back());
127         }
128
129 private:
130         std::list<TimerData<Time> > data;
131
132 };
133
134 }
135
136 #endif /* APP_TIMER_H_ */