From 4c011a0a12a06ae87e9bdd296ce503131a292d27 Mon Sep 17 00:00:00 2001 From: simonb Date: Tue, 18 Apr 2006 15:17:11 +0000 Subject: don't check the clock so often... --- ChangeLog | 2 ++ src/ClockTool.cc | 7 ++----- src/FbTk/Timer.cc | 62 +++++++++++++++++++++++++++++++++++++++++-------------- src/FbTk/Timer.hh | 8 +++++-- 4 files changed, 57 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9250265..8a5729c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,8 @@ (Format: Year/Month/Day) Changes for 0.9.16: *06/04/18: + * Add new timer ability - interval - to reduce clock update checks (Simon) + ClockTool.cc FbTk/Timer.hh/cc * Fix system tray resize looping/livelock, sf.net bug #1359442 (Simon) SystemTray.cc * 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, // setup timer to check the clock every 0.01 second // if nothing has changed, it wont update the graphics - timeval delay; - delay.tv_sec = 0; - delay.tv_usec = 100000; - m_timer.setTimeout(delay); + m_timer.setInterval(1); + // m_timer.setTimeout(delay); // don't need to set timeout on interval timer FbTk::RefCount update_graphic(new FbTk::SimpleCommand(*this, &ClockTool::updateTime)); m_timer.setCommand(update_graphic); @@ -243,7 +241,6 @@ unsigned int ClockTool::height() const { } void ClockTool::updateTime() { - // update clock time_t the_time = time(0); 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 { Timer::TimerList Timer::m_timerlist; -Timer::Timer():m_timing(false), m_once(false) { +Timer::Timer():m_timing(false), m_once(false), m_interval(0) { } Timer::Timer(RefCount &handler): m_handler(handler), m_timing(false), - m_once(false) { + m_once(false), + m_interval(0) { } @@ -72,7 +73,7 @@ void Timer::setTimeout(time_t t) { } -void Timer::setTimeout(timeval t) { +void Timer::setTimeout(const timeval &t) { m_timeout.tv_sec = t.tv_sec; m_timeout.tv_usec = t.tv_usec; } @@ -85,10 +86,10 @@ void Timer::start() { gettimeofday(&m_start, 0); // only add Timers that actually DO something - if (! m_timing && *m_handler) { + if ((! m_timing || m_interval != 0) && *m_handler) { m_timing = true; addTimer(this); //add us to the list - } + } } @@ -111,17 +112,19 @@ void Timer::updateTimers(int fd) { FD_SET(fd, &rfds); - if (m_timerlist.size() > 0) { + if (!m_timerlist.empty()) { gettimeofday(&now, 0); tm.tv_sec = tm.tv_usec = 0l; Timer *timer = m_timerlist.front(); - tm.tv_sec = timer->getStartTime().tv_sec + - timer->getTimeout().tv_sec - now.tv_sec; - tm.tv_usec = timer->getStartTime().tv_usec + - timer->getTimeout().tv_usec - now.tv_usec; + const timeval &start = timer->getStartTime(); + const timeval &length = timer->getTimeout(); + tm.tv_sec = start.tv_sec + + length.tv_sec - now.tv_sec; + tm.tv_usec = start.tv_usec + + length.tv_usec - now.tv_usec; while (tm.tv_usec >= 1000000) { tm.tv_sec++; @@ -138,10 +141,17 @@ void Timer::updateTimers(int fd) { } } + if (tm.tv_sec < 0) { + tm.tv_sec = 0; + tm.tv_usec = 0; + } + timeout = &tm; } - select(fd + 1, &rfds, 0, 0, timeout); + if (select(fd + 1, &rfds, 0, 0, timeout) != 0) + // didn't time out! x events pending + return; TimerList::iterator it; @@ -167,10 +177,13 @@ void Timer::updateTimers(int fd) { //This is to make sure we don't get an invalid iterator //when we do fireTimeout Timer &t = *(*it); - tm.tv_sec = t.getStartTime().tv_sec + - t.getTimeout().tv_sec; - tm.tv_usec = t.getStartTime().tv_usec + - t.getTimeout().tv_usec; + const timeval &start = t.getStartTime(); + const timeval &length = t.getTimeout(); + + tm.tv_sec = start.tv_sec + + length.tv_sec; + tm.tv_usec = start.tv_usec + + length.tv_usec; if (((now.tv_sec < tm.tv_sec) || (now.tv_sec == tm.tv_sec && now.tv_usec < tm.tv_usec))) @@ -179,6 +192,9 @@ void Timer::updateTimers(int fd) { t.fireTimeout(); // restart the current timer so that the start time is updated if (! t.doOnce()) { + if (t.getInterval() != 0) { + it = m_timerlist.erase(it); + } t.start(); // Note that this mustn't be done if we're deleting the @@ -200,6 +216,22 @@ void Timer::updateTimers(int fd) { void Timer::addTimer(Timer *timer) { assert(timer); + int interval = timer->getInterval(); + // interval timers have their timeout change every time they are started! + if (interval != 0) { + timeval tm; + tm.tv_sec = timer->getStartTime().tv_sec; + tm.tv_usec = timer->getStartTime().tv_usec; + + // now convert to interval + tm.tv_sec = interval - (tm.tv_sec % interval) - 1; + tm.tv_usec = 1000000 - tm.tv_usec; + if (tm.tv_usec == 1000000) { + tm.tv_usec = 0; + tm.tv_sec += 1; + } + timer->setTimeout(tm); + } TimerList::iterator it = m_timerlist.begin(); 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: /// set timeout void setTimeout(time_t val); /// set timeout - void setTimeout(timeval val); + void setTimeout(const timeval &val); void setCommand(RefCount &cmd); + void setInterval(int val) { m_interval = val; } /// start timing void start(); /// stop timing @@ -73,7 +74,8 @@ public: /// update all timers static void updateTimers(int file_descriptor); - inline int isTiming() const { return m_timing; } + inline int isTiming() const { return m_timing; } + inline int getInterval() const { return m_interval; } inline int doOnce() const { return m_once; } inline const timeval &getTimeout() const { return m_timeout; } @@ -96,6 +98,8 @@ private: bool m_timing; ///< clock running? bool m_once; ///< do timeout only once? + int m_interval; ///< Is an interval-only timer (e.g. clock) + // note that intervals only take note of the seconds, not microseconds timeval m_start; ///< start time timeval m_timeout; ///< time length -- cgit v0.11.2