X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=otk%2Ftimer.hh;h=dc2917f17d13365db06b41fb6931de8208118721;hb=a91a6f97daeb058f346246081e1c83a788787f9b;hp=2deeba58ea831c615b79a0164810ae026cda04f6;hpb=9259ec5732851dd66f7c598d629e3808ac7ab3d8;p=chaz%2Fopenbox diff --git a/otk/timer.hh b/otk/timer.hh index 2deeba58..dc2917f1 100644 --- a/otk/timer.hh +++ b/otk/timer.hh @@ -1,124 +1,114 @@ -// -*- mode: C++; indent-tabs-mode: nil; -*- -#ifndef _BLACKBOX_Timer_hh -#define _BLACKBOX_Timer_hh +// -*- 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 } #include -#include #include namespace otk { -// forward declaration -class OBTimerQueueManager; - -typedef void *OBTimeoutData; -typedef void (*OBTimeoutHandler)(OBTimeoutData); - -class OBTimer { -private: - OBTimerQueueManager *manager; - OBTimeoutHandler handler; - OBTimeoutData data; - bool timing, recur; - - timeval _start, _timeout; - - OBTimer(const OBTimer&); - OBTimer& operator=(const OBTimer&); - +//! The Timer class implements timed callbacks. +/*! + 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. +*/ +class Timer { public: - OBTimer(OBTimerQueueManager *m, OBTimeoutHandler h, OBTimeoutData d); - virtual ~OBTimer(); - - void fireTimeout(); - - inline bool isTiming() const { return timing; } - inline bool isRecurring() const { return recur; } + //! Data type of Timer callback + typedef void (*TimeoutHandler)(void *data); - 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()); } -}; +private: + //! 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); -template -class _timer_queue: protected std::priority_queue<_Tp, _Sequence, _Compare> { public: - typedef std::priority_queue<_Tp, _Sequence, _Compare> _Base; - - _timer_queue(): _Base() {} - ~_timer_queue() {} - - void release(const _Tp& value) { - c.erase(std::remove(c.begin(), c.end(), value), c.end()); - // after removing the item we need to make the heap again - std::make_heap(c.begin(), c.end(), comp); - } - bool empty() const { return _Base::empty(); } - size_t size() const { return _Base::size(); } - void push(const _Tp& value) { _Base::push(value); } - void pop() { _Base::pop(); } - const _Tp& top() const { return _Base::top(); } -private: - // no copying! - _timer_queue(const _timer_queue&) {} - _timer_queue& operator=(const _timer_queue&) {} -}; - -struct TimerLessThan { - bool operator()(const OBTimer* const l, const OBTimer* const r) const { - return *r < *l; - } -}; + //! 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); -typedef _timer_queue, TimerLessThan> TimerQueue; + //! 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); -class OBTimerQueueManager { -private: - TimerQueue timerList; -public: - OBTimerQueueManager() {} - virtual ~OBTimerQueueManager() {} + //! 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); - //! Will wait for and fire the next timer in the queue. + //! Returns a relative timeval (to pass select) of the next timer /*! - The function will stop waiting if an event is received from the X server. + @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. */ - virtual void fire(); - - virtual void addTimer(OBTimer* timer); - virtual void removeTimer(OBTimer* timer); + static bool nearestTimeout(struct timeval &tm); + + //! Initializes internal data before use + static void initialize(); + + //! Deletes all waiting timers + static void destroy(); }; } -#endif // _BLACKBOX_Timer_hh +#endif // __timer.hh