summaryrefslogtreecommitdiff
path: root/src/script.rs
diff options
context:
space:
mode:
authorMica White <botahamec@outlook.com>2026-07-29 21:19:57 -0400
committerMica White <botahamec@outlook.com>2026-07-29 21:19:57 -0400
commitc687e2aba30ca231b03288108b632f1bad464028 (patch)
tree6134233d24211510eb674417d3374615a74b8268 /src/script.rs
parent20ecfc902cc5a654a079e9ba22c41179aca221bb (diff)
Script optimizationHEADmain
Diffstat (limited to 'src/script.rs')
-rw-r--r--src/script.rs249
1 files changed, 171 insertions, 78 deletions
diff --git a/src/script.rs b/src/script.rs
index 8539c92..a2cb76d 100644
--- a/src/script.rs
+++ b/src/script.rs
@@ -1,4 +1,4 @@
-use std::path::Path;
+use std::{path::Path, sync::Arc};
use rustc_hash::FxHashMap;
@@ -7,11 +7,13 @@ use crate::{
file::{FileManager, GameManifest},
input::InputManager,
scene::{preload_scene, switch_scenes},
+ script::wasm::WasmModule,
storage::StorageManager,
time::TimeContext,
};
-mod wasm;
+pub mod lua;
+pub mod wasm;
pub struct ScriptManager<'a> {
scripts: &'a [ScriptDeclaration],
@@ -20,9 +22,11 @@ pub struct ScriptManager<'a> {
script_states: FxHashMap<usize, Box<[u8]>>,
}
+#[derive(Clone)]
pub struct WasmRunner {
- pub engine: wasmi::Engine,
- pub linker: wasmi::Linker<FullScriptContext<'static>>,
+ pub engine: tinywasm::Engine,
+ pub store: Arc<spin::Mutex<tinywasm::Store>>,
+ pub linker: tinywasm::Imports,
}
pub struct ScriptContext<'a> {
@@ -41,7 +45,7 @@ pub struct FullScriptContext<'a> {
pub input: &'a InputManager,
pub time: &'a TimeContext,
pub scripts: &'a ScriptManager<'a>,
- pub files: &'a FileManager,
+ pub files: Box<[Box<Path>]>,
pub storage: &'a StorageManager,
pub wasm_runner: &'a WasmRunner,
pub operation_queue: &'a mut Vec<Operation>,
@@ -79,6 +83,10 @@ pub enum ScriptDeclaration {
update: StaticScriptFunction,
end: StaticScriptFunction,
},
+ Lua {
+ name: Box<str>,
+ path: Box<Path>,
+ },
Wasm {
name: Box<str>,
path: Box<Path>,
@@ -104,66 +112,62 @@ impl Default for WasmRunner {
impl WasmRunner {
pub fn new() -> Self {
- let engine = wasmi::Engine::default();
- let linker = unsafe {
- std::mem::transmute::<
- wasmi::Linker<FullScriptContext<'_>>,
- wasmi::Linker<FullScriptContext<'_>>,
- >(wasm::linker(&engine).unwrap())
- };
- Self { engine, linker }
+ let engine = tinywasm::Engine::default();
+ let mut store = tinywasm::Store::new(engine.clone());
+ let linker = wasm::linker(&mut store).unwrap();
+ let store = Arc::new(spin::Mutex::new(store));
+ Self {
+ engine,
+ store,
+ linker,
+ }
}
- pub fn compile(&self, data: &[u8]) -> Result<wasmi::Module, wasmi::Error> {
- wasmi::Module::new(&self.engine, data)
+ pub fn compile(&self, data: &[u8]) -> Result<WasmModule, tinywasm::Error> {
+ let module = tinywasm::parse_bytes(data)?;
+ let instance = tinywasm::ModuleInstance::instantiate(
+ &mut self.store.lock(),
+ &module,
+ Some(self.linker.clone()),
+ )?;
+ Ok(WasmModule { instance })
}
- #[allow(clippy::too_many_arguments)]
+ #[expect(clippy::too_many_arguments)]
pub fn run_function(
&self,
script_id: usize,
- module: &wasmi::Module,
+ module: &mut WasmModule,
scripts: &ScriptManager,
- files: &FileManager,
+ files: Box<[Box<Path>]>,
wasm_runner: &WasmRunner,
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 = {
- puffin::profile_scope!("create store");
- wasmi::Store::new(&self.engine, unsafe {
- std::mem::transmute::<FullScriptContext<'_>, FullScriptContext<'_>>(
- FullScriptContext {
- script_id,
- manifest: context.manifest,
- buffer: context.buffer,
- input: context.input,
- time: context.time,
- storage: context.storage,
- scripts,
- files,
- wasm_runner,
- operation_queue: &mut context.operation_queue,
- },
- )
- })
- };
- 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 [])
- }
+ ) -> Result<(), tinywasm::Error> {
+ puffin::profile_function!();
+
+ let context = std::ptr::from_mut(Box::leak(Box::new(FullScriptContext {
+ script_id,
+ manifest: context.manifest,
+ buffer: context.buffer,
+ input: context.input,
+ time: context.time,
+ storage: context.storage,
+ scripts,
+ files,
+ wasm_runner,
+ operation_queue: &mut context.operation_queue,
+ })));
+
+ let function = module
+ .instance
+ .func::<u64, ()>(&wasm_runner.store.lock(), function_name)?;
+ let r = function.call(
+ &mut wasm_runner.store.lock(),
+ context.expose_provenance() as u64,
+ );
+ drop(unsafe { Box::from_raw(context) });
+ r
}
}
@@ -185,6 +189,11 @@ impl<'a> ScriptManager<'a> {
return Some(i);
}
}
+ ScriptDeclaration::Lua { name, .. } => {
+ if &**name == needle {
+ return Some(i);
+ }
+ }
ScriptDeclaration::Wasm { name, .. } => {
if &**name == needle {
return Some(i);
@@ -205,17 +214,17 @@ impl<'a> ScriptManager<'a> {
let script = &self.scripts[script_id];
match script {
ScriptDeclaration::Static { .. } => (),
- ScriptDeclaration::Wasm { path, .. } => {
- files.start_loading_file(path, &wasm_runner.engine)
- }
+ ScriptDeclaration::Lua { path, .. } => files.start_loading_file(path, wasm_runner),
+ ScriptDeclaration::Wasm { path, .. } => files.start_loading_file(path, wasm_runner),
}
}
- pub fn is_script_loaded(&self, script_id: usize, files: &FileManager) -> bool {
+ pub fn is_script_loaded(&self, script_id: usize, loaded_files: &[Box<Path>]) -> bool {
let script = &self.scripts[script_id];
match script {
ScriptDeclaration::Static { .. } => true,
- ScriptDeclaration::Wasm { path, .. } => files.is_file_loaded(path),
+ ScriptDeclaration::Lua { path, .. } => loaded_files.contains(path),
+ ScriptDeclaration::Wasm { path, .. } => loaded_files.contains(path),
}
}
@@ -223,6 +232,7 @@ impl<'a> ScriptManager<'a> {
let script = &self.scripts[script_id];
match script {
ScriptDeclaration::Static { .. } => (),
+ ScriptDeclaration::Lua { path, .. } => files.unload_file(path),
ScriptDeclaration::Wasm { path, .. } => files.unload_file(path),
}
}
@@ -284,7 +294,9 @@ impl<'a> ScriptManager<'a> {
Operation::UpdateState {
script_id,
new_state,
- } => *get_script_state(&mut self.script_states, *script_id) = new_state.clone(),
+ } => {
+ self.script_states.insert(*script_id, new_state.clone());
+ }
Operation::UpdateEntity { name, new_state } => {
self.entities.insert(name.clone(), new_state.clone());
}
@@ -316,18 +328,46 @@ impl<'a> ScriptManager<'a> {
)
});
}
+ ScriptDeclaration::Lua { path, .. } => {
+ files.load_file(path.clone(), wasm_runner).unwrap();
+ let loaded_files = files.loaded_files();
+ let module = files.get_cached_file_mut(path).unwrap().unwrap_lua_module();
+ if let Err(e) = module.run_function(
+ "start",
+ FullScriptContext {
+ script_id,
+ manifest: context.manifest,
+ buffer: context.buffer,
+ input: context.input,
+ time: context.time,
+ scripts: self,
+ files: loaded_files,
+ storage: context.storage,
+ wasm_runner,
+ operation_queue: &mut context.operation_queue,
+ },
+ ) {
+ log::error!("{e}");
+ }
+ }
ScriptDeclaration::Wasm { path, .. } => {
- files.load_file(path.clone(), &wasm_runner.engine).unwrap();
- let module = files.get_cached_file(path).unwrap().unwrap_wasm_module();
- wasm_runner.run_function(
+ files.load_file(path.clone(), wasm_runner).unwrap();
+ let loaded_files = files.loaded_files();
+ let module = files
+ .get_cached_file_mut(path)
+ .unwrap()
+ .unwrap_wasm_module_mut();
+ if let Err(e) = wasm_runner.run_function(
script_id,
module,
self,
- files,
+ loaded_files,
wasm_runner,
context,
"start",
- );
+ ) {
+ log::error!("{e}");
+ }
}
}
self.active_scripts.push(script_id);
@@ -360,18 +400,46 @@ impl<'a> ScriptManager<'a> {
);
});
}
+ ScriptDeclaration::Lua { path, .. } => {
+ files.load_file(path.clone(), wasm_runner).unwrap();
+ let loaded_files = files.loaded_files();
+ let module = files.get_cached_file_mut(path).unwrap().unwrap_lua_module();
+ if let Err(e) = module.run_function(
+ "end",
+ FullScriptContext {
+ script_id,
+ manifest: context.manifest,
+ buffer: context.buffer,
+ input: context.input,
+ time: context.time,
+ scripts: self,
+ files: loaded_files,
+ storage: context.storage,
+ wasm_runner,
+ operation_queue: &mut context.operation_queue,
+ },
+ ) {
+ log::error!("{e}");
+ }
+ }
ScriptDeclaration::Wasm { path, .. } => {
- files.load_file(path.clone(), &wasm_runner.engine).unwrap();
- let module = files.get_cached_file(path).unwrap().unwrap_wasm_module();
- wasm_runner.run_function(
+ files.load_file(path.clone(), wasm_runner).unwrap();
+ let loaded_files = files.loaded_files();
+ let module = files
+ .get_cached_file_mut(path)
+ .unwrap()
+ .unwrap_wasm_module_mut();
+ if let Err(e) = wasm_runner.run_function(
script_id,
module,
self,
- files,
+ loaded_files,
wasm_runner,
context,
"end",
- );
+ ) {
+ log::error!("{e}");
+ }
}
};
}
@@ -399,21 +467,46 @@ impl<'a> ScriptManager<'a> {
)
}
}
+ ScriptDeclaration::Lua { path, .. } => {
+ files.load_file(path.clone(), wasm_runner).unwrap();
+ let loaded_files = files.loaded_files();
+ let module = files.get_cached_file_mut(path).unwrap().unwrap_lua_module();
+ if let Err(e) = module.run_function(
+ "update",
+ FullScriptContext {
+ script_id: *script_id,
+ manifest: context.manifest,
+ buffer: context.buffer,
+ input: context.input,
+ time: context.time,
+ scripts: self,
+ files: loaded_files,
+ storage: context.storage,
+ wasm_runner,
+ operation_queue: &mut context.operation_queue,
+ },
+ ) {
+ log::error!("{e}");
+ }
+ }
ScriptDeclaration::Wasm { path, .. } => {
- let module = {
- puffin::profile_scope!("load module");
- files.load_file(path.clone(), &wasm_runner.engine).unwrap();
- files.get_cached_file(path).unwrap().unwrap_wasm_module()
- };
- wasm_runner.run_function(
+ files.load_file(path.clone(), wasm_runner).unwrap();
+ let loaded_files = files.loaded_files();
+ let module = files
+ .get_cached_file_mut(path)
+ .unwrap()
+ .unwrap_wasm_module_mut();
+ if let Err(e) = wasm_runner.run_function(
*script_id,
module,
self,
- files,
+ loaded_files,
wasm_runner,
context,
"update",
- );
+ ) {
+ log::error!("Error while running scripts: {e}");
+ }
}
}
}