From e8f85e4a723b772c099a3c03a6cb721c48561e4b Mon Sep 17 00:00:00 2001 From: Mica White Date: Mon, 6 Jul 2026 13:59:36 -0400 Subject: Fully support WASM (in some contexts) --- src/script.rs | 94 ++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 26 deletions(-) (limited to 'src/script.rs') diff --git a/src/script.rs b/src/script.rs index 861f665..2de50f5 100644 --- a/src/script.rs +++ b/src/script.rs @@ -2,7 +2,9 @@ use std::path::Path; use rustc_hash::FxHashMap; -use crate::{buffer::Buffer, file::FileManager, input::InputManager}; +use crate::{buffer::Buffer, file::FileManager, input::InputManager, time::TimeContext}; + +mod wasm; pub struct ScriptManager<'a> { scripts: &'a [ScriptDeclaration], @@ -12,16 +14,18 @@ pub struct ScriptManager<'a> { pub struct WasmRunner { pub engine: wasmi::Engine, - pub linker: wasmi::Linker<&'static ScriptContext<'static>>, + pub linker: wasmi::Linker<&'static mut ScriptContext<'static>>, } pub struct ScriptContext<'a> { pub buffer: &'a mut Buffer, pub input: &'a InputManager, + pub time: &'a TimeContext, } type StaticScriptFunction = Option, &mut Box<[u8]>)>; +#[derive(Debug, Clone)] pub enum ScriptDeclaration { Static { start: StaticScriptFunction, @@ -53,7 +57,12 @@ impl Default for WasmRunner { impl WasmRunner { pub fn new() -> Self { let engine = wasmi::Engine::default(); - let linker = wasmi::Linker::new(&engine); + let linker = unsafe { + std::mem::transmute::< + wasmi::Linker<&mut ScriptContext<'_>>, + wasmi::Linker<&mut ScriptContext<'_>>, + >(wasm::linker(&engine).unwrap()) + }; Self { engine, linker } } @@ -69,14 +78,26 @@ impl WasmRunner { ) -> Result<(), wasmi::Error> { // safety: the store won't be kept around after this function ends. Only the // lifetimes are being transmuted - let mut store = wasmi::Store::new(&self.engine, unsafe { - std::mem::transmute::<&ScriptContext<'_>, &ScriptContext<'_>>(context) - }); - let instance = self.linker.instantiate_and_start(&mut store, module)?; - let function = instance.get_func(&store, function_name).ok_or_else(|| { - wasmi::Error::new(format!("No function named {function_name} was exported")) - })?; - function.call(&mut store, &[], &mut []) + let mut store = { + puffin::profile_scope!("create store"); + wasmi::Store::new(&self.engine, unsafe { + std::mem::transmute::<&mut ScriptContext<'_>, &mut ScriptContext<'_>>(context) + }) + }; + let instance = { + puffin::profile_scope!("instantiate"); + self.linker.instantiate_and_start(&mut store, module)? + }; + let function = { + puffin::profile_scope!("get function"); + instance.get_func(&store, function_name).ok_or_else(|| { + wasmi::Error::new(format!("No function named {function_name} was exported")) + })? + }; + { + puffin::profile_scope!("call function"); + function.call(&mut store, &[], &mut []) + } } } @@ -89,6 +110,35 @@ impl<'a> ScriptManager<'a> { } } + pub fn preload_script( + &self, + script_id: usize, + files: &mut FileManager, + wasm_runner: &WasmRunner, + ) { + let script = &self.scripts[script_id]; + match script { + ScriptDeclaration::Static { .. } => (), + ScriptDeclaration::Wasm { path } => files.start_loading_file(path, &wasm_runner.engine), + } + } + + pub fn is_script_loaded(&self, script_id: usize, files: &mut FileManager) -> bool { + let script = &self.scripts[script_id]; + match script { + ScriptDeclaration::Static { .. } => true, + ScriptDeclaration::Wasm { path } => files.is_file_loaded(path), + } + } + + pub fn unload_script(&self, script_id: usize, files: &mut FileManager) { + let script = &self.scripts[script_id]; + match script { + ScriptDeclaration::Static { .. } => (), + ScriptDeclaration::Wasm { path } => files.unload_file(path), + } + } + pub fn activate_script( &mut self, script_id: usize, @@ -177,24 +227,16 @@ impl<'a> ScriptManager<'a> { } } ScriptDeclaration::Wasm { path } => { - let module = files - .load_file(path.clone(), &wasm_runner.engine) - .unwrap() - .unwrap_wasm_module(); + let module = { + puffin::profile_scope!("load module"); + files + .load_file(path.clone(), &wasm_runner.engine) + .unwrap() + .unwrap_wasm_module() + }; wasm_runner.run_function(module, context, "update"); } } } } - - pub fn reset_script( - &mut self, - script_id: usize, - context: &mut ScriptContext<'_>, - wasm_runner: &WasmRunner, - files: &mut FileManager, - ) { - self.activate_script(script_id, context, wasm_runner, files); - self.deactivate_script(script_id, context, wasm_runner, files); - } } -- cgit v1.2.3