1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-07-02 18:05:26 +03:00

Made Clock simpler and more reliable

Removed the suspend check: the best thing we can do after oversleeping
is the same as when we're woken right on time: fetch the time and
reschedule for the next minute boundary.

Don't create a new timer on every callback; instead return the next
interval to SDL.
This commit is contained in:
Maarten ter Huurne 2013-08-07 02:57:44 +02:00
parent a15339d425
commit 9158b90a45
2 changed files with 20 additions and 35 deletions

View File

@ -23,31 +23,23 @@ static void notify()
extern "C" Uint32 clockCallbackFunc(Uint32 timeout, void *d); extern "C" Uint32 clockCallbackFunc(Uint32 timeout, void *d);
class Clock::Forwarder { class Clock::Forwarder {
static unsigned int clockCallbackFunc(Clock *clock, unsigned int timeout) static unsigned int clockCallbackFunc(Clock *clock)
{ {
return clock->clockCallback(timeout); return clock->clockCallback();
} }
friend Uint32 clockCallbackFunc(Uint32 timeout, void *d); friend Uint32 clockCallbackFunc(Uint32 timeout, void *d);
}; };
extern "C" Uint32 clockCallbackFunc(Uint32 timeout, void *d) extern "C" Uint32 clockCallbackFunc(Uint32 timeout, void *d)
{ {
return Clock::Forwarder::clockCallbackFunc(static_cast<Clock *>(d), timeout); return Clock::Forwarder::clockCallbackFunc(static_cast<Clock *>(d));
} }
unsigned int Clock::clockCallback(unsigned int timeout) unsigned int Clock::clockCallback()
{ {
unsigned int now_ticks = SDL_GetTicks(); unsigned int ms = update();
if (now_ticks > timeout_startms + timeout + 1000) {
DEBUG("Suspend occured, restarting timer\n");
timeout_startms = now_ticks;
return timeout;
}
resetTimer();
notify(); notify();
return 60000; return ms;
} }
std::string Clock::getTime(bool is24) std::string Clock::getTime(bool is24)
@ -63,7 +55,7 @@ std::string Clock::getTime(bool is24)
return std::string(buf); return std::string(buf);
} }
int Clock::update() unsigned int Clock::update()
{ {
struct timeval tv; struct timeval tv;
struct tm result; struct tm result;
@ -71,25 +63,20 @@ int Clock::update()
localtime_r(&tv.tv_sec, &result); localtime_r(&tv.tv_sec, &result);
minutes = result.tm_min; minutes = result.tm_min;
hours = result.tm_hour; hours = result.tm_hour;
DEBUG("Time updated: %02i:%02i\n", hours, minutes); DEBUG("Time updated: %02i:%02i:%02i\n", hours, minutes, result.tm_sec);
return result.tm_sec;
}
void Clock::resetTimer() // Compute number of milliseconds to next minute boundary.
{ // We don't need high precision, but it is important that any deviation is
SDL_RemoveTimer(timer); // past the minute mark, so the fetched hour and minute number belong to
timer = NULL; // the freshly started minute.
// Clamping it at 1 sec both avoids overloading the system in case our
int secs = update(); // computation goes haywire and avoids passing 0 to SDL, which would stop
addTimer((60 - secs) * 1000); // the recurring timer.
return std::max(1, (60 - result.tm_sec)) * 1000;
} }
void Clock::addTimer(int timeout) void Clock::addTimer(int timeout)
{ {
if (timeout < 1000 || timeout > 60000)
timeout = 60000;
timeout_startms = SDL_GetTicks();
timer = SDL_AddTimer(timeout, clockCallbackFunc, this); timer = SDL_AddTimer(timeout, clockCallbackFunc, this);
if (timer == NULL) if (timer == NULL)
ERROR("Could not initialize SDLTimer: %s\n", SDL_GetError()); ERROR("Could not initialize SDLTimer: %s\n", SDL_GetError());
@ -99,8 +86,8 @@ Clock::Clock()
{ {
tzset(); tzset();
int sec = update(); unsigned int ms = update();
addTimer((60 - sec) * 1000); addTimer(ms);
} }
Clock::~Clock() Clock::~Clock()

View File

@ -16,12 +16,10 @@ public:
private: private:
void addTimer(int timeout); void addTimer(int timeout);
void resetTimer(); unsigned int update();
int update(); unsigned int clockCallback();
unsigned int clockCallback(unsigned int timeout);
SDL_TimerID timer; SDL_TimerID timer;
unsigned int timeout_startms;
int minutes, hours; int minutes, hours;
}; };