summaryrefslogtreecommitdiff
path: root/src/script.rs
diff options
context:
space:
mode:
authorMica White <botahamec@outlook.com>2026-07-06 13:59:36 -0400
committerMica White <botahamec@outlook.com>2026-07-06 13:59:36 -0400
commite8f85e4a723b772c099a3c03a6cb721c48561e4b (patch)
treea879493f40ba52399c2af05eacdb95b8939b0712 /src/script.rs
parentbdbd5faeb7be5e5f81c1f4a952c8110df9e9b990 (diff)
Fully support WASM (in some contexts)
Diffstat (limited to 'src/script.rs')
-rw-r--r--src/script.rs94
1 files changed, 68 insertions, 26 deletions
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<fn(&mut ScriptContext<'_>, &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);
- }
}