diff options
| author | LLLL Colonq <llll@colonq> | 2024-08-16 15:29:23 -0400 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2024-08-16 15:29:23 -0400 |
| commit | 7874c1d28bccbd4e089e0a7a2a8c8ad005aa09e8 (patch) | |
| tree | b3dd88f550b7e1b77a8ab63759362fba405f0ac4 | |
| parent | 2b0a405e36e346ff1b8fe33cc359918b210ef6f3 (diff) | |
Update
| -rw-r--r-- | Cargo.toml | 5 | ||||
| -rw-r--r-- | src/js/module.js | 7 | ||||
| -rw-r--r-- | src/lib.rs | 121 | ||||
| -rw-r--r-- | src/module.rs | 45 |
4 files changed, 119 insertions, 59 deletions
@@ -4,6 +4,9 @@ version = "0.1.0" authors = ["LLLL Colonq <llll@colonq.computer>"] edition = "2021" +[lib] +crate-type = ["cdylib", "rlib"] + [profile.release] opt-level = 2 codegen-units = 1 @@ -27,7 +30,7 @@ console_error_panic_hook = "*" # log to browser console on panic tracing-wasm = "*" # trace performance in browser wasm-bindgen = "*" # interface with javascript wasm-bindgen-futures = "*" # interface with async javascript -js-sys = "*" +js-sys = "*" # browser APIs to interact with JS runtime (e.g. run WASM) [dependencies.web-sys] # common browser APIs version = "*" diff --git a/src/js/module.js b/src/js/module.js new file mode 100644 index 0000000..f7bff39 --- /dev/null +++ b/src/js/module.js @@ -0,0 +1,7 @@ +export function js_build_interface() { + return { + env: { + log_info: window.wasmBindings.log_info, + }, + }; +} @@ -12,6 +12,7 @@ pub mod texture; pub mod font; pub mod audio; pub mod shadow; +pub mod module; static mut CTX: Option<*const context::Context> = None; static mut ST: Option<*mut state::State> = None; @@ -29,7 +30,12 @@ where } } -pub fn run<F, G>(gnew: F) where G: state::Game + 'static, F: (Fn(&context::Context) -> G) { +pub async fn run<'a, F, G, Fut>(gnew: F) +where + Fut: std::future::Future<Output = G>, + G: state::Game + 'static, + F: (Fn(&'a context::Context) -> Fut), +{ console_log::init_with_level(log::Level::Debug).unwrap(); console_error_panic_hook::set_once(); tracing_wasm::set_as_global_default(); @@ -46,8 +52,8 @@ pub fn run<F, G>(gnew: F) where G: state::Game + 'static, F: (Fn(&context::Conte let ctx = Box::leak(Box::new(context::Context::new(window))); ctx.maximize_canvas(); - let mut game = Box::leak(Box::new(gnew(ctx))); - let mut st = Box::leak(Box::new(state::State::new(&ctx))); + let game = Box::leak(Box::new(gnew(ctx).await)); + let st = Box::leak(Box::new(state::State::new(&ctx))); unsafe { CTX = Some(ctx as _); @@ -56,69 +62,68 @@ pub fn run<F, G>(gnew: F) where G: state::Game + 'static, F: (Fn(&context::Conte } st.write_log("test"); - st.write_log("foo"); - st.write_log("bar"); - st.write_log("baz"); event_loop.set_control_flow(winit::event_loop::ControlFlow::Wait); - event_loop.spawn(move |event, elwt| { - match event { - winit::event::Event::WindowEvent { - event: wev, - window_id, - .. - } => match wev { - winit::event::WindowEvent::CloseRequested - if window_id == ctx.window.id() => elwt.exit(), - winit::event::WindowEvent::Resized{..} => { - ctx.maximize_canvas(); - st.handle_resize(&ctx); - }, - winit::event::WindowEvent::Focused(false) => { - st.keys = state::Keys::new(); - }, - winit::event::WindowEvent::MouseInput { - button, - state, + event_loop.spawn(|event, elwt| { + contextualize(|ctx, st, game: &mut G| { + match &event { + winit::event::Event::WindowEvent { + event: wev, + window_id, .. - } => match state { - winit::event::ElementState::Pressed => { - st.mouse_pressed(&ctx, button, game) + } => match wev { + winit::event::WindowEvent::CloseRequested + if *window_id == ctx.window.id() => elwt.exit(), + winit::event::WindowEvent::Resized{..} => { + ctx.maximize_canvas(); + st.handle_resize(&ctx); }, - winit::event::ElementState::Released => { - st.mouse_released(&ctx, button) + winit::event::WindowEvent::Focused(false) => { + st.keys = state::Keys::new(); }, - } - winit::event::WindowEvent::KeyboardInput { - event: winit::event::KeyEvent { - physical_key: winit::keyboard::PhysicalKey::Code(key), + winit::event::WindowEvent::MouseInput { + button, state, - repeat: false, .. - }, - .. - } => match state { - winit::event::ElementState::Pressed => { - st.key_pressed(&ctx, key) - }, - winit::event::ElementState::Released => { - st.key_released(&ctx, key) - }, - } - _ => {}, - }, + } => match state { + winit::event::ElementState::Pressed => { + st.mouse_pressed(&ctx, *button, game) + }, + winit::event::ElementState::Released => { + st.mouse_released(&ctx, *button) + }, + } + winit::event::WindowEvent::KeyboardInput { + event: winit::event::KeyEvent { + physical_key: winit::keyboard::PhysicalKey::Code(key), + state, + repeat: false, + .. + }, + .. + } => match state { + winit::event::ElementState::Pressed => { + st.key_pressed(&ctx, *key) + }, + winit::event::ElementState::Released => { + st.key_released(&ctx, *key) + }, + } + _ => {}, + }, - winit::event::Event::AboutToWait => { - if ctx.resize_necessary() { - ctx.maximize_canvas(); - st.handle_resize(&ctx); - } - st.run_update(&ctx, game); - st.run_render(&ctx, game); - ctx.window.request_redraw(); - }, + winit::event::Event::AboutToWait => { + if ctx.resize_necessary() { + ctx.maximize_canvas(); + st.handle_resize(&ctx); + } + st.run_update(&ctx, game); + st.run_render(&ctx, game); + ctx.window.request_redraw(); + }, - _ => {}, - } + _ => {}, + } + }); }); } diff --git a/src/module.rs b/src/module.rs new file mode 100644 index 0000000..1fc4100 --- /dev/null +++ b/src/module.rs @@ -0,0 +1,45 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn log_info(msg: i8) { + log::info!("{:?}", msg); +} + +#[wasm_bindgen(module="/src/js/module.js")] +extern "C" { + fn js_build_interface() -> js_sys::Object; +} + +pub struct Module { + pub wasm: js_sys::WebAssembly::Instance, +} + +impl Module { + pub async fn new(bytes: &[u8]) -> Option<Self> { + let imp = js_build_interface(); + let o = wasm_bindgen_futures::JsFuture::from( + js_sys::WebAssembly::instantiate_buffer(bytes, &imp) + ).await.unwrap(); + let i = js_sys::Reflect::get(&o, &"instance".into()).unwrap(); + if let Ok(wasm) = i.dyn_into::<js_sys::WebAssembly::Instance>() { + Some(Self { + wasm, + }) + } else { + log::info!("failed 3"); + None + } + } + pub fn call(&self, nm: &str) { + let exp = self.wasm.exports(); + if let Ok(fo) = js_sys::Reflect::get(&exp, &nm.into()) { + if let Ok(func) = fo.dyn_into::<js_sys::Function>() { + let _ = func.call0(&JsValue::undefined()); + } else { + log::warn!("couldn't cast module function: {}", nm); + } + } else { + log::warn!("couldn't find module function: {}", nm); + } + } +} |
