all repos — openbox @ b0a532db8adeb909fa2cd8e518ca6917a2d7df0a

openbox fork - make it a bit more like ryudo

split the OBTimerQueueManager and TimerQueue into their own files
Dana Jansens danakj@orodu.net
commit

b0a532db8adeb909fa2cd8e518ca6917a2d7df0a

parent

d4d89ce0bbd3dd0c556a593accb5e48f7ae09d9e

M otk/Makefile.amotk/Makefile.am

@@ -5,7 +5,8 @@

noinst_LIBRARIES=libotk.a libotk_a_SOURCES= color.cc display.cc font.cc gccache.cc image.cc \ - imagecontrol.cc rect.cc screeninfo.cc texture.cc timer.cc + imagecontrol.cc rect.cc screeninfo.cc texture.cc timer.cc \ + timerqueuemanager.cc MAINTAINERCLEANFILES= Makefile.in
M otk/timer.ccotk/timer.cc

@@ -5,8 +5,7 @@ # include "../config.h"

#endif // HAVE_CONFIG_H #include "timer.hh" -#include "display.hh" -#include "util.hh" +#include "timerqueuemanager.hh" namespace otk {

@@ -40,7 +39,7 @@ manager = m;

handler = h; data = d; - recur = timing = False; + recur = timing = false; }

@@ -70,7 +69,7 @@ {

gettimeofday(&_start, 0); if (! timing) { - timing = True; + timing = true; manager->addTimer(this); } }

@@ -78,7 +77,7 @@

void OBTimer::stop(void) { - timing = False; + timing = false; manager->removeTimer(this); }

@@ -86,7 +85,7 @@

void OBTimer::halt(void) { - timing = False; + timing = false; }

@@ -125,62 +124,6 @@ timeval end = endpoint();

return ! ((tm.tv_sec < end.tv_sec) || (tm.tv_sec == end.tv_sec && tm.tv_usec < end.tv_usec)); -} - - -void OBTimerQueueManager::fire() -{ - fd_set rfds; - timeval now, tm, *timeout = (timeval *) 0; - - const int xfd = ConnectionNumber(otk::OBDisplay::display); - - FD_ZERO(&rfds); - FD_SET(xfd, &rfds); // break on any x events - - if (! timerList.empty()) { - const OBTimer* const timer = timerList.top(); - - gettimeofday(&now, 0); - tm = timer->timeRemaining(now); - - timeout = &tm; - } - - select(xfd + 1, &rfds, 0, 0, timeout); - - // check for timer timeout - gettimeofday(&now, 0); - - // there is a small chance for deadlock here: - // *IF* the timer list keeps getting refreshed *AND* the time between - // timer->start() and timer->shouldFire() is within the timer's period - // then the timer will keep firing. This should be VERY near impossible. - while (! timerList.empty()) { - OBTimer *timer = timerList.top(); - if (! timer->shouldFire(now)) - break; - - timerList.pop(); - - timer->fireTimeout(); - timer->halt(); - if (timer->isRecurring()) - timer->start(); - } -} - - -void OBTimerQueueManager::addTimer(OBTimer *timer) -{ - assert(timer); - timerList.push(timer); -} - -void OBTimerQueueManager::removeTimer(OBTimer* timer) -{ - assert(timer); - timerList.release(timer); } }
M otk/timer.hhotk/timer.hh

@@ -1,6 +1,6 @@

// -*- mode: C++; indent-tabs-mode: nil; -*- -#ifndef _BLACKBOX_Timer_hh -#define _BLACKBOX_Timer_hh +#ifndef __timer_hh +#define __timer_hh extern "C" { #ifdef TIME_WITH_SYS_TIME

@@ -15,16 +15,17 @@ # endif // HAVE_SYS_TIME_H

#endif // TIME_WITH_SYS_TIME } -#include <queue> -#include <algorithm> -#include <vector> - namespace otk { -// forward declaration class OBTimerQueueManager; +//! The data passed to the OBTimeoutHandler function. +/*! + 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. +*/ typedef void *OBTimeoutData; +//! The type of function which can be set as the callback for an OBTimer firing typedef void (*OBTimeoutHandler)(OBTimeoutData); class OBTimer {

@@ -68,74 +69,6 @@ bool operator<(const OBTimer& other) const

{ return shouldFire(other.endpoint()); } }; - -template <class _Tp, class _Sequence, class _Compare> -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; - } -}; - -typedef _timer_queue<OBTimer*, - std::vector<OBTimer*>, TimerLessThan> TimerQueue; - -//! 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() {} - - //! Will wait for and fire the next timer in the queue. - /*! - The function will stop waiting if an event is received from the X server. - */ - virtual void fire(); - - //! Adds a new timer to the queue - /*! - @param timer An OBTimer to add to the queue - */ - virtual void addTimer(OBTimer* timer); - //! Removes a timer from the queue - /*! - @param timer An OBTimer already in the queue to remove - */ - virtual void removeTimer(OBTimer* timer); -}; - } -#endif // _BLACKBOX_Timer_hh +#endif // __timer_hh
A otk/timerqueue.hh

@@ -0,0 +1,52 @@

+// -*- mode: C++; indent-tabs-mode: nil; -*- +#ifndef __timerqueue_hh +#define __timerqueue_hh + +#ifndef DOXYGEN_IGNORE + +#include "timer.hh" + +#include <queue> +#include <vector> +#include <algorithm> + +namespace otk { + +template <class _Tp, class _Sequence, class _Compare> +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; + } +}; + +typedef _timer_queue<OBTimer*, + std::vector<OBTimer*>, TimerLessThan> TimerQueue; + +} + +#endif // DOXYGEN_IGNORE + +#endif // __timerqueue_hh
A otk/timerqueuemanager.cc

@@ -0,0 +1,67 @@

+// -*- mode: C++; indent-tabs-mode: nil; -*- + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif // HAVE_CONFIG_H + +#include "timerqueuemanager.hh" +#include "display.hh" + +namespace otk { + +void OBTimerQueueManager::fire() +{ + fd_set rfds; + timeval now, tm, *timeout = (timeval *) 0; + + const int xfd = ConnectionNumber(otk::OBDisplay::display); + + FD_ZERO(&rfds); + FD_SET(xfd, &rfds); // break on any x events + + if (! timerList.empty()) { + const OBTimer* const timer = timerList.top(); + + gettimeofday(&now, 0); + tm = timer->timeRemaining(now); + + timeout = &tm; + } + + select(xfd + 1, &rfds, 0, 0, timeout); + + // check for timer timeout + gettimeofday(&now, 0); + + // there is a small chance for deadlock here: + // *IF* the timer list keeps getting refreshed *AND* the time between + // timer->start() and timer->shouldFire() is within the timer's period + // then the timer will keep firing. This should be VERY near impossible. + while (! timerList.empty()) { + OBTimer *timer = timerList.top(); + if (! timer->shouldFire(now)) + break; + + timerList.pop(); + + timer->fireTimeout(); + timer->halt(); + if (timer->isRecurring()) + timer->start(); + } +} + + +void OBTimerQueueManager::addTimer(OBTimer *timer) +{ + assert(timer); + timerList.push(timer); +} + +void OBTimerQueueManager::removeTimer(OBTimer* timer) +{ + assert(timer); + timerList.release(timer); +} + +}
A otk/timerqueuemanager.hh

@@ -0,0 +1,45 @@

+// -*- mode: C++; indent-tabs-mode: nil; -*- +#ifndef __timerqueuemanager_hh +#define __timerqueuemanager_hh + +#include "timerqueue.hh" + +namespace otk { + +//! 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() {} + + //! Will wait for and fire the next timer in the queue. + /*! + The function will stop waiting if an event is received from the X server. + */ + virtual void fire(); + + //! Adds a new timer to the queue + /*! + @param timer An OBTimer to add to the queue + */ + virtual void addTimer(OBTimer* timer); + //! Removes a timer from the queue + /*! + @param timer An OBTimer already in the queue to remove + */ + virtual void removeTimer(OBTimer* timer); +}; + +} + +#endif // __timerqueuemanager_hh