diff --git a/src/platform/mach.js b/src/platform/mach.js index 168cffb5..ba896ff3 100644 --- a/src/platform/mach.js +++ b/src/platform/mach.js @@ -140,6 +140,9 @@ const mach = { observer: undefined, events: [], changes: [], + update: undefined, + wait_event_timeout: 0, + wait_event_timer: undefined, init(wasm) { this.wasm = wasm; @@ -181,6 +184,14 @@ const mach = { throw Error(mach.getString(str, len)); }, + machClearEventTimer() { + if (mach.wait_event_timer !== undefined) { + clearTimeout(mach.wait_event_timer); + mach.wait_event_timer = undefined; + window.requestAnimationFrame(mach.update); + } + }, + machCanvasInit(width, height, id) { let canvas = document.createElement("canvas"); canvas.id = "#mach-canvas-" + mach.canvases.length; @@ -198,32 +209,39 @@ const mach = { canvas.addEventListener("keydown", (ev) => { mach.events.push(...[1, convertKeyCode(ev.code)]); + mach.machClearEventTimer(); }); canvas.addEventListener("keyup", (ev) => { mach.events.push(...[2, convertKeyCode(ev.code)]); + mach.machClearEventTimer(); }); canvas.addEventListener("mousemove", (ev) => { mach.events.push(...[3, ev.clientX, ev.clientY]); + mach.machClearEventTimer(); }); canvas.addEventListener("mousedown", (ev) => { mach.events.push(...[4, ev.button]); + mach.machClearEventTimer(); }); canvas.addEventListener("mouseup", (ev) => { mach.events.push(...[5, ev.button]); + mach.machClearEventTimer(); }); canvas.addEventListener("wheel", (ev) => { mach.events.push(...[6, ev.deltaX, ev.deltaY]); + mach.machClearEventTimer(); }); canvas.addEventListener("mach-canvas-resize", (ev) => { const cv_index = mach.canvases.findIndex((el) => el.canvas === ev.currentTarget); const cv = mach.canvases[cv_index]; mach.changes.push(...[1, cv.canvas.width, cv.canvas.height, window.devicePixelRatio]); + mach.machClearEventTimer(); }); document.body.appendChild(canvas); @@ -278,8 +296,16 @@ const mach = { window.dispatchEvent(new Event("mach-close")); }, + machSetWaitEvent(timeout) { + mach.wait_event_timeout = timeout; + }, + + machHasEvent() { + return (mach.events.length > 0); + }, + machEventShift() { - if (mach.events.length < 0) + if (mach.events.length === 0) return 0; return mach.events.shift(); @@ -290,7 +316,7 @@ const mach = { }, machChangeShift() { - if (mach.changes.length < 0) + if (mach.changes.length === 0) return 0; return mach.changes.shift(); diff --git a/src/platform/wasm.zig b/src/platform/wasm.zig index ae6cf379..3d015e8e 100644 --- a/src/platform/wasm.zig +++ b/src/platform/wasm.zig @@ -14,6 +14,8 @@ const js = struct { extern fn machCanvasGetFramebufferWidth(canvas: CanvasId) u32; extern fn machCanvasGetFramebufferHeight(canvas: CanvasId) u32; extern fn machEmitCloseEvent() void; + extern fn machSetWaitEvent(timeout: f64) void; + extern fn machHasEvent() bool; extern fn machEventShift() i32; extern fn machEventShiftFloat() f64; extern fn machChangeShift() u32; @@ -68,6 +70,10 @@ pub const Platform = struct { if (value) js.machEmitCloseEvent(); } + pub fn setWaitEvent(_: *Platform, timeout: f64) void { + js.machSetWaitEvent(timeout); + } + pub fn getFramebufferSize(platform: *Platform) structs.Size { return platform.last_framebuffer_size; } @@ -99,6 +105,10 @@ pub const Platform = struct { } } + pub fn hasEvent(_: *Platform) bool { + return js.machHasEvent(); + } + pub fn pollEvent(_: *Platform) ?structs.Event { const event_type = js.machEventShift(); diff --git a/www/template.html b/www/template.html index 84eedd27..1eff36e9 100644 --- a/www/template.html +++ b/www/template.html @@ -28,9 +28,19 @@ let update = function() {{ if (!frame) return; instance.exports.wasmUpdate(); - window.requestAnimationFrame(update); + if (mach.wait_event_timeout > 0) {{ + mach.wait_event_timer = setTimeout(() => {{ + window.requestAnimationFrame(update); + }}, + mach.wait_event_timeout * 1000); + }} + else {{ + window.requestAnimationFrame(update); + }} }}; + mach.update = update; + window.requestAnimationFrame(update); window.addEventListener("mach-close", () => {{