#include "TimerClock.h" struct _TimerClock { GObject parent; TimerClockAction action; int interval; gpointer data; GThread *thread; gboolean running; gint64 lastTick; gint64 currentTime; }; G_DEFINE_TYPE(TimerClock, timer_clock, G_TYPE_OBJECT); static void timer_clock_thread_callback(TimerClock *self) { self->lastTick = g_get_monotonic_time() / 1000; while (self->running) { guint now = g_get_monotonic_time() / 1000; self->currentTime = now - self->lastTick; if (self->currentTime >= self->interval) { self->action(self->data); self->lastTick = now; self->currentTime = 0; } g_usleep(50); } } TimerClock *timer_clock_new(int interval, TimerClockAction action, gpointer data) { TimerClock *o = TIMER_CLOCK(g_object_new(TIMER_TYPE_CLOCK, NULL)); o->action = action; o->interval = interval; o->data = data; return o; } void timer_clock_start(TimerClock *self) { self->running = TRUE; self->thread = g_thread_new("timer", (GThreadFunc) timer_clock_thread_callback, self); } void timer_clock_stop(TimerClock *self) { self->running = FALSE; g_thread_join(self->thread); self->thread = NULL; } gboolean timer_clock_is_running(TimerClock *self) { return self->running; } static void timer_clock_finalize(GObject *self) { TIMER_CLOCK(self)->running = FALSE; if (TIMER_CLOCK(self)->thread != NULL) { g_thread_unref(TIMER_CLOCK(self)->thread); } G_OBJECT_CLASS(timer_clock_parent_class)->finalize(self); } static void timer_clock_class_init(TimerClockClass *class) { G_OBJECT_CLASS(class)->finalize = timer_clock_finalize; } static void timer_clock_init(TimerClock *self) { }