From a30ca384b0a794b35b2e930c5dfe426bcc035eb9 Mon Sep 17 00:00:00 2001 From: Rob Watson Date: Thu, 17 Sep 2020 13:46:14 +0200 Subject: [PATCH] Proof-of-concept: load and call player module from core --- frontend/core/Cargo.toml | 1 + .../core/src/components/waveform/canvas.rs | 2 +- frontend/core/src/lib.rs | 8 +++++ frontend/core/static/app.js | 32 ++++--------------- frontend/core/static/index.html | 6 +--- frontend/core/static/player.js | 30 +++++++++++++++++ frontend/player/src/lib.rs | 5 +-- 7 files changed, 51 insertions(+), 33 deletions(-) create mode 100644 frontend/core/static/player.js diff --git a/frontend/core/Cargo.toml b/frontend/core/Cargo.toml index 092a9f9..17845e9 100644 --- a/frontend/core/Cargo.toml +++ b/frontend/core/Cargo.toml @@ -17,6 +17,7 @@ futures = "0.3.5" cpal = { path = "/home/rob/dev/cpal", version = "0.12.1", features = ["wasm-bindgen"] } wasm-bindgen-futures = "0.4" console_error_panic_hook = "0.1.6" +weblog = "0.2" [dependencies.web-sys] version = "0.3.44" diff --git a/frontend/core/src/components/waveform/canvas.rs b/frontend/core/src/components/waveform/canvas.rs index 96f0166..35b3162 100644 --- a/frontend/core/src/components/waveform/canvas.rs +++ b/frontend/core/src/components/waveform/canvas.rs @@ -45,7 +45,7 @@ impl Component for Canvas { fn rendered(&mut self, first_render: bool) { if first_render { let cb = Closure::wrap(Box::new(|| { - ConsoleService::log(&format!("In setInterval callback")); + // ConsoleService::log(&format!("In setInterval callback")); }) as Box); // TODO: request_animation_frame() ? diff --git a/frontend/core/src/lib.rs b/frontend/core/src/lib.rs index 3fb7d68..67b9d01 100644 --- a/frontend/core/src/lib.rs +++ b/frontend/core/src/lib.rs @@ -6,15 +6,23 @@ extern crate js_sys; use std::panic; use wasm_bindgen::prelude::*; use yew::prelude::*; +use weblog::*; mod agents; mod components; mod utils; +#[wasm_bindgen(module = "/static/player.js")] +extern "C" { + fn get_val() -> i32; +} + #[wasm_bindgen(start)] pub fn run_app() { #[cfg(debug_assertions)] panic::set_hook(Box::new(console_error_panic_hook::hook)); + console_log!("Get value from player module:", get_val()); + App::::new().mount_to_body(); } diff --git a/frontend/core/static/app.js b/frontend/core/static/app.js index 5f11209..50727e1 100644 --- a/frontend/core/static/app.js +++ b/frontend/core/static/app.js @@ -1,43 +1,25 @@ -const { run_app } = wasm_bindgen; +import init from "/wasm/audioview_core.js"; -async function loadWasm() { +// https://github.com/rustwasm/wasm-bindgen/blob/master/examples/raytrace-parallel/index.js#L14 +function checkBrowser() { let msg = 'This demo requires a current version of Firefox (e.g., 79.0)'; if (typeof SharedArrayBuffer !== 'function') { alert('this browser does not have SharedArrayBuffer support enabled' + '\n\n' + msg); return } - // Test for bulk memory operations with passive data segments - // (module (memory 1) (data passive "")) const buf = new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x05, 0x03, 0x01, 0x00, 0x01, 0x0b, 0x03, 0x01, 0x01, 0x00]); if (!WebAssembly.validate(buf)) { alert('this browser does not support passive wasm memory, demo does not work' + '\n\n' + msg); return } - - let res = await wasm_bindgen('/wasm/audioview_player_bg.wasm'); - console.log(res); - //run_app(); } window.addEventListener("DOMContentLoaded", () => { - console.log("Loading wasm module..."); - loadWasm(); + checkBrowser(); - //console.log("Setting up audio worklet..."); - - //const ctx = new AudioContext(); - //ctx.audioWorklet.addModule("worklet.js?t=" + new Date().getTime()) - //.then(() => { - //const workletNode = new AudioWorkletNode(ctx, 'audio-worker'); - - //workletNode.connect(ctx.destination); - - //fetch('audioview.wasm?t=' + new Date().getTime()) - //.then(r => r.arrayBuffer()) - //.then(r => workletNode.port.postMessage({ type: 'loadWasm', data: r })) - //.catch(err => console.log(err)); - //}) - //.catch(err => console.error(err)); + // Initialize frontend/core wasm module, which loads the frontend/player module + // internally: + init(); }); diff --git a/frontend/core/static/index.html b/frontend/core/static/index.html index 332e972..eee456b 100644 --- a/frontend/core/static/index.html +++ b/frontend/core/static/index.html @@ -4,11 +4,7 @@ Audioview - - + diff --git a/frontend/core/static/player.js b/frontend/core/static/player.js new file mode 100644 index 0000000..b103b92 --- /dev/null +++ b/frontend/core/static/player.js @@ -0,0 +1,30 @@ +// Currently, in order to compile the player module in a way that can both +// utilize shared memory and be sent to an audio worklet, it seems necessary to +// generate JS bindings with --no-modules. +// +// https://github.com/rustwasm/wasm-bindgen/blob/master/examples/raytrace-parallel/build.sh#L18-L19 +// +// Therefore, in order to import the public player API into the frontend-core +// module, we create a simple ES6 module ourselves which loads the player wasm +// module and then exports the necessary functions. These can then be imported +// into the core module using an extern "C" block. +// +// I really don't know if it's the best possible approach at this time. But it +// works! + +let wasmModule; + +function init() { + console.log("Loading audioview_player wasm module..."); + + wasm_bindgen('/wasm/audioview_player_bg.wasm') + .then(mod => wasmModule = mod) + .then(() => console.log("Loaded audioview_player wasm module successfully")) + .catch(err => console.error); +} + +export function get_val() { + return wasmModule.get_val(); +} + +init(); diff --git a/frontend/player/src/lib.rs b/frontend/player/src/lib.rs index cb542ca..d11b7fb 100644 --- a/frontend/player/src/lib.rs +++ b/frontend/player/src/lib.rs @@ -1,5 +1,6 @@ use wasm_bindgen::prelude::*; -pub fn main() { - println!("Hello, world"); +#[wasm_bindgen] +pub fn get_val() -> i32 { + 123 }