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<str>,
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<usize> {
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: &mut ScriptManager,
files: &mut 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(
scenes: &[Scene],
scripts: &mut ScriptManager,
context: &mut ScriptContext<'_>,
files: &mut FileManager,
wasm_runner: &WasmRunner,
new: usize,
) {
let active_scripts = scripts
.active_scripts
.iter()
.cloned()
.collect::<Box<[usize]>>();
for script_id in &active_scripts {
scripts.deactivate_script(*script_id, context, wasm_runner, files);
}
let mut needed_scripts = FxHashSet::default();
let scene = &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 = &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<usize> = 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);
}
}
|