// Fill the environment with js functions we want to expose to the wasm module. // since we compile with -Wl,--allow-undefined, the linked does not complain // about undefined symbols. So we use make_environment to resolve from env below // and fail at runtime if a symbol is not found. function make_environment(...envs) { return new Proxy(envs, { get(_target, prop, _receiver) { for (let env of envs) { if (env.hasOwnProperty(prop)) { return env[prop]; } } return (...args) => { throw "NOT IMPLEMENTED: " + prop + " " + args + ""; } } }); } async function init() { const WIDTH = 800; const HEIGHT = 600; const { instance } = await WebAssembly.instantiateStreaming(fetch("./main.wasm"), { env: make_environment({}) }); const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); canvas.width = WIDTH; canvas.height = HEIGHT; // Fill the gradient before the first frame is displayed. instance.exports.init(); const ptr = instance.exports.get_buffer_ptr(); const len = instance.exports.get_buffer_len(); const image = new ImageData( new Uint8ClampedArray( instance.exports.memory.buffer, ptr, len * 4, ), WIDTH, ); let previousTimestamp; const render = (timestamp) => { const dt = previousTimestamp === undefined ? 0 : Math.min((timestamp - previousTimestamp) / 1000, 0.05); previousTimestamp = timestamp; instance.exports.render_frame(dt); ctx.putImageData(image, 0, 0); window.requestAnimationFrame(render); }; window.requestAnimationFrame(render); } init();