X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=otk%2Ftimer.hh;h=556475c19296a7828f6bb3314e246d0a20aa69d2;hb=dca8c61a91cab29128a72f252b70f4bd9f7786ff;hp=0bc38e1be945ed6474e54028fd18c199153f936c;hpb=d4d89ce0bbd3dd0c556a593accb5e48f7ae09d9e;p=chaz%2Fopenbox diff --git a/otk/timer.hh b/otk/timer.hh index 0bc38e1b..556475c1 100644 --- a/otk/timer.hh +++ b/otk/timer.hh @@ -1,141 +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; } - - 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()); } -}; - + //! Data type of Timer callback + typedef void (*TimeoutHandler)(void *data); -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; - } -}; + //! 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); -typedef _timer_queue, TimerLessThan> TimerQueue; + //! 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); -//! Manages a queue of OBTimer objects -/*! - All OBTimer objects add themself to an OBTimerQueueManager. The manager is - what fires the timers when their time has elapsed. This is done by having the - application call the OBTimerQueueManager::fire class in its main event loop. -*/ -class OBTimerQueueManager { -private: - //! A priority queue of all timers being managed by this class. - TimerQueue timerList; public: - //! Constructs a new OBTimerQueueManager - OBTimerQueueManager() {} - //! Destroys the OBTimerQueueManager - virtual ~OBTimerQueueManager() {} + //! 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); - //! Will wait for and fire the next timer in the queue. + //! Overloaded delete so we can leave deleted objects in queue for later reap /*! - The function will stop waiting if an event is received from the X server. + @param self Pointer to current instance of Timer. */ - virtual void fire(); + void operator delete(void *self); - //! Adds a new timer to the queue + //! Dispatches all elligible timers, then optionally waits for X events /*! - @param timer An OBTimer to add to the queue + @param wait Whether to wait for X events after processing timers. */ - virtual void addTimer(OBTimer* timer); - //! Removes a timer from the queue + static void dispatchTimers(bool wait = true); + + //! Returns a relative timeval (to pass select) of the next timer /*! - @param timer An OBTimer already in the queue to remove + @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 removeTimer(OBTimer* timer); + static bool nearestTimeout(struct timeval &tm); + + //! Initializes internal data before use + static void initialize(void); + + //! Deletes all waiting timers + static void destroy(void); }; } -#endif // _BLACKBOX_Timer_hh +#endif // __timer.hh