diff options
Diffstat (limited to 'src/web.zig')
| -rw-r--r-- | src/web.zig | 36 |
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, |
