]> git.localhorst.tv Git - l2e.git/blobdiff - src/app/Timer.h
added getters for interval timer information
[l2e.git] / src / app / Timer.h
index 465ed64e45edc14a13faa7f462b70e35275e83a1..d744fe09966cc203e76982695a1824e05946ed14 100644 (file)
@@ -1,31 +1,32 @@
-/*
- * Timer.h
- *
- *  Created on: Aug 10, 2012
- *      Author: holy
- */
-
 #ifndef APP_TIMER_H_
 #define APP_TIMER_H_
 
 #include <algorithm>
 #include <list>
+#include <cmath>
 
 namespace app {
 
+/// Stores timing information.
+/// For use by app::Timer.
 template<class Time>
 struct TimerData {
 
-       TimerData() : time(0), target(0), refCount(0) { }
-       TimerData(Time target) : time(0), target(target), refCount(0) { }
+       TimerData() : time(0), target(0), refCount(0), justHit(false), repeat(false) { }
+       TimerData(Time target, bool repeat) : time(0), target(target), refCount(0), justHit(false), repeat(repeat) { }
 
        Time time;
        Time target;
        int refCount;
+       bool justHit;
+       bool repeat;
 
 };
 
 
+/// Timer handle.
+/// How the various information returned by the const member functions is to be
+/// interpreted highly depends on how the timer was created (by app::Timers).
 template<class Time>
 class Timer {
 
@@ -45,18 +46,71 @@ public:
        }
 
 public:
-       bool Running() const {
+       /// Check if the timer was started (and not cleared) yet.
+       bool Started() const {
                return data;
        }
+       /// Check if the timer has reached its target time (only sensible for
+       /// countdown timers).
        bool Finished() const {
-               return data ? data->time >= data->target : false;
+               return data && data->target != Time() && !data->repeat && data->time >= data->target;
        }
+       /// Check if the timer was started and has not finished yet (in case it's a
+       /// countdown).
+       bool Running() const {
+               return data && !Finished();
+       }
+       /// Get the elapsed time since the timer started.
        Time Elapsed() const {
                return data ? data->time : Time();
        }
+       /// Get the time remaining for countdowns.
        Time Remaining() const {
                return data ? (data->target - data->time) : Time();
        }
+       /// Time from start to hit.
+       Time TargetTime() const {
+               return data ? data->target : Time();
+       }
+       /// Get the elapsed time since the timer started or last hit.
+       Time IterationElapsed() const {
+               return data ? data->time % data->target : Time();
+       }
+       /// Get the remaining time in this iteration.
+       Time IterationRemaining() const {
+               return TargetTime() - IterationElapsed();
+       }
+       /// Get the iteration index for interval timers.
+       int Iteration() const {
+               return (data && data->target > Time()) ? std::floor(data->time / data->target) : Time();
+       }
+       /// Check if the timer reached its interval or countdown goal this iteration.
+       bool JustHit() const {
+               return data && data->justHit;
+       }
+
+       /// Unset the timer (does not stop other handles for a shared timer).
+       void Clear() {
+               if (data) {
+                       --data->refCount;
+                       data = 0;
+               }
+       }
+       /// Reset the timer, do not stop it if it's running.
+       void Reset() {
+               if (data) data->time = Time();
+       }
+       /// Restart the timer.
+       /// Only works if the timer was started at least once.
+       void Restart() {
+               if (data) {
+                       if (data->target > Time() && data->justHit) {
+                               data->time -= data->target;
+                       } else {
+                               data->time = Time();
+                       }
+               }
+       }
 
 private:
        TimerData<Time> *data;
@@ -64,6 +118,7 @@ private:
 };
 
 
+/// Tracker for timers, responsible for creating and updating them.
 template<class Time>
 class Timers {
 
@@ -71,8 +126,14 @@ public:
        Timers() { }
 
 public:
+       /// Move all timers forward by delta.
        void Update(Time delta) {
                for (typename std::list<TimerData<Time> >::iterator i(data.begin()), end(data.end()); i != end;) {
+                       if (i->target > 0) {
+                               Time intervalTime(i->time);
+                               if (i->repeat) while (intervalTime > i->target) intervalTime -= i->target;
+                               i->justHit = intervalTime < i->target && intervalTime + delta >= i->target;
+                       }
                        i->time += delta;
                        if (i->refCount <= 0) {
                                i = data.erase(i);
@@ -81,12 +142,21 @@ public:
                        }
                }
        }
+       /// Start a timer that counts elapsed time until stopped manually.
        Timer<Time> StartTimer() {
                data.push_back(TimerData<Time>());
                return Timer<Time>(&data.back());
        }
+       /// Start a countdown that hits (JustHit() returing true) when duration
+       /// elapsed.
        Timer<Time> StartCountdown(Time duration) {
-               data.push_back(TimerData<Time>(duration));
+               data.push_back(TimerData<Time>(duration, false));
+               return Timer<Time>(&data.back());
+       }
+       /// Start an interval timer that hits (JustHit() returning true) each time
+       /// duration has passed.
+       Timer<Time> StartInterval(Time duration) {
+               data.push_back(TimerData<Time>(duration, true));
                return Timer<Time>(&data.back());
        }
 
@@ -97,4 +167,4 @@ private:
 
 }
 
-#endif /* APP_TIMER_H_ */
+#endif