2002-05-25 00:29:44 +00:00
|
|
|
// -*- mode: C++; indent-tabs-mode: nil; -*-
|
|
|
|
#ifndef _BLACKBOX_Timer_hh
|
|
|
|
#define _BLACKBOX_Timer_hh
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
#ifdef TIME_WITH_SYS_TIME
|
|
|
|
# include <sys/time.h>
|
|
|
|
# include <time.h>
|
|
|
|
#else // !TIME_WITH_SYS_TIME
|
|
|
|
# ifdef HAVE_SYS_TIME_H
|
|
|
|
# include <sys/time.h>
|
|
|
|
# else // !HAVE_SYS_TIME_H
|
|
|
|
# include <time.h>
|
|
|
|
# endif // HAVE_SYS_TIME_H
|
|
|
|
#endif // TIME_WITH_SYS_TIME
|
|
|
|
}
|
|
|
|
|
2002-11-03 11:46:05 +00:00
|
|
|
#include <queue>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <vector>
|
|
|
|
|
2002-11-03 14:29:34 +00:00
|
|
|
namespace otk {
|
2002-11-03 11:46:05 +00:00
|
|
|
|
2002-05-25 00:29:44 +00:00
|
|
|
// forward declaration
|
2002-11-03 12:27:49 +00:00
|
|
|
class OBTimerQueueManager;
|
2002-05-25 00:29:44 +00:00
|
|
|
|
2002-11-03 14:29:34 +00:00
|
|
|
typedef void *OBTimeoutData;
|
|
|
|
typedef void (*OBTimeoutHandler)(OBTimeoutData);
|
2002-05-25 00:29:44 +00:00
|
|
|
|
2002-11-03 12:48:10 +00:00
|
|
|
class OBTimer {
|
2002-05-25 00:29:44 +00:00
|
|
|
private:
|
2002-11-03 14:29:34 +00:00
|
|
|
OBTimerQueueManager *manager;
|
|
|
|
OBTimeoutHandler handler;
|
|
|
|
OBTimeoutData data;
|
2002-05-25 00:29:44 +00:00
|
|
|
bool timing, recur;
|
|
|
|
|
|
|
|
timeval _start, _timeout;
|
|
|
|
|
2002-11-03 12:48:10 +00:00
|
|
|
OBTimer(const OBTimer&);
|
|
|
|
OBTimer& operator=(const OBTimer&);
|
2002-05-25 00:29:44 +00:00
|
|
|
|
|
|
|
public:
|
2002-11-03 14:29:34 +00:00
|
|
|
OBTimer(OBTimerQueueManager *m, OBTimeoutHandler h, OBTimeoutData d);
|
|
|
|
virtual ~OBTimer();
|
2002-05-25 00:29:44 +00:00
|
|
|
|
2002-11-03 14:29:34 +00:00
|
|
|
void fireTimeout();
|
2002-05-25 00:29:44 +00:00
|
|
|
|
2002-11-03 14:29:34 +00:00
|
|
|
inline bool isTiming() const { return timing; }
|
|
|
|
inline bool isRecurring() const { return recur; }
|
2002-05-25 00:29:44 +00:00
|
|
|
|
2002-11-03 14:29:34 +00:00
|
|
|
inline const timeval &getTimeout() const { return _timeout; }
|
|
|
|
inline const timeval &getStartTime() const { return _start; }
|
2002-05-25 00:29:44 +00:00
|
|
|
|
|
|
|
timeval timeRemaining(const timeval &tm) const;
|
|
|
|
bool shouldFire(const timeval &tm) const;
|
2002-11-03 14:29:34 +00:00
|
|
|
timeval endpoint() const;
|
2002-05-25 00:29:44 +00:00
|
|
|
|
|
|
|
inline void recurring(bool b) { recur = b; }
|
|
|
|
|
|
|
|
void setTimeout(long t);
|
|
|
|
void setTimeout(const timeval &t);
|
|
|
|
|
2002-11-03 14:29:34 +00:00
|
|
|
void start(); // manager acquires timer
|
|
|
|
void stop(); // manager releases timer
|
|
|
|
void halt(); // halts the timer
|
2002-05-25 00:29:44 +00:00
|
|
|
|
2002-11-03 12:48:10 +00:00
|
|
|
bool operator<(const OBTimer& other) const
|
2002-05-25 00:29:44 +00:00
|
|
|
{ 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;
|
|
|
|
|
2002-11-03 14:29:34 +00:00
|
|
|
_timer_queue(): _Base() {}
|
|
|
|
~_timer_queue() {}
|
2002-05-25 00:29:44 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2002-11-03 14:29:34 +00:00
|
|
|
bool empty() const { return _Base::empty(); }
|
|
|
|
size_t size() const { return _Base::size(); }
|
2002-05-25 00:29:44 +00:00
|
|
|
void push(const _Tp& value) { _Base::push(value); }
|
2002-11-03 14:29:34 +00:00
|
|
|
void pop() { _Base::pop(); }
|
|
|
|
const _Tp& top() const { return _Base::top(); }
|
2002-05-25 00:29:44 +00:00
|
|
|
private:
|
|
|
|
// no copying!
|
|
|
|
_timer_queue(const _timer_queue&) {}
|
|
|
|
_timer_queue& operator=(const _timer_queue&) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct TimerLessThan {
|
2002-11-03 12:48:10 +00:00
|
|
|
bool operator()(const OBTimer* const l, const OBTimer* const r) const {
|
2002-05-25 00:29:44 +00:00
|
|
|
return *r < *l;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2002-11-03 12:48:10 +00:00
|
|
|
typedef _timer_queue<OBTimer*,
|
|
|
|
std::vector<OBTimer*>, TimerLessThan> TimerQueue;
|
2002-05-25 00:29:44 +00:00
|
|
|
|
2002-11-04 03:37:17 +00:00
|
|
|
//! 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.
|
|
|
|
*/
|
2002-11-03 12:27:49 +00:00
|
|
|
class OBTimerQueueManager {
|
|
|
|
private:
|
2002-11-04 03:37:17 +00:00
|
|
|
//! A priority queue of all timers being managed by this class.
|
2002-11-03 12:27:49 +00:00
|
|
|
TimerQueue timerList;
|
2002-05-25 00:29:44 +00:00
|
|
|
public:
|
2002-11-04 03:37:17 +00:00
|
|
|
//! Constructs a new OBTimerQueueManager
|
2002-11-03 12:27:49 +00:00
|
|
|
OBTimerQueueManager() {}
|
2002-11-04 03:37:17 +00:00
|
|
|
//! Destroys the OBTimerQueueManager
|
2002-11-03 12:27:49 +00:00
|
|
|
virtual ~OBTimerQueueManager() {}
|
2002-11-03 12:48:10 +00:00
|
|
|
|
|
|
|
//! 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();
|
2002-11-04 03:37:17 +00:00
|
|
|
|
|
|
|
//! Adds a new timer to the queue
|
|
|
|
/*!
|
|
|
|
@param timer An OBTimer to add to the queue
|
|
|
|
*/
|
2002-11-03 12:48:10 +00:00
|
|
|
virtual void addTimer(OBTimer* timer);
|
2002-11-04 03:37:17 +00:00
|
|
|
//! Removes a timer from the queue
|
|
|
|
/*!
|
|
|
|
@param timer An OBTimer already in the queue to remove
|
|
|
|
*/
|
2002-11-03 12:48:10 +00:00
|
|
|
virtual void removeTimer(OBTimer* timer);
|
2002-05-25 00:29:44 +00:00
|
|
|
};
|
|
|
|
|
2002-11-03 11:46:05 +00:00
|
|
|
}
|
|
|
|
|
2002-05-25 00:29:44 +00:00
|
|
|
#endif // _BLACKBOX_Timer_hh
|