2013-07-22 06:54:09 +03:00
|
|
|
#include "clock.h"
|
2013-08-06 22:55:31 +03:00
|
|
|
|
2013-07-22 06:54:09 +03:00
|
|
|
#include "debug.h"
|
|
|
|
#include "inputmanager.h"
|
|
|
|
|
2013-08-06 22:55:31 +03:00
|
|
|
#include <sys/time.h>
|
|
|
|
|
2013-07-22 06:54:09 +03:00
|
|
|
|
2013-08-06 22:55:31 +03:00
|
|
|
static void notify()
|
2013-07-22 06:54:09 +03:00
|
|
|
{
|
|
|
|
SDL_UserEvent e = {
|
|
|
|
.type = SDL_USEREVENT,
|
|
|
|
.code = REPAINT_MENU,
|
|
|
|
.data1 = NULL,
|
|
|
|
.data2 = NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Inject an user event, that will be handled as a "repaint"
|
|
|
|
* event by the InputManager */
|
|
|
|
SDL_PushEvent((SDL_Event *) &e);
|
|
|
|
}
|
|
|
|
|
2013-08-06 22:55:31 +03:00
|
|
|
extern "C" Uint32 clockCallbackFunc(Uint32 timeout, void *d);
|
|
|
|
|
|
|
|
class Clock::Forwarder {
|
2013-08-07 03:57:44 +03:00
|
|
|
static unsigned int clockCallbackFunc(Clock *clock)
|
2013-08-06 22:55:31 +03:00
|
|
|
{
|
2013-08-07 03:57:44 +03:00
|
|
|
return clock->clockCallback();
|
2013-08-06 22:55:31 +03:00
|
|
|
}
|
|
|
|
friend Uint32 clockCallbackFunc(Uint32 timeout, void *d);
|
|
|
|
};
|
|
|
|
|
|
|
|
extern "C" Uint32 clockCallbackFunc(Uint32 timeout, void *d)
|
2013-07-22 06:54:09 +03:00
|
|
|
{
|
2013-08-07 03:57:44 +03:00
|
|
|
return Clock::Forwarder::clockCallbackFunc(static_cast<Clock *>(d));
|
2013-08-06 22:55:31 +03:00
|
|
|
}
|
2013-07-22 06:54:09 +03:00
|
|
|
|
2013-08-07 03:57:44 +03:00
|
|
|
unsigned int Clock::clockCallback()
|
2013-08-06 22:55:31 +03:00
|
|
|
{
|
2013-08-07 03:57:44 +03:00
|
|
|
unsigned int ms = update();
|
2013-07-22 06:54:09 +03:00
|
|
|
notify();
|
2013-08-07 03:57:44 +03:00
|
|
|
return ms;
|
2013-07-22 06:54:09 +03:00
|
|
|
}
|
|
|
|
|
2013-08-06 22:55:31 +03:00
|
|
|
std::string Clock::getTime(bool is24)
|
2013-07-22 06:54:09 +03:00
|
|
|
{
|
|
|
|
char buf[9];
|
|
|
|
int h = hours;
|
|
|
|
bool pm = hours >= 12;
|
|
|
|
|
|
|
|
if (!is24 && pm)
|
|
|
|
h -= 12;
|
|
|
|
|
|
|
|
sprintf(buf, "%02i:%02i%s", h, minutes, is24 ? "" : (pm ? "pm" : "am"));
|
2013-08-06 22:55:31 +03:00
|
|
|
return std::string(buf);
|
2013-07-22 06:54:09 +03:00
|
|
|
}
|
|
|
|
|
2013-08-07 03:57:44 +03:00
|
|
|
unsigned int Clock::update()
|
2013-07-22 06:54:09 +03:00
|
|
|
{
|
|
|
|
struct timeval tv;
|
|
|
|
struct tm result;
|
|
|
|
gettimeofday(&tv, NULL);
|
|
|
|
localtime_r(&tv.tv_sec, &result);
|
|
|
|
minutes = result.tm_min;
|
|
|
|
hours = result.tm_hour;
|
2013-08-07 03:57:44 +03:00
|
|
|
DEBUG("Time updated: %02i:%02i:%02i\n", hours, minutes, result.tm_sec);
|
|
|
|
|
|
|
|
// Compute number of milliseconds to next minute boundary.
|
|
|
|
// We don't need high precision, but it is important that any deviation is
|
|
|
|
// past the minute mark, so the fetched hour and minute number belong to
|
|
|
|
// the freshly started minute.
|
|
|
|
// Clamping it at 1 sec both avoids overloading the system in case our
|
|
|
|
// computation goes haywire and avoids passing 0 to SDL, which would stop
|
|
|
|
// the recurring timer.
|
|
|
|
return std::max(1, (60 - result.tm_sec)) * 1000;
|
2013-07-22 06:54:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void Clock::addTimer(int timeout)
|
|
|
|
{
|
2013-08-06 22:55:31 +03:00
|
|
|
timer = SDL_AddTimer(timeout, clockCallbackFunc, this);
|
2013-07-22 06:54:09 +03:00
|
|
|
if (timer == NULL)
|
|
|
|
ERROR("Could not initialize SDLTimer: %s\n", SDL_GetError());
|
|
|
|
}
|
|
|
|
|
2013-08-06 22:55:31 +03:00
|
|
|
Clock::Clock()
|
2013-07-22 06:54:09 +03:00
|
|
|
{
|
|
|
|
tzset();
|
|
|
|
|
2013-08-07 03:57:44 +03:00
|
|
|
unsigned int ms = update();
|
|
|
|
addTimer(ms);
|
2013-07-22 06:54:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
Clock::~Clock()
|
|
|
|
{
|
|
|
|
SDL_RemoveTimer(timer);
|
|
|
|
}
|