aboutsummaryrefslogtreecommitdiffstats
path: root/src/screen.c
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-26 17:58:26 +0100
committereunhhu <[email protected]>2026-09-26 17:58:26 +0100
commitb466603358f8fa5a74551a9819fdd54ad124ef0c (patch)
tree6f34265f30455589201222521c1a452274a0601d /src/screen.c
parent15c4616e19d997c64a983e39501289c7d9f50d0a (diff)
downloadvega-b466603358f8fa5a74551a9819fdd54ad124ef0c.tar.gz
vega-b466603358f8fa5a74551a9819fdd54ad124ef0c.zip
Give live surfaces a clock and run timers; add a stopwatch
The terminal and the web page set the time events see to the wall clock and tick an app's timers on time: each round ticks what is due, draws, then waits for input, a frame or the next tick, and a tick is news to every open page at once. Scripts have no clock: time MS sets the time the next events see and tick TIMER ticks, so an app that uses time replays exactly. A module swap reschedules the timers. examples/stopwatch.aup runs on every surface; the checks drive it by script, on a pseudo-terminal by the clock, and on the web page.
Diffstat (limited to 'src/screen.c')
-rw-r--r--src/screen.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/screen.c b/src/screen.c
index 56c2cf9..fdecaf4 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -1,7 +1,36 @@
+#define _POSIX_C_SOURCE 200809L
#include "vega.h"
#include "module-text.h"
#include <math.h>
#include <string.h>
+#include <time.h>
+
+double vega_now(void) {
+ struct timespec t;
+ clock_gettime(CLOCK_REALTIME, &t);
+ return floor((double)t.tv_sec * 1000 + (double)t.tv_nsec / 1e6);
+}
+
+void vega_timers_start(VegaTimers *timers, const PureModule *m, double now) {
+ for (uint32_t i = 0; i < m->inputs; ++i)
+ timers->next[i] = m->input[i].kind == PURE_KIND_TIMER ? now + m->input[i].period : 0;
+}
+
+long vega_timers_run(VegaTimers *timers, PureApp *app, double now, bool *ticked) {
+ const PureModule *m = app->module;
+ double soonest = -1;
+ for (uint32_t i = 0; i < m->inputs; ++i) {
+ if (m->input[i].kind != PURE_KIND_TIMER) continue;
+ if (timers->next[i] <= now) {
+ app->now = now;
+ pure_app_tick(app, i); /* a failed tick changes nothing, as any failed event */
+ *ticked = true;
+ timers->next[i] = now + m->input[i].period;
+ }
+ if (soonest < 0 || timers->next[i] - now < soonest) soonest = timers->next[i] - now;
+ }
+ return soonest < 0 ? -1 : (long)ceil(soonest);
+}
static unsigned long evaluations;