10 /// Stores timing information.
11 /// For use by app::Timer.
15 TimerData() : time(0), target(0), refCount(0), justHit(false), repeat(false) { }
16 TimerData(Time target, bool repeat) : time(0), target(target), refCount(0), justHit(false), repeat(repeat) { }
28 /// How the various information returned by the const member functions is to be
29 /// interpreted highly depends on how the timer was created (by app::Timers).
35 ~Timer() { if (data) --data->refCount; }
36 Timer(TimerData<Time> *data) : data(data) { ++data->refCount; }
37 Timer(const Timer<Time> &other)
38 : data(other.data) { if (data) ++(data->refCount); }
39 Timer<Time> &operator =(const Timer<Time> &other) {
40 Timer<Time> temp(other);
44 void Swap(Timer<Time> &other) {
45 std::swap(data, other.data);
49 /// Check if the timer was started (and not cleared) yet.
50 bool Started() const {
53 /// Check if the timer has reached its target time (only sensible for
54 /// countdown timers).
55 bool Finished() const {
56 return data && data->target != Time() && !data->repeat && data->time >= data->target;
58 /// Check if the timer was started and has not finished yet (in case it's a
60 bool Running() const {
61 return data && !Finished();
63 /// Get the elapsed time since the timer started.
64 Time Elapsed() const {
65 return data ? data->time : Time();
67 /// Get the time remaining for countdowns.
68 Time Remaining() const {
69 return data ? (data->target - data->time) : Time();
71 /// Time from start to hit.
72 Time TargetTime() const {
73 return data ? data->target : Time();
75 /// Get the elapsed time since the timer started or last hit.
76 Time IterationElapsed() const {
77 return data ? data->time % data->target : Time();
79 /// Get the remaining time in this iteration.
80 Time IterationRemaining() const {
81 return TargetTime() - IterationElapsed();
83 /// Get the iteration index for interval timers.
84 int Iteration() const {
85 return (data && data->target > Time()) ? std::floor(data->time / data->target) : Time();
87 /// Check if the timer reached its interval or countdown goal this iteration.
88 bool JustHit() const {
89 return data && data->justHit;
92 /// Unset the timer (does not stop other handles for a shared timer).
99 /// Reset the timer, do not stop it if it's running.
101 if (data) data->time = Time();
103 /// Restart the timer.
104 /// Only works if the timer was started at least once.
107 if (data->target > Time() && data->justHit) {
108 data->time -= data->target;
116 TimerData<Time> *data;
121 /// Tracker for timers, responsible for creating and updating them.
129 /// Move all timers forward by delta.
130 void Update(Time delta) {
131 for (typename std::list<TimerData<Time> >::iterator i(data.begin()), end(data.end()); i != end;) {
133 Time intervalTime(i->time);
134 if (i->repeat) while (intervalTime > i->target) intervalTime -= i->target;
135 i->justHit = intervalTime < i->target && intervalTime + delta >= i->target;
138 if (i->refCount <= 0) {
145 /// Start a timer that counts elapsed time until stopped manually.
146 Timer<Time> StartTimer() {
147 data.push_back(TimerData<Time>());
148 return Timer<Time>(&data.back());
150 /// Start a countdown that hits (JustHit() returing true) when duration
152 Timer<Time> StartCountdown(Time duration) {
153 data.push_back(TimerData<Time>(duration, false));
154 return Timer<Time>(&data.back());
156 /// Start an interval timer that hits (JustHit() returning true) each time
157 /// duration has passed.
158 Timer<Time> StartInterval(Time duration) {
159 data.push_back(TimerData<Time>(duration, true));
160 return Timer<Time>(&data.back());
164 std::list<TimerData<Time> > data;