X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=otk%2Ftimer.hh;h=dc2917f17d13365db06b41fb6931de8208118721;hb=60cbb9ee92058b7d52bf2a4542c64c7858b00cdd;hp=610a02e6c8a10d24a0ab98b662aa8cf040b97093;hpb=b0a532db8adeb909fa2cd8e518ca6917a2d7df0a;p=chaz%2Fopenbox diff --git a/otk/timer.hh b/otk/timer.hh index 610a02e6..dc2917f1 100644 --- a/otk/timer.hh +++ b/otk/timer.hh @@ -1,74 +1,114 @@ -// -*- mode: C++; indent-tabs-mode: nil; -*- +// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- #ifndef __timer_hh #define __timer_hh +/*! @file timer.hh + @brief Contains the Timer class, used for timed callbacks. +*/ + extern "C" { -#ifdef TIME_WITH_SYS_TIME -# include -# include -#else // !TIME_WITH_SYS_TIME -# ifdef HAVE_SYS_TIME_H -# include -# else // !HAVE_SYS_TIME_H -# include -# endif // HAVE_SYS_TIME_H -#endif // TIME_WITH_SYS_TIME +#include } -namespace otk { +#include +#include -class OBTimerQueueManager; +namespace otk { -//! The data passed to the OBTimeoutHandler function. +//! The Timer class implements timed callbacks. /*! - Note: this is a very useful place to put an object instance, and set the - event handler to a static function in the same class. + The Timer class can be used to have a callback fire after a given time + interval. A created Timer will fire repetitively until it is destroyed. */ -typedef void *OBTimeoutData; -//! The type of function which can be set as the callback for an OBTimer firing -typedef void (*OBTimeoutHandler)(OBTimeoutData); +class Timer { +public: + //! Data type of Timer callback + typedef void (*TimeoutHandler)(void *data); -class OBTimer { private: - OBTimerQueueManager *manager; - OBTimeoutHandler handler; - OBTimeoutData data; - bool timing, recur; - - timeval _start, _timeout; - - OBTimer(const OBTimer&); - OBTimer& operator=(const OBTimer&); + //! Compares two timeval structs + struct TimerCompare { + //! Compares two timeval structs + inline bool operator()(const Timer *a, const Timer *b) const { + return ((&a->_timeout)->tv_sec == (&b->_timeout)->tv_sec) ? + ((&a->_timeout)->tv_usec > (&b->_timeout)->tv_usec) : + ((&a->_timeout)->tv_sec > (&b->_timeout)->tv_sec); + } + }; + friend struct TimerCompare; // give access to _timeout for shitty compilers + + typedef + std::priority_queue, TimerCompare> TimerQ; + + //! Milliseconds between timer firings + long _delay; + //! Callback for timer expiry + TimeoutHandler _action; + //! Data sent to callback + void *_data; + //! We overload the delete operator to just set this to true + bool _del_me; + //! The time the last fire should've been at + struct timeval _last; + //! When this timer will next trigger + struct timeval _timeout; + + //! Queue of pending timers + static TimerQ _q; + //! Time next timer will expire + static timeval _nearest_timeout; + //! Time at start of current processing loop + static timeval _now; + + //! Really delete something (not just flag for later) + /*! + @param self Timer to be deleted. + */ + static void realDelete(Timer *self); + + //! Adds a millisecond delay to a timeval structure + /*! + @param a Amount of time to increment. + @param msec Number of milliseconds to increment by. + */ + static void timevalAdd(timeval &a, long msec); public: - OBTimer(OBTimerQueueManager *m, OBTimeoutHandler h, OBTimeoutData d); - virtual ~OBTimer(); - - void fireTimeout(); - - inline bool isTiming() const { return timing; } - inline bool isRecurring() const { return recur; } - - inline const timeval &getTimeout() const { return _timeout; } - inline const timeval &getStartTime() const { return _start; } - - timeval timeRemaining(const timeval &tm) const; - bool shouldFire(const timeval &tm) const; - timeval endpoint() const; - - inline void recurring(bool b) { recur = b; } - - void setTimeout(long t); - void setTimeout(const timeval &t); - - void start(); // manager acquires timer - void stop(); // manager releases timer - void halt(); // halts the timer - - bool operator<(const OBTimer& other) const - { return shouldFire(other.endpoint()); } + //! Constructs a new running timer and queues it + /*! + @param delay Time in milliseconds between firings + @param cb The function to be called on fire. + @param data Data to be passed to the callback on fire. + */ + Timer(long delay, TimeoutHandler cb, void *data); + + //! Overloaded delete so we can leave deleted objects in queue for later reap + /*! + @param self Pointer to current instance of Timer. + */ + void operator delete(void *self); + + //! Dispatches all elligible timers, then optionally waits for X events + /*! + @param wait Whether to wait for X events after processing timers. + */ + static void dispatchTimers(bool wait = true); + + //! Returns a relative timeval (to pass select) of the next timer + /*! + @param tm Changed to hold the time until next timer. + @return true if there are any timers queued, and the timeout is being + returned in 'tm'. false if there are no timers queued. + */ + static bool nearestTimeout(struct timeval &tm); + + //! Initializes internal data before use + static void initialize(); + + //! Deletes all waiting timers + static void destroy(); }; } -#endif // __timer_hh +#endif // __timer.hh