summaryrefslogtreecommitdiff
path: root/src/FbTk
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk')
-rw-r--r--src/FbTk/Timer.cc62
-rw-r--r--src/FbTk/Timer.hh8
2 files changed, 53 insertions, 17 deletions
diff --git a/src/FbTk/Timer.cc b/src/FbTk/Timer.cc
index 09bb7dd..15da0fb 100644
--- a/src/FbTk/Timer.cc
+++ b/src/FbTk/Timer.cc
@@ -48,14 +48,15 @@ namespace FbTk {
48 48
49Timer::TimerList Timer::m_timerlist; 49Timer::TimerList Timer::m_timerlist;
50 50
51Timer::Timer():m_timing(false), m_once(false) { 51Timer::Timer():m_timing(false), m_once(false), m_interval(0) {
52 52
53} 53}
54 54
55Timer::Timer(RefCount<Command> &handler): 55Timer::Timer(RefCount<Command> &handler):
56 m_handler(handler), 56 m_handler(handler),
57 m_timing(false), 57 m_timing(false),
58 m_once(false) { 58 m_once(false),
59 m_interval(0) {
59} 60}
60 61
61 62
@@ -72,7 +73,7 @@ void Timer::setTimeout(time_t t) {
72} 73}
73 74
74 75
75void Timer::setTimeout(timeval t) { 76void Timer::setTimeout(const timeval &t) {
76 m_timeout.tv_sec = t.tv_sec; 77 m_timeout.tv_sec = t.tv_sec;
77 m_timeout.tv_usec = t.tv_usec; 78 m_timeout.tv_usec = t.tv_usec;
78} 79}
@@ -85,10 +86,10 @@ void Timer::start() {
85 gettimeofday(&m_start, 0); 86 gettimeofday(&m_start, 0);
86 87
87 // only add Timers that actually DO something 88 // only add Timers that actually DO something
88 if (! m_timing && *m_handler) { 89 if ((! m_timing || m_interval != 0) && *m_handler) {
89 m_timing = true; 90 m_timing = true;
90 addTimer(this); //add us to the list 91 addTimer(this); //add us to the list
91 } 92 }
92} 93}
93 94
94 95
@@ -111,17 +112,19 @@ void Timer::updateTimers(int fd) {
111 FD_SET(fd, &rfds); 112 FD_SET(fd, &rfds);
112 113
113 114
114 if (m_timerlist.size() > 0) { 115 if (!m_timerlist.empty()) {
115 gettimeofday(&now, 0); 116 gettimeofday(&now, 0);
116 117
117 tm.tv_sec = tm.tv_usec = 0l; 118 tm.tv_sec = tm.tv_usec = 0l;
118 119
119 Timer *timer = m_timerlist.front(); 120 Timer *timer = m_timerlist.front();
120 121
121 tm.tv_sec = timer->getStartTime().tv_sec + 122 const timeval &start = timer->getStartTime();
122 timer->getTimeout().tv_sec - now.tv_sec; 123 const timeval &length = timer->getTimeout();
123 tm.tv_usec = timer->getStartTime().tv_usec + 124 tm.tv_sec = start.tv_sec +
124 timer->getTimeout().tv_usec - now.tv_usec; 125 length.tv_sec - now.tv_sec;
126 tm.tv_usec = start.tv_usec +
127 length.tv_usec - now.tv_usec;
125 128
126 while (tm.tv_usec >= 1000000) { 129 while (tm.tv_usec >= 1000000) {
127 tm.tv_sec++; 130 tm.tv_sec++;
@@ -138,10 +141,17 @@ void Timer::updateTimers(int fd) {
138 } 141 }
139 } 142 }
140 143
144 if (tm.tv_sec < 0) {
145 tm.tv_sec = 0;
146 tm.tv_usec = 0;
147 }
148
141 timeout = &tm; 149 timeout = &tm;
142 } 150 }
143 151
144 select(fd + 1, &rfds, 0, 0, timeout); 152 if (select(fd + 1, &rfds, 0, 0, timeout) != 0)
153 // didn't time out! x events pending
154 return;
145 155
146 TimerList::iterator it; 156 TimerList::iterator it;
147 157
@@ -167,10 +177,13 @@ void Timer::updateTimers(int fd) {
167 //This is to make sure we don't get an invalid iterator 177 //This is to make sure we don't get an invalid iterator
168 //when we do fireTimeout 178 //when we do fireTimeout
169 Timer &t = *(*it); 179 Timer &t = *(*it);
170 tm.tv_sec = t.getStartTime().tv_sec + 180 const timeval &start = t.getStartTime();
171 t.getTimeout().tv_sec; 181 const timeval &length = t.getTimeout();
172 tm.tv_usec = t.getStartTime().tv_usec + 182
173 t.getTimeout().tv_usec; 183 tm.tv_sec = start.tv_sec +
184 length.tv_sec;
185 tm.tv_usec = start.tv_usec +
186 length.tv_usec;
174 187
175 if (((now.tv_sec < tm.tv_sec) || 188 if (((now.tv_sec < tm.tv_sec) ||
176 (now.tv_sec == tm.tv_sec && now.tv_usec < tm.tv_usec))) 189 (now.tv_sec == tm.tv_sec && now.tv_usec < tm.tv_usec)))
@@ -179,6 +192,9 @@ void Timer::updateTimers(int fd) {
179 t.fireTimeout(); 192 t.fireTimeout();
180 // restart the current timer so that the start time is updated 193 // restart the current timer so that the start time is updated
181 if (! t.doOnce()) { 194 if (! t.doOnce()) {
195 if (t.getInterval() != 0) {
196 it = m_timerlist.erase(it);
197 }
182 t.start(); 198 t.start();
183 199
184 // Note that this mustn't be done if we're deleting the 200 // Note that this mustn't be done if we're deleting the
@@ -200,6 +216,22 @@ void Timer::updateTimers(int fd) {
200 216
201void Timer::addTimer(Timer *timer) { 217void Timer::addTimer(Timer *timer) {
202 assert(timer); 218 assert(timer);
219 int interval = timer->getInterval();
220 // interval timers have their timeout change every time they are started!
221 if (interval != 0) {
222 timeval tm;
223 tm.tv_sec = timer->getStartTime().tv_sec;
224 tm.tv_usec = timer->getStartTime().tv_usec;
225
226 // now convert to interval
227 tm.tv_sec = interval - (tm.tv_sec % interval) - 1;
228 tm.tv_usec = 1000000 - tm.tv_usec;
229 if (tm.tv_usec == 1000000) {
230 tm.tv_usec = 0;
231 tm.tv_sec += 1;
232 }
233 timer->setTimeout(tm);
234 }
203 235
204 TimerList::iterator it = m_timerlist.begin(); 236 TimerList::iterator it = m_timerlist.begin();
205 TimerList::iterator it_end = m_timerlist.end(); 237 TimerList::iterator it_end = m_timerlist.end();
diff --git a/src/FbTk/Timer.hh b/src/FbTk/Timer.hh
index 61bb11b..773d5b8 100644
--- a/src/FbTk/Timer.hh
+++ b/src/FbTk/Timer.hh
@@ -64,8 +64,9 @@ public:
64 /// set timeout 64 /// set timeout
65 void setTimeout(time_t val); 65 void setTimeout(time_t val);
66 /// set timeout 66 /// set timeout
67 void setTimeout(timeval val); 67 void setTimeout(const timeval &val);
68 void setCommand(RefCount<Command> &cmd); 68 void setCommand(RefCount<Command> &cmd);
69 void setInterval(int val) { m_interval = val; }
69 /// start timing 70 /// start timing
70 void start(); 71 void start();
71 /// stop timing 72 /// stop timing
@@ -73,7 +74,8 @@ public:
73 /// update all timers 74 /// update all timers
74 static void updateTimers(int file_descriptor); 75 static void updateTimers(int file_descriptor);
75 76
76 inline int isTiming() const { return m_timing; } 77 inline int isTiming() const { return m_timing; }
78 inline int getInterval() const { return m_interval; }
77 inline int doOnce() const { return m_once; } 79 inline int doOnce() const { return m_once; }
78 80
79 inline const timeval &getTimeout() const { return m_timeout; } 81 inline const timeval &getTimeout() const { return m_timeout; }
@@ -96,6 +98,8 @@ private:
96 98
97 bool m_timing; ///< clock running? 99 bool m_timing; ///< clock running?
98 bool m_once; ///< do timeout only once? 100 bool m_once; ///< do timeout only once?
101 int m_interval; ///< Is an interval-only timer (e.g. clock)
102 // note that intervals only take note of the seconds, not microseconds
99 103
100 timeval m_start; ///< start time 104 timeval m_start; ///< start time
101 timeval m_timeout; ///< time length 105 timeval m_timeout; ///< time length