X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=otk%2Ftimer.hh;h=dc2917f17d13365db06b41fb6931de8208118721;hb=9c2b06668e349901791fb9fe459cc511e460287e;hp=d518dc5a9abfec6187d365eb97e02f758d6e5c13;hpb=7ebccbf39a02d4185b09728c5d55910742d926ff;p=chaz%2Fopenbox diff --git a/otk/timer.hh b/otk/timer.hh index d518dc5a..dc2917f1 100644 --- a/otk/timer.hh +++ b/otk/timer.hh @@ -1,132 +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); -//! A Timer class which will fire a function when its time elapses -class OBTimer { private: - //! The manager which to add ourself to and remove ourself after we are done - OBTimerQueueManager *_manager; - //! The function to call when the time elapses - OBTimeoutHandler _handler; - //! The data which gets passed along to the OBTimeoutHandler - OBTimeoutData _data; - //! Determines if the timer is currently started - bool _timing; - //! When this is true, the timer will reset itself to fire again every time - bool _recur; - - //! The time at which the timer started - timeval _start; - //! The time at which the timer is going to fire - timeval _timeout; - - //! Disallows copying of OBTimer objects - OBTimer(const OBTimer&); - //! Disallows copying of OBTimer objects - OBTimer& operator=(const OBTimer&); - -public: - //! Constructs a new OBTimer object + //! 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 m The OBTimerQueueManager with which to associate. The manager - specified will be resposible for making this timer fire. - @param h The function to call when the timer fires - @param d The data to pass along to the function call when the timer fires + @param self Timer to be deleted. */ - OBTimer(OBTimerQueueManager *m, OBTimeoutHandler h, OBTimeoutData d); - //! Destroys the OBTimer object - virtual ~OBTimer(); - - //! Fires the timer, calling its OBTimeoutHandler - void fire(); - - //! Returns if the OBTimer is started and timing - inline bool timing() const { return _timing; } - //! Returns if the OBTimer is going to repeat - inline bool recurring() const { return _recur; } + static void realDelete(Timer *self); - //! Gets the amount of time the OBTimer should last before firing - inline const timeval &timeout() const { return _timeout; } - //! Gets the time at which the OBTimer started - inline const timeval &startTime() const { return _start; } - - //! Gets the amount of time left before the OBTimer fires - timeval remainingTime(const timeval &tm) const; - //! Returns if the OBTimer is past its timeout time, and should fire - bool shouldFire(const timeval &tm) const; - - //! Gets the time at which the OBTimer will fire - timeval endTime() const; - - //! Sets the OBTimer to repeat or not + //! Adds a millisecond delay to a timeval structure /*! - @param b If true, the timer is set to repeat; otherwise, it will fire only - once + @param a Amount of time to increment. + @param msec Number of milliseconds to increment by. */ - inline void setRecurring(bool b) { _recur = b; } + static void timevalAdd(timeval &a, long msec); - //! Sets the amount of time for the OBTimer to last in milliseconds - /*! - @param t The number of milliseconds the timer should last - */ - void setTimeout(long t); - //! Sets the amount of time the OBTimer should last before firing +public: + //! Constructs a new running timer and queues it /*! - @param t The amount of time the timer should last + @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. */ - void setTimeout(const timeval &t); + Timer(long delay, TimeoutHandler cb, void *data); - //! Causes the timer to begin + //! Overloaded delete so we can leave deleted objects in queue for later reap /*! - The timer fires after the time in OBTimer::getTimeout has passed since this - function was called. - Calling this function while the timer is already started will cause it to - restart its countdown. + @param self Pointer to current instance of Timer. */ - void start(); // manager acquires timer - //! Causes the timer to stop + void operator delete(void *self); + + //! Dispatches all elligible timers, then optionally waits for X events /*! - The timer will no longer fire once this function has been called. - Calling this function more than once does not have any effect. + @param wait Whether to wait for X events after processing timers. */ - void stop(); // manager releases timer + static void dispatchTimers(bool wait = true); - //! Determines if this OBTimer will fire before a second OBTimer object + //! Returns a relative timeval (to pass select) of the next timer /*! - @param other The second OBTimer with which to compare - @return true if this OBTimer will fire before 'other'; otherwise, false + @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. */ - bool operator<(const OBTimer& other) const - { return shouldFire(other.endTime()); } + 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