1 /*
2 ** Copyright 2002, Double Precision Inc.
3 **
4 ** See COPYING for distribution information.
5 */
6 
7 #ifndef timer_H
8 #define timer_H
9 
10 #include "../curses/curses_config.h"
11 #if TIME_WITH_SYS_TIME
12 # include <sys/time.h>
13 # include <time.h>
14 #else
15 # if HAVE_SYS_TIME_H
16 #  include <sys/time.h>
17 # else
18 #  include <time.h>
19 # endif
20 #endif
21 
22 #include <set>
23 
24 ////////////////////////////////////////////////////////////////////////////
25 //
26 // The Timer object is used primarily by CursesStatusBar to automatically
27 // clear messages after a short delay, but it can be used as a general
28 // purpose timer.
29 //
30 // Timer processing depends on the application repeatedly calling the
31 // getNextTimeout() method, which checks for any timers that need to go
32 // off.  getNextTimeout() returns a timeval when the getNextTimeout() should
33 // be called again, to check for any more timers.
34 //
35 // The Timer object may be instantiated as is, or subclassed.  The expired()
36 // method may be invoked, after getNextTimeout(), to check if the timer has
37 // gone off.  Alternativelly, the subclass can implement the alarm() method.
38 
39 class Timer {
40 	struct timeval timeout;
41 
42 	static std::set<Timer *> timer_list;
43 
44 public:
45 	Timer();
46 	virtual ~Timer();
47 
48 	// Set a timeout for the given number of seconds.
49 
50 	void setTimer(int);
51 
52 	// Set a timeout for the given number of seconds/milliseconds.
53 
54 	void setTimer(struct timeval tv);
55 
56 	// Cancel this timer.
57 
cancelTimer()58 	void cancelTimer() { timeout.tv_sec=0; timeout.tv_usec=0; }
expired()59 	bool expired() { return timeout.tv_sec == 0 && timeout.tv_usec == 0; }
60 
61 	// Compute how long before this timer goes off.
62 
63 	struct timeval getTimer() const;
64 
65 	// Compute how long before this timer goes off, if the current time is
66 	// 'now'.
67 
68 	struct timeval getTimer(const struct timeval &now) const;
69 
70 	// The timer has gone off.
71 
72 	virtual void alarm();
73 
74 	// Trigger any pending timers.  alarmCalledFlag gets set to true if
75 	// any alarms were kicked off
76 
77 	static struct timeval getNextTimeout(bool &alarmCalledFlag);
78 };
79 
80 //////////////////////////////////////////////////////////////////////////
81 //
82 //  A helpful template that embeds Timer as a member of another class.
83 //  Rather than subclassing from Timer, multiple Timer objects may be
84 //  members of a class.  Typical usage:
85 //
86 //  class X {
87 //     ...
88 //
89 //  TimerRedirect<X> timera, timerb;
90 //
91 //       void timeraFunc();
92 //       void timerbFunc();
93 //  };
94 //
95 //  X::X()
96 //  {
97 //       timera=this;
98 //       timerb=this;
99 //
100 //       timera= &X::timerAFunc;
101 //       timerb= &X::timerBFunc;
102 //  }
103 //
104 //  ...
105 //
106 //       timera.setTimer(10);
107 //
108 
109 template<class T> class TimerRedirect : public Timer {
110 
111 	T *myClass;
112 	void (T::*myMethod)();
113 
114 public:
TimerRedirect()115 	TimerRedirect() : myClass(0), myMethod(0) {}
~TimerRedirect()116 	~TimerRedirect() {}
117 
118 	void operator=(T *classPtr) { myClass=classPtr; }
119 	void operator=( void (T::*methodPtr)() ) { myMethod=methodPtr; }
120 
alarm()121 	void alarm() { if (myClass && myMethod) (myClass->*myMethod)(); }
122 };
123 
124 #endif
125