diff options
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | src/ClockTool.cc | 7 | ||||
-rw-r--r-- | src/FbTk/Timer.cc | 62 | ||||
-rw-r--r-- | src/FbTk/Timer.hh | 8 |
4 files changed, 57 insertions, 22 deletions
@@ -1,6 +1,8 @@ | |||
1 | (Format: Year/Month/Day) | 1 | (Format: Year/Month/Day) |
2 | Changes for 0.9.16: | 2 | Changes for 0.9.16: |
3 | *06/04/18: | 3 | *06/04/18: |
4 | * Add new timer ability - interval - to reduce clock update checks (Simon) | ||
5 | ClockTool.cc FbTk/Timer.hh/cc | ||
4 | * Fix system tray resize looping/livelock, sf.net bug #1359442 (Simon) | 6 | * Fix system tray resize looping/livelock, sf.net bug #1359442 (Simon) |
5 | SystemTray.cc | 7 | SystemTray.cc |
6 | * Fix iconbar updates (icon and title) | 8 | * Fix iconbar updates (icon and title) |
diff --git a/src/ClockTool.cc b/src/ClockTool.cc index 851973c..e4b6c0c 100644 --- a/src/ClockTool.cc +++ b/src/ClockTool.cc | |||
@@ -150,10 +150,8 @@ ClockTool::ClockTool(const FbTk::FbWindow &parent, | |||
150 | 150 | ||
151 | // setup timer to check the clock every 0.01 second | 151 | // setup timer to check the clock every 0.01 second |
152 | // if nothing has changed, it wont update the graphics | 152 | // if nothing has changed, it wont update the graphics |
153 | timeval delay; | 153 | m_timer.setInterval(1); |
154 | delay.tv_sec = 0; | 154 | // m_timer.setTimeout(delay); // don't need to set timeout on interval timer |
155 | delay.tv_usec = 100000; | ||
156 | m_timer.setTimeout(delay); | ||
157 | FbTk::RefCount<FbTk::Command> update_graphic(new FbTk::SimpleCommand<ClockTool>(*this, | 155 | FbTk::RefCount<FbTk::Command> update_graphic(new FbTk::SimpleCommand<ClockTool>(*this, |
158 | &ClockTool::updateTime)); | 156 | &ClockTool::updateTime)); |
159 | m_timer.setCommand(update_graphic); | 157 | m_timer.setCommand(update_graphic); |
@@ -243,7 +241,6 @@ unsigned int ClockTool::height() const { | |||
243 | } | 241 | } |
244 | 242 | ||
245 | void ClockTool::updateTime() { | 243 | void ClockTool::updateTime() { |
246 | |||
247 | // update clock | 244 | // update clock |
248 | time_t the_time = time(0); | 245 | time_t the_time = time(0); |
249 | 246 | ||
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 | ||
49 | Timer::TimerList Timer::m_timerlist; | 49 | Timer::TimerList Timer::m_timerlist; |
50 | 50 | ||
51 | Timer::Timer():m_timing(false), m_once(false) { | 51 | Timer::Timer():m_timing(false), m_once(false), m_interval(0) { |
52 | 52 | ||
53 | } | 53 | } |
54 | 54 | ||
55 | Timer::Timer(RefCount<Command> &handler): | 55 | Timer::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 | ||
75 | void Timer::setTimeout(timeval t) { | 76 | void 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 | ||
201 | void Timer::addTimer(Timer *timer) { | 217 | void 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 |