Use the new glfw timers to get rid of the kitty specific timers
This commit is contained in:
parent
da507dfd19
commit
f10c65f1bf
@ -10,7 +10,6 @@
|
|||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "fonts.h"
|
#include "fonts.h"
|
||||||
#include "charsets.h"
|
#include "charsets.h"
|
||||||
#include "timers.h"
|
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
@ -769,13 +768,9 @@ cm_thread_write(PyObject UNUSED *self, PyObject *args) {
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EventLoopData main_event_loop = {0};
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
wait_for_events() {
|
wait_for_events() {
|
||||||
maximum_wait = prepare_for_poll(&main_event_loop, maximum_wait);
|
|
||||||
event_loop_wait(maximum_wait);
|
event_loop_wait(maximum_wait);
|
||||||
dispatch_timers(&main_event_loop);
|
|
||||||
maximum_wait = -1;
|
maximum_wait = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -797,9 +792,9 @@ static PyObject*
|
|||||||
add_python_timer(PyObject *self UNUSED, PyObject *args) {
|
add_python_timer(PyObject *self UNUSED, PyObject *args) {
|
||||||
PyObject *callback;
|
PyObject *callback;
|
||||||
double interval;
|
double interval;
|
||||||
const char *name;
|
int repeats = 1;
|
||||||
if (!PyArg_ParseTuple(args, "sOd", &name, &callback, &interval)) return NULL;
|
if (!PyArg_ParseTuple(args, "Od|p", &callback, &interval, &repeats)) return NULL;
|
||||||
unsigned long long timer_id = add_timer(&main_event_loop, name, interval, 1, python_timer_callback, callback, python_timer_cleanup);
|
unsigned long long timer_id = add_main_loop_timer(interval, repeats ? true: false, python_timer_callback, callback, python_timer_cleanup);
|
||||||
Py_INCREF(callback);
|
Py_INCREF(callback);
|
||||||
return Py_BuildValue("K", timer_id);
|
return Py_BuildValue("K", timer_id);
|
||||||
}
|
}
|
||||||
@ -808,16 +803,7 @@ static PyObject*
|
|||||||
remove_python_timer(PyObject *self UNUSED, PyObject *args) {
|
remove_python_timer(PyObject *self UNUSED, PyObject *args) {
|
||||||
unsigned long long timer_id;
|
unsigned long long timer_id;
|
||||||
if (!PyArg_ParseTuple(args, "K", &timer_id)) return NULL;
|
if (!PyArg_ParseTuple(args, "K", &timer_id)) return NULL;
|
||||||
remove_timer(&main_event_loop, timer_id);
|
remove_main_loop_timer(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);
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -919,7 +905,6 @@ main_loop(ChildMonitor *self, PyObject *a UNUSED) {
|
|||||||
report_reaped_pids();
|
report_reaped_pids();
|
||||||
has_open_windows = process_pending_closes(self);
|
has_open_windows = process_pending_closes(self);
|
||||||
}
|
}
|
||||||
remove_all_timers(&main_event_loop);
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
if (cocoa_pending_actions_wd) { free(cocoa_pending_actions_wd); cocoa_pending_actions_wd = NULL; }
|
if (cocoa_pending_actions_wd) { free(cocoa_pending_actions_wd); cocoa_pending_actions_wd = NULL; }
|
||||||
#endif
|
#endif
|
||||||
@ -1528,7 +1513,6 @@ static PyMethodDef module_methods[] = {
|
|||||||
METHODB(safe_pipe, METH_NOARGS),
|
METHODB(safe_pipe, METH_NOARGS),
|
||||||
{"add_timer", (PyCFunction)add_python_timer, METH_VARARGS, ""},
|
{"add_timer", (PyCFunction)add_python_timer, METH_VARARGS, ""},
|
||||||
{"remove_timer", (PyCFunction)remove_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),
|
METHODB(monitor_pid, METH_VARARGS),
|
||||||
{"set_iutf8", (PyCFunction)pyset_iutf8, METH_VARARGS, ""},
|
{"set_iutf8", (PyCFunction)pyset_iutf8, METH_VARARGS, ""},
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
|
|||||||
117
kitty/timers.c
117
kitty/timers.c
@ -1,117 +0,0 @@
|
|||||||
/*
|
|
||||||
* timers.c
|
|
||||||
* Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net>
|
|
||||||
*
|
|
||||||
* Distributed under terms of the GPL3 license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "timers.h"
|
|
||||||
#include <float.h>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net>
|
|
||||||
*
|
|
||||||
* 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);
|
|
||||||
@ -122,4 +122,4 @@ def update_check(timer_id=None):
|
|||||||
|
|
||||||
def run_update_check(interval=24 * 60 * 60):
|
def run_update_check(interval=24 * 60 * 60):
|
||||||
if update_check():
|
if update_check():
|
||||||
add_timer('update_check', update_check, interval)
|
add_timer(update_check, interval)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user