summaryrefslogtreecommitdiff
path: root/src/web.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/web.zig')
-rw-r--r--src/web.zig36
1 files changed, 17 insertions, 19 deletions
diff --git a/src/web.zig b/src/web.zig
index b77d07a6..532e3794 100644
--- a/src/web.zig
+++ b/src/web.zig
@@ -1,7 +1,7 @@
//! Freestanding WebAssembly boundary for the DOM backend.
//!
//! JavaScript owns the clock and nothing else: it calls `pardes_tick` (one
-//! `Pardes.pump`) and reads the packed cell buffer `present` left behind. The
+//! `Pardes.pump`, at requestAnimationFrame's timestamp) and reads the packed cell buffer `present` left behind. The
//! host vtable below is only what a page genuinely has — pixels, the
//! clipboard, links, downloads. Processes, a real filesystem, a language
//! backend and subprocess pipes are left null, so the core answers them itself
@@ -106,6 +106,9 @@ const State = struct {
frame_len: usize = 0,
frame_cols: u16 = 0,
frame_rows: u16 = 0,
+ /// requestAnimationFrame's timestamp as the last tick gave it, in ns:
+ /// the core's clock (`Host.now`).
+ now_ns: u64 = 0,
fn init(cols: u16, rows: u16) !State {
const allocs = pardes.memory.init(gpa);
@@ -276,30 +279,19 @@ export fn pardes_pointer_leave() void {
s.core.update(.pointer_leave);
}
-/// One iteration of the core's own loop: queued input, effects, render,
-/// present. JS calls it once per animation frame, after spending that frame's
-/// animation ticks.
-export fn pardes_tick() void {
+/// One iteration of the core's own loop: queued input, effects, the frames
+/// of animation `timestamp_ms` (requestAnimationFrame's clock) has brought,
+/// render, present. JS calls it once per display frame; a call with no
+/// timestamp (NaN) leaves the clock where it was.
+export fn pardes_tick(timestamp_ms: f64) void {
const s = &(state orelse return);
+ if (std.math.isFinite(timestamp_ms) and timestamp_ms >= 0)
+ s.now_ns = @intFromFloat(timestamp_ms * std.time.ns_per_ms);
s.core.pump(host(s)) catch |err| {
last_error = @intFromError(err);
};
}
-/// Spend one fixed 60 Hz animation step, the only writer of animated time in
-/// this host. Separate from the pump for the reason the AppKit shell keeps them
-/// separate: if every input pump also advanced the transition, a burst of keys
-/// would collapse a ten-frame fade into one display frame.
-export fn pardes_animation_tick() void {
- const s = &(state orelse return);
- s.core.update(.tick);
-}
-
-export fn pardes_animating() u32 {
- const s = &(state orelse return 0);
- return @intFromBool(s.core.animationActive());
-}
-
/// The Exit builtin, or the last pane closing. JS stops its frame loop.
export fn pardes_should_quit() u32 {
const s = &(state orelse return 0);
@@ -462,7 +454,13 @@ extern "pardes" fn host_download(
bytes_len: usize,
) callconv(.c) void;
+fn now(ctx: ?*anyopaque) u64 {
+ const s: *State = @ptrCast(@alignCast(ctx.?));
+ return s.now_ns;
+}
+
const vtable: pardes.Host.VTable = .{
+ .now = now,
.present = present,
.write_file = writeFile,
.write_dump = writeDump,