use rustc_hash::FxHashSet; use serde::{Deserialize, Serialize}; use crate::{ file::FileManager, script::{ScriptContext, ScriptManager, WasmRunner}, }; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Scene { pub name: Box, pub preload_scenes: Box<[usize]>, pub scripts: ResourceRequirements, } #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct ResourceRequirements { pub required: Box<[usize]>, pub preload: Box<[usize]>, } pub fn scene_id_by_name(scenes: &[Scene], name: &str) -> Option { for (i, scene) in scenes.iter().enumerate() { if &*scene.name == name { return Some(i); } } None } pub fn preload_scene( scenes: &[Scene], scripts: &mut ScriptManager, files: &mut FileManager, wasm_runner: &WasmRunner, id: usize, ) { let scene = &scenes[id]; for script in &scene.scripts.required { scripts.preload_script(*script, files, wasm_runner); } } pub fn is_scene_loaded( scenes: &[Scene], scripts: &ScriptManager, files: &FileManager, id: usize, ) -> bool { let scene = &scenes[id]; scene .scripts .required .iter() .cloned() .all(|script_id| scripts.is_script_loaded(script_id, files)) } pub fn switch_scenes( scripts: &mut ScriptManager, context: &mut ScriptContext<'_>, files: &mut FileManager, wasm_runner: &WasmRunner, new: usize, ) { let active_scripts = scripts .active_scripts .iter() .cloned() .collect::>(); for script_id in &active_scripts { scripts.deactivate_script(*script_id, context, wasm_runner, files); } let mut needed_scripts = FxHashSet::default(); let scene = &context.manifest.scenes[new]; for script_id in &scene.scripts.required { needed_scripts.insert(*script_id); scripts.activate_script(*script_id, context, wasm_runner, files); } for script_id in &scene.scripts.preload { needed_scripts.insert(*script_id); scripts.preload_script(*script_id, files, wasm_runner); } for scene_to_preload in &scene.preload_scenes { let scene_to_preload = &context.manifest.scenes[*scene_to_preload]; for script_id in &scene_to_preload.scripts.required { needed_scripts.insert(*script_id); scripts.preload_script(*script_id, files, wasm_runner); } } let active_scripts: FxHashSet = active_scripts.iter().cloned().collect(); let unneeded_scripts = active_scripts.difference(&needed_scripts); for script_id in unneeded_scripts { scripts.unload_script(*script_id, files); } }