prep for runloop code
[chaz/yoink] / src / moof / timer.hh
index d7a411bc48e82089891795db5602d2cfb42e4326..3ec4ef9d8e04bd23a1e6141d4c242e430f6d0d5e 100644 (file)
  * Functions for measuring time in a friendly unit.
  */
 
-#include <map>
-
 #include <boost/bind.hpp>
 #include <boost/function.hpp>
+#include <boost/noncopyable.hpp>
 
+#include <moof/hash.hh>
 #include <moof/math.hh>
 
 
 namespace moof {
 
 
-class timer
+/**
+ * A class to represent a timer for scheduled events.  The timer events
+ * will be executed on or sometime after their schedculed time.  The
+ * runloop associated with the current running view will make an attempt to
+ * fire any expired timers as close to their scheduled times as possible.
+ */
+class timer : public boost::noncopyable
 {
 public:
 
+       /**
+        * A type for the state of a timer.
+        */
        enum mode
        {
-               invalid         = -1,
-               normal          =  0,
-               absolute        =  1,
-               repeat          =  2
+               invalid         = -1,   /// Timer is not scheduled.
+               relative        =  0,   /// Timer is scheduled by a relative time.
+               absolute        =  1,   /// Timer is scheduled by an absolute time.
+               repeat          =  2    /// Timer is scheduled by a periodic time.
        };
 
+       /**
+        * Function protocol for a timer event handler.  A function matching
+        * this protocol will be called when the timer expires.  The function
+        * takes two parameters: the timer object that just expired, and the
+        * absolute time.
+        */
        typedef boost::function<void(timer&,scalar)> function;
 
 
+       /**
+        * Construct an invalid (uninitialized) timer.
+        */
        timer() :
-               mode_(invalid) {}
+               mode_(invalid),
+               absolute_(SCALAR(0.0)) {}
 
-       timer(const function& function, scalar seconds, mode mode = normal)
+       /**
+        * Construct a scheduled timer.
+        * \param function The event handler.
+        * \param seconds The number of seconds; the meaning of this depends on
+        * the mode of the timer.
+        * \param mode The timer mode.  If the mode is relative (default), the
+        * seconds parameter is the number of seconds from the current time to
+        * wait before expiring the timer.  If the mode is absolute, the
+        * seconds parameter is the number of seconds from some arbitrary,
+        * fixed time in the past.  If the mode is repeat, the seconds
+        * parameter is the number of seconds from now to wait before expiring
+        * the timer, at which time the timer will be rescheduled to expired
+        * again at that many seconds from the expiration time.  A repeating
+        * timer can be invalidated manually using invalidate().
+        */
+       timer(const function& function, scalar seconds, mode mode = relative)
        {
                init(function, seconds, mode);
        }
 
+       /**
+        * Deconstruct a timer.  This will automagically invalidate the timer,
+        * so it will not expire or fire an event.
+        */
        ~timer()
        {
                invalidate();
        }
 
-       void init(const function& function, scalar seconds, mode mode = normal);
 
+       /**
+        * Initialize a timer with a scheduled time.  If the timer is already
+        * scheduled, its prior schedule will be invalidated and replaced by
+        * this new schedule.
+        * \param function The event handler.
+        * \param seconds The number of seconds; the meaning of this depends on
+        * the mode of the timer.
+        * \param mode The timer mode.  If the mode is relative (default), the
+        * seconds parameter is the number of seconds from the current time to
+        * wait before expiring the timer.  If the mode is absolute, the
+        * seconds parameter is the number of seconds from some arbitrary,
+        * fixed time in the past.  If the mode is repeat, the seconds
+        * parameter is the number of seconds from now to wait before expiring
+        * the timer, at which time the timer will be rescheduled to expired
+        * again at that many seconds from the expiration time.  A repeating
+        * timer can be invalidated manually using invalidate().
+        */
+       void init(const function& function,
+                         scalar seconds,
+                         mode mode = relative);
+
+       
+       /**
+        * Get whether or not the timer is valid.  If a timer is valid, it is
+        * still scheduled to expired.  You can get the time remaining from
+        * seconds_remaining().
+        */
        bool is_valid() const;
+
+       /**
+        * Manually invalidated the timer, removing any schedule such that the
+        * timer will not expired and no event will be fired.
+        */
        void invalidate();
 
+
+       /**
+        * Manually fire the timer event.  Usually, the timer event will be
+        * fired when the timer expires, but this can be used to fire it
+        * prematurely.  If the timer is scheduled, it will be invalidated.  If
+        * the timer is already invalid (but is initialized with an event
+        * handler), the event will be fired and the timer will remain invalid.
+        */
        void fire();
 
+
+       /**
+        * Get the number of seconds remaining before the timer is scheduled to
+        * expired.  If the timer is invalid, the retured value will be
+        * negative.
+        * \return Seconds.
+        */
        scalar seconds_remaining() const;
+
+       /**
+        * Get the absolute time of the next expiration of this timer.
+        * \return Seconds.
+        */
+       scalar next_expiration() const;
+
+
+       /**
+        * Get whether or not the timer is expired.  A timer on a repeating
+        * schedule will never be expired since it will always have a scheduled
+        * expiration time in the future.  If the timer is expired but not
+        * invalid, the timer event has not yet fired; the timer will be
+        * invalidated when it does fire.
+        * \return True if the timer is expired, false otherwise.
+        */
        bool is_expired() const;
+
+       /**
+        * Get whether or not the timer is on a repeating schedule.
+        * \return True if the timer is repeating, false otherwise.
+        */
        bool is_repeating() const;
 
 
@@ -87,22 +192,39 @@ public:
         * \param seconds Number of seconds.
         * \param mode The timer mode.
         */
-       static void sleep(scalar seconds, mode mode = normal);
+       static void sleep(scalar seconds, mode mode = relative);
+
+
+       /**
+        * Get the absolute time when the next timer is scheduled to expire.
+        * \return Absolute time, in seconds.
+        */
+       static scalar next_event()
+       {
+               return next_event_;
+       }
 
 
-       static scalar next_expiration()
+       /**
+        * Fire any timers which are not yet invalidated but have an expiration
+        * time in the past.
+        */
+       static void fire_expired_timers()
        {
-               return gNextFire;
+               fire_expired_timers(ticks());
        }
 
-       static void fire_expired_timers();
+       /**
+        * Fire any timers which are not yet invalidated but have an expiration
+        * time before a given absolute time.
+        */
        static void fire_expired_timers(scalar t);
 
 
 private:
 
        static unsigned new_identifier();
-       static scalar find_next_expiration();
+       static scalar find_next_event();
 
        function        function_;
        mode            mode_;
@@ -110,8 +232,8 @@ private:
        scalar          interval_;
        unsigned        id_;
 
-       static scalar                                           gNextFire;
-       static std::map<unsigned,timer*>        gTimers;
+       static scalar                                                           next_event_;
+       static hash<unsigned,timer*,hash_function>      timers_;
 };
 
 
This page took 0.021486 seconds and 4 git commands to generate.