summaryrefslogtreecommitdiff
path: root/src/script.rs
diff options
context:
space:
mode:
authorMica White <botahamec@outlook.com>2026-07-03 16:35:05 -0400
committerMica White <botahamec@outlook.com>2026-07-03 16:35:05 -0400
commitbdbd5faeb7be5e5f81c1f4a952c8110df9e9b990 (patch)
tree324a84ed9cba6b4ac5427775362ae25c6588b4db /src/script.rs
parentf31fda79035077a9dab8dee07a11d71fac3ba791 (diff)
parentcbbe1ca7f7b36b03e813fbf7e0147341090762bb (diff)
merge
Diffstat (limited to 'src/script.rs')
-rw-r--r--src/script.rs138
1 files changed, 84 insertions, 54 deletions
diff --git a/src/script.rs b/src/script.rs
index be7f6f4..861f665 100644
--- a/src/script.rs
+++ b/src/script.rs
@@ -1,7 +1,6 @@
use std::path::Path;
use rustc_hash::FxHashMap;
-use wasmer::{Imports, Instance, Module, Store};
use crate::{buffer::Buffer, file::FileManager, input::InputManager};
@@ -11,12 +10,17 @@ pub struct ScriptManager<'a> {
script_states: FxHashMap<usize, Box<[u8]>>,
}
+pub struct WasmRunner {
+ pub engine: wasmi::Engine,
+ pub linker: wasmi::Linker<&'static ScriptContext<'static>>,
+}
+
pub struct ScriptContext<'a> {
pub buffer: &'a mut Buffer,
pub input: &'a InputManager,
}
-type StaticScriptFunction = Option<fn(&mut ScriptContext, &mut Box<[u8]>)>;
+type StaticScriptFunction = Option<fn(&mut ScriptContext<'_>, &mut Box<[u8]>)>;
pub enum ScriptDeclaration {
Static {
@@ -29,17 +33,6 @@ pub enum ScriptDeclaration {
},
}
-pub struct WasmScript {
- pub module: Module,
- pub instance: Instance,
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub enum Profile {
- Debug,
- Release,
-}
-
impl<'a> ScriptContext<'a> {
pub fn exit(&mut self) -> ! {
let _ = self.buffer.finish();
@@ -51,6 +44,42 @@ fn get_script_state(states: &mut FxHashMap<usize, Box<[u8]>>, script_id: usize)
states.entry(script_id).or_insert(Box::from([]))
}
+impl Default for WasmRunner {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl WasmRunner {
+ pub fn new() -> Self {
+ let engine = wasmi::Engine::default();
+ let linker = wasmi::Linker::new(&engine);
+ Self { engine, linker }
+ }
+
+ pub fn compile(&self, data: &[u8]) -> Result<wasmi::Module, wasmi::Error> {
+ wasmi::Module::new(&self.engine, data)
+ }
+
+ pub fn run_function(
+ &self,
+ module: &wasmi::Module,
+ context: &mut ScriptContext<'_>,
+ function_name: &str,
+ ) -> 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 [])
+ }
+}
+
impl<'a> ScriptManager<'a> {
pub fn new(scripts: &'a [ScriptDeclaration]) -> Self {
Self {
@@ -64,6 +93,7 @@ impl<'a> ScriptManager<'a> {
&mut self,
script_id: usize,
context: &mut ScriptContext<'_>,
+ wasm_runner: &WasmRunner,
files: &mut FileManager,
) {
let Some(script_declaration) = self.scripts.get(script_id) else {
@@ -79,19 +109,23 @@ impl<'a> ScriptManager<'a> {
});
}
ScriptDeclaration::Wasm { path } => {
- todo!("wasm scripts")
- // let module = files.load_file(path.clone()).unwrap().unwrap_wasm_module();
- // let mut store = wasmi::Store::new(&files.wasm_compiler, context);
- // let instance = self
- // .linker
- // .instantiate_and_start(&mut store, &module)
- // .unwrap();
+ let module = files
+ .load_file(path.clone(), &wasm_runner.engine)
+ .unwrap()
+ .unwrap_wasm_module();
+ wasm_runner.run_function(module, context, "start");
}
}
self.active_scripts.push(script_id);
}
- pub fn deactivate_script(&mut self, script_id: usize, context: &mut ScriptContext<'_>) {
+ pub fn deactivate_script(
+ &mut self,
+ script_id: usize,
+ context: &mut ScriptContext<'_>,
+ wasm_runner: &WasmRunner,
+ files: &mut FileManager,
+ ) {
self.active_scripts.retain(|element| {
if *element != script_id {
let Some(script) = self.scripts.get(script_id) else {
@@ -106,7 +140,13 @@ impl<'a> ScriptManager<'a> {
);
});
}
- ScriptDeclaration::Wasm { .. } => todo!("wasm scripts"),
+ ScriptDeclaration::Wasm { path } => {
+ let module = files
+ .load_file(path.clone(), &wasm_runner.engine)
+ .unwrap()
+ .unwrap_wasm_module();
+ wasm_runner.run_function(module, context, "end");
+ }
};
true
@@ -116,13 +156,18 @@ impl<'a> ScriptManager<'a> {
});
}
- pub fn run_scripts(&mut self, context: &mut ScriptContext<'_>) {
+ pub fn run_scripts(
+ &mut self,
+ context: &mut ScriptContext<'_>,
+ wasm_runner: &WasmRunner,
+ files: &mut FileManager,
+ ) {
puffin::profile_function!();
for script_id in &self.active_scripts {
let Some(script) = self.scripts.get(*script_id) else {
unreachable!("The active script does not exist");
};
- match *script {
+ match script {
ScriptDeclaration::Static { update, .. } => {
if let Some(s) = update {
s(
@@ -131,40 +176,25 @@ impl<'a> ScriptManager<'a> {
)
}
}
- ScriptDeclaration::Wasm { .. } => todo!("wasm scripts"),
- }
- }
- }
-
- pub fn reset_script(&mut self, script_id: usize, context: &mut ScriptContext<'_>) {
- let script = &self.scripts[script_id];
- match script {
- ScriptDeclaration::Static { start, end, .. } => {
- if let Some(s) = start {
- s(
- context,
- get_script_state(&mut self.script_states, script_id),
- )
- }
- if let Some(s) = end {
- s(
- context,
- get_script_state(&mut self.script_states, script_id),
- )
+ ScriptDeclaration::Wasm { path } => {
+ let module = files
+ .load_file(path.clone(), &wasm_runner.engine)
+ .unwrap()
+ .unwrap_wasm_module();
+ wasm_runner.run_function(module, context, "update");
}
}
- ScriptDeclaration::Wasm { .. } => todo!("wasm scripts"),
}
}
-}
-impl WasmScript {
- fn call_function(&self, name: &str, profile: Profile, store: &mut Store, imports: &Imports) {
- let instance = match profile {
- Profile::Debug => &Instance::new(store, &self.module, imports).unwrap(),
- Profile::Release => &self.instance,
- };
- let function = instance.exports.get_function(name).unwrap();
- function.call(store, &[]).unwrap();
+ 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);
}
}