practice-timer/TimerClock.c

70 lines
1.7 KiB
C

#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) {
}