diff options
| author | Mica White <botahamec@outlook.com> | 2026-07-06 13:59:36 -0400 |
|---|---|---|
| committer | Mica White <botahamec@outlook.com> | 2026-07-06 13:59:36 -0400 |
| commit | e8f85e4a723b772c099a3c03a6cb721c48561e4b (patch) | |
| tree | a879493f40ba52399c2af05eacdb95b8939b0712 /src/file.rs | |
| parent | bdbd5faeb7be5e5f81c1f4a952c8110df9e9b990 (diff) | |
Fully support WASM (in some contexts)
Diffstat (limited to 'src/file.rs')
| -rw-r--r-- | src/file.rs | 86 |
1 files changed, 70 insertions, 16 deletions
diff --git a/src/file.rs b/src/file.rs index 2963879..20fdd68 100644 --- a/src/file.rs +++ b/src/file.rs @@ -4,7 +4,10 @@ use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; use smol::{Task, block_on, unblock}; -use crate::scene::{Scene, scene_id_by_name}; +use crate::{ + scene::{ResourceRequirements, Scene, scene_id_by_name}, + script::ScriptDeclaration, +}; type FileTask = Task<std::io::Result<FileData>>; @@ -13,18 +16,39 @@ pub struct FileManager { cache: FxHashMap<Box<Path>, FileData>, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone)] pub struct GameManifest { pub name: Box<str>, pub first_scene: usize, pub scenes: Box<[Scene]>, + pub scripts: Box<[ScriptDeclaration]>, } #[derive(Debug, Serialize, Deserialize)] struct TomlGameManifest { name: Box<str>, first_scene: Box<str>, - scene: Box<[Scene]>, + #[serde(default)] + scene: Box<[TomlScene]>, + #[serde(default)] + script: Box<[TomlScript]>, +} + +#[derive(Debug, Serialize, Deserialize)] +struct TomlScene { + name: Box<str>, + #[serde(default)] + preload_scenes: Box<[Box<str>]>, + #[serde(default)] + scripts: Box<[Box<str>]>, + #[serde(default)] + preload_scripts: Box<[Box<str>]>, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(tag = "type", rename_all = "kebab-case")] +enum TomlScript { + Wasm { name: Box<str>, path: Box<Path> }, } pub enum FileData { @@ -33,22 +57,50 @@ pub enum FileData { } fn normalize_game_manifest(manifest: TomlGameManifest) -> std::io::Result<GameManifest> { - let first_scene = scene_id_by_name(&manifest.scene, &manifest.first_scene).ok_or( + let mut scripts = Vec::with_capacity(manifest.script.len()); + let script_map: FxHashMap<Box<str>, usize> = manifest + .script + .into_iter() + .map(|script| match script { + TomlScript::Wasm { name, path } => { + scripts.push(ScriptDeclaration::Wasm { path }); + (name, scripts.len() - 1) + } + }) + .collect(); + let scenes: Box<[Scene]> = manifest + .scene + .into_iter() + .map(|scene| Scene { + name: scene.name, + preload_scenes: Box::from([]), + scripts: ResourceRequirements { + required: scene + .scripts + .iter() + .map(|s| *script_map.get(s).unwrap()) + .collect(), + preload: scene + .preload_scripts + .iter() + .map(|s| *script_map.get(s).unwrap()) + .collect(), + }, + }) + .collect(); + let first_scene = scene_id_by_name(&scenes, &manifest.first_scene).ok_or( std::io::Error::other("Invalid first scene: scene not found"), )?; Ok(GameManifest { name: manifest.name, first_scene, - scenes: manifest.scene, + scenes, + scripts: scripts.into_boxed_slice(), }) } fn compile_data(path: &Path, data: &[u8], compiler: &wasmi::Engine) -> std::io::Result<FileData> { - if path == "manifest.postcard" { - return Ok(FileData::GameManifest( - postcard::from_bytes(data).map_err(std::io::Error::other)?, - )); - } else if path == "manifest.toml" { + if path == "manifest.toml" { return Ok(FileData::GameManifest(normalize_game_manifest( toml::from_slice(data).map_err(std::io::Error::other)?, )?)); @@ -96,12 +148,14 @@ impl FileManager { path: Box<Path>, wasm_compiler: &wasmi::Engine, ) -> std::io::Result<&FileData> { - let data = compile_data( - path.as_ref(), - &std::fs::read(path.as_ref()).map(Vec::into_boxed_slice)?, - wasm_compiler, - )?; - self.cache.entry(path.clone()).insert_entry(data); + if !self.cache.contains_key(&path) { + let data = compile_data( + path.as_ref(), + &std::fs::read(path.as_ref()).map(Vec::into_boxed_slice)?, + wasm_compiler, + )?; + self.cache.entry(path.clone()).insert_entry(data); + } Ok(self.cache.get(&path).unwrap()) } |
