diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index 27ccd5f2a..f66096a38 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -10,7 +10,6 @@ #include "screen.h" #include "fonts.h" #include "charsets.h" -#include "timers.h" #include #include #include @@ -769,13 +768,9 @@ cm_thread_write(PyObject UNUSED *self, PyObject *args) { Py_RETURN_NONE; } -static EventLoopData main_event_loop = {0}; - static inline void wait_for_events() { - maximum_wait = prepare_for_poll(&main_event_loop, maximum_wait); event_loop_wait(maximum_wait); - dispatch_timers(&main_event_loop); maximum_wait = -1; } @@ -797,9 +792,9 @@ static PyObject* add_python_timer(PyObject *self UNUSED, PyObject *args) { PyObject *callback; double interval; - const char *name; - if (!PyArg_ParseTuple(args, "sOd", &name, &callback, &interval)) return NULL; - unsigned long long timer_id = add_timer(&main_event_loop, name, interval, 1, python_timer_callback, callback, python_timer_cleanup); + int repeats = 1; + if (!PyArg_ParseTuple(args, "Od|p", &callback, &interval, &repeats)) return NULL; + unsigned long long timer_id = add_main_loop_timer(interval, repeats ? true: false, python_timer_callback, callback, python_timer_cleanup); Py_INCREF(callback); return Py_BuildValue("K", timer_id); } @@ -808,16 +803,7 @@ static PyObject* remove_python_timer(PyObject *self UNUSED, PyObject *args) { unsigned long long timer_id; if (!PyArg_ParseTuple(args, "K", &timer_id)) return NULL; - remove_timer(&main_event_loop, timer_id); - Py_RETURN_NONE; -} - -static PyObject* -change_python_timer_interval(PyObject *self UNUSED, PyObject *args) { - unsigned long long timer_id; - double interval; - if (!PyArg_ParseTuple(args, "Kd", &timer_id, &interval)) return NULL; - change_timer_interval(&main_event_loop, timer_id, interval); + remove_main_loop_timer(timer_id); Py_RETURN_NONE; } @@ -919,7 +905,6 @@ main_loop(ChildMonitor *self, PyObject *a UNUSED) { report_reaped_pids(); has_open_windows = process_pending_closes(self); } - remove_all_timers(&main_event_loop); #ifdef __APPLE__ if (cocoa_pending_actions_wd) { free(cocoa_pending_actions_wd); cocoa_pending_actions_wd = NULL; } #endif @@ -1528,7 +1513,6 @@ static PyMethodDef module_methods[] = { METHODB(safe_pipe, METH_NOARGS), {"add_timer", (PyCFunction)add_python_timer, METH_VARARGS, ""}, {"remove_timer", (PyCFunction)remove_python_timer, METH_VARARGS, ""}, - {"change_timer_interval", (PyCFunction)change_python_timer_interval, METH_VARARGS, ""}, METHODB(monitor_pid, METH_VARARGS), {"set_iutf8", (PyCFunction)pyset_iutf8, METH_VARARGS, ""}, {NULL} /* Sentinel */ diff --git a/kitty/timers.c b/kitty/timers.c deleted file mode 100644 index e3716829f..000000000 --- a/kitty/timers.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * timers.c - * Copyright (C) 2019 Kovid Goyal - * - * Distributed under terms of the GPL3 license. - */ - -#include "timers.h" -#include - -static id_type timer_counter = 0; - -static int -compare_timers(const void *a_, const void *b_) { - const Timer *a = (const Timer*)a_, *b = (const Timer*)b_; - return (a->trigger_at > b->trigger_at) ? 1 : (a->trigger_at < b->trigger_at) ? -1 : 0; -} - -static inline void -update_timers(EventLoopData *eld) { - if (eld->timers_count > 1) qsort(eld->timers, eld->timers_count, sizeof(eld->timers[0]), compare_timers); -} - -id_type -add_timer(EventLoopData *eld, const char *name, double interval, int enabled, timer_callback_func cb, void *cb_data, timer_cleanup_func cleanup) { - if (eld->timers_count >= sizeof(eld->timers)/sizeof(eld->timers[0])) { - fprintf(stderr, "Too many timers added\n"); - return 0; - } - Timer *t = eld->timers + eld->timers_count++; - t->interval = interval; - t->name = name; - t->trigger_at = enabled ? monotonic() + interval : DBL_MAX; - t->callback = cb; - t->callback_data = cb_data; - t->cleanup = cleanup; - t->id = ++timer_counter; - update_timers(eld); - return t->id; -} - - -void -remove_timer(EventLoopData *eld, id_type timer_id) { - for (nfds_t i = 0; i < eld->timers_count; i++) { - if (eld->timers[i].id == timer_id) { - if (eld->timers[i].cleanup) eld->timers[i].cleanup(timer_id, eld->timers[i].callback_data); - remove_i_from_array(eld->timers, i, eld->timers_count); - update_timers(eld); - break; - } - } -} - -void -remove_all_timers(EventLoopData *eld) { - while (eld->timers_count) { - eld->timers_count--; - if (eld->timers[eld->timers_count].cleanup) eld->timers[eld->timers_count].cleanup(eld->timers[eld->timers_count].id, eld->timers[eld->timers_count].callback_data); - } -} - -void -toggle_timer(EventLoopData *eld, id_type timer_id, int enabled) { - for (nfds_t i = 0; i < eld->timers_count; i++) { - if (eld->timers[i].id == timer_id) { - double trigger_at = enabled ? (monotonic() + eld->timers[i].interval) : DBL_MAX; - if (trigger_at != eld->timers[i].trigger_at) { - eld->timers[i].trigger_at = trigger_at; - update_timers(eld); - } - break; - } - } -} - -void -change_timer_interval(EventLoopData *eld, id_type timer_id, double interval) { - for (nfds_t i = 0; i < eld->timers_count; i++) { - if (eld->timers[i].id == timer_id) { - eld->timers[i].interval = interval; - break; - } - } -} - - -double -prepare_for_poll(EventLoopData *eld, double timeout) { - if (!eld->timers_count || eld->timers[0].trigger_at == DBL_MAX) return timeout; - double now = monotonic(), next_repeat_at = eld->timers[0].trigger_at; - if (timeout < 0 || now + timeout > next_repeat_at) { - timeout = next_repeat_at <= now ? 0 : next_repeat_at - now; - } - return timeout; -} - -unsigned int -dispatch_timers(EventLoopData *eld) { - if (!eld->timers_count || eld->timers[0].trigger_at == DBL_MAX) return 0; - static struct { timer_callback_func func; id_type id; void* data; } dispatches[sizeof(eld->timers)/sizeof(eld->timers[0])]; - unsigned int num_dispatches = 0; - double now = monotonic(); - for (nfds_t i = 0; i < eld->timers_count && eld->timers[i].trigger_at <= now; i++) { - eld->timers[i].trigger_at = now + eld->timers[i].interval; - dispatches[num_dispatches].func = eld->timers[i].callback; - dispatches[num_dispatches].id = eld->timers[i].id; - dispatches[num_dispatches].data = eld->timers[i].callback_data; - num_dispatches++; - } - // we dispatch separately so that the callbacks can modify timers - for (unsigned i = 0; i < num_dispatches; i++) { - dispatches[i].func(dispatches[i].id, dispatches[i].data); - } - if (num_dispatches) update_timers(eld); - return num_dispatches; -} diff --git a/kitty/timers.h b/kitty/timers.h deleted file mode 100644 index b0260a538..000000000 --- a/kitty/timers.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2019 Kovid Goyal - * - * Distributed under terms of the GPL3 license. - */ - -#pragma once - -#include "data-types.h" - -typedef void(*timer_callback_func)(id_type, void*); -typedef void(*timer_cleanup_func)(id_type, void*); - -typedef struct { - id_type id; - double interval, trigger_at; - timer_callback_func callback; - timer_cleanup_func cleanup; - void *callback_data; - const char *name; -} Timer; - - -typedef struct { - nfds_t timers_count; - Timer timers[128]; -} EventLoopData; - - -double prepare_for_poll(EventLoopData *eld, double timeout); -id_type add_timer(EventLoopData *eld, const char *name, double interval, int enabled, timer_callback_func cb, void *cb_data, timer_cleanup_func cleanup); -void remove_timer(EventLoopData *eld, id_type timer_id); -void remove_all_timers(EventLoopData *eld); -void toggle_time(EventLoopData *eld, id_type timer_id, int enabled); -void change_timer_interval(EventLoopData *eld, id_type timer_id, double interval); -unsigned int dispatch_timers(EventLoopData *eld); diff --git a/kitty/update_check.py b/kitty/update_check.py index 62c480825..c8765fd56 100644 --- a/kitty/update_check.py +++ b/kitty/update_check.py @@ -122,4 +122,4 @@ def update_check(timer_id=None): def run_update_check(interval=24 * 60 * 60): if update_check(): - add_timer('update_check', update_check, interval) + add_timer(update_check, interval)