X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fmoof%2Ftimer.hh;h=3ec4ef9d8e04bd23a1e6141d4c242e430f6d0d5e;hp=d7a411bc48e82089891795db5602d2cfb42e4326;hb=1d4aa0d34b0410c7bc60a24bad7abb55eacc850a;hpb=831f04d4bc19a390415ac0bbac4331c7a65509bc;ds=sidebyside diff --git a/src/moof/timer.hh b/src/moof/timer.hh index d7a411b..3ec4ef9 100644 --- a/src/moof/timer.hh +++ b/src/moof/timer.hh @@ -17,54 +17,159 @@ * Functions for measuring time in a friendly unit. */ -#include - #include #include +#include +#include #include 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 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 gTimers; + static scalar next_event_; + static hash timers_; };