diff options
Diffstat (limited to 'src/file.rs')
| -rw-r--r-- | src/file.rs | 67 |
1 files changed, 55 insertions, 12 deletions
diff --git a/src/file.rs b/src/file.rs index 9b9888c..4aedd48 100644 --- a/src/file.rs +++ b/src/file.rs @@ -6,7 +6,7 @@ use smol::{Task, unblock}; use crate::{ scene::{ResourceRequirements, Scene, scene_id_by_name}, - script::ScriptDeclaration, + script::{ScriptDeclaration, WasmRunner, lua::LuaModule, wasm::WasmModule}, }; type FileTask = Task<std::io::Result<FileData>>; @@ -25,7 +25,7 @@ pub struct GameManifest { } #[derive(Debug, Serialize, Deserialize)] -struct TomlGameManifest { +pub struct TomlGameManifest { name: Box<str>, first_scene: Box<str>, #[serde(default)] @@ -49,14 +49,16 @@ struct TomlScene { #[serde(tag = "type", rename_all = "kebab-case")] enum TomlScript { Wasm { name: Box<str>, path: Box<Path> }, + Lua { name: Box<str>, path: Box<Path> }, } pub enum FileData { GameManifest(GameManifest), - WasmModule(wasmi::Module), + WasmModule(Box<WasmModule>), + LuaModule(Box<LuaModule>), } -fn normalize_game_manifest(manifest: TomlGameManifest) -> std::io::Result<GameManifest> { +pub fn normalize_game_manifest(manifest: TomlGameManifest) -> std::io::Result<GameManifest> { let mut scripts = Vec::with_capacity(manifest.script.len()); let script_map: FxHashMap<Box<str>, usize> = manifest .script @@ -69,6 +71,13 @@ fn normalize_game_manifest(manifest: TomlGameManifest) -> std::io::Result<GameMa }); (name, scripts.len() - 1) } + TomlScript::Lua { name, path } => { + scripts.push(ScriptDeclaration::Lua { + name: name.clone(), + path, + }); + (name, scripts.len() - 1) + } }) .collect(); let scenes: Box<[Scene]> = manifest @@ -102,8 +111,8 @@ fn normalize_game_manifest(manifest: TomlGameManifest) -> std::io::Result<GameMa }) } -fn compile_data(path: &Path, data: &[u8], compiler: &wasmi::Engine) -> std::io::Result<FileData> { - if path == "manifest.toml" { +fn compile_data(path: &Path, data: &[u8], compiler: &WasmRunner) -> std::io::Result<FileData> { + if path == "tortuise.toml" { return Ok(FileData::GameManifest(normalize_game_manifest( toml::from_slice(data).map_err(std::io::Error::other)?, )?)); @@ -113,9 +122,14 @@ fn compile_data(path: &Path, data: &[u8], compiler: &wasmi::Engine) -> std::io:: .and_then(OsStr::to_str) .map(|ext| ext.to_lowercase()); if extension.as_deref() == Some("wasm") { - return Ok(FileData::WasmModule( - wasmi::Module::new(compiler, data).map_err(std::io::Error::other)?, - )); + return Ok(FileData::WasmModule(Box::new( + compiler.compile(data).map_err(std::io::Error::other)?, + ))); + } + if extension.as_deref() == Some("lua") { + return Ok(FileData::LuaModule(Box::new( + LuaModule::new(data).map_err(std::io::Error::other)?, + ))); } Err(std::io::Error::other("Unrecognized file extension")) } @@ -129,7 +143,23 @@ impl FileData { } } - pub fn unwrap_wasm_module(&self) -> &wasmi::Module { + pub fn unwrap_wasm_module(&self) -> &WasmModule { + if let FileData::WasmModule(module) = self { + module + } else { + panic!("Not a WASM module") + } + } + + pub fn unwrap_lua_module(&self) -> &LuaModule { + if let FileData::LuaModule(module) = self { + module + } else { + panic!("Not a Lua module") + } + } + + pub fn unwrap_wasm_module_mut(&mut self) -> &mut WasmModule { if let FileData::WasmModule(module) = self { module } else { @@ -149,7 +179,7 @@ impl FileManager { pub fn load_file( &mut self, path: Box<Path>, - wasm_compiler: &wasmi::Engine, + wasm_compiler: &WasmRunner, ) -> std::io::Result<&FileData> { if !self.cache.contains_key(&path) { let data = compile_data( @@ -166,7 +196,11 @@ impl FileManager { self.cache.get(path) } - pub fn start_loading_file(&mut self, path: impl AsRef<Path>, wasm_compiler: &wasmi::Engine) { + pub fn get_cached_file_mut(&mut self, path: &Path) -> Option<&mut FileData> { + self.cache.get_mut(path) + } + + pub fn start_loading_file(&mut self, path: impl AsRef<Path>, wasm_compiler: &WasmRunner) { let boxed_path = Box::from(path.as_ref()); let compiler = wasm_compiler.clone(); let task = unblock(move || { @@ -180,6 +214,15 @@ impl FileManager { self.active_tasks.insert(boxed_path, task); } + pub fn loaded_files(&self) -> Box<[Box<Path>]> { + self.active_tasks + .iter() + .filter(|&(_, v)| v.is_finished()) + .map(|(k, _)| k.clone()) + .chain(self.cache.keys().cloned()) + .collect() + } + pub fn is_file_loaded(&self, path: impl AsRef<Path>) -> bool { self.active_tasks .get(path.as_ref()) |
