use std::io::Read;
use anyhow::Result;
use crate::resource::prp::PlasmaRead;
use super::uoid::{Uoid, read_key_uoid};
#[derive(Debug, Clone)]
pub struct SceneNodeData {
pub self_key: Option<Uoid>,
pub scene_objects: Vec<Option<Uoid>>,
pub pool_objects: Vec<Option<Uoid>>,
}
impl SceneNodeData {
pub fn read(reader: &mut impl Read) -> Result<Self> {
let self_key = read_key_uoid(reader)?;
let num_scene_objects = reader.read_u32()?;
let mut scene_objects = Vec::with_capacity(num_scene_objects as usize);
for _ in 0..num_scene_objects {
scene_objects.push(read_key_uoid(reader)?);
}
let num_pool = reader.read_u32()?;
let mut pool_objects = Vec::with_capacity(num_pool as usize);
for _ in 0..num_pool {
pool_objects.push(read_key_uoid(reader)?);
}
Ok(Self {
self_key,
scene_objects,
pool_objects,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::class_index::ClassIndex;
use crate::resource::prp::PrpPage;
use std::io::Cursor;
use std::path::Path;
#[test]
fn test_parse_cleft_scene_node() {
let path = Path::new("../../Plasma/staging/client/dat/Cleft_District_Cleft.prp");
if !path.exists() {
eprintln!("Skipping test: {:?} not found", path);
return;
}
let page = PrpPage::from_file(path).unwrap();
let node_keys: Vec<_> = page.keys_of_type(ClassIndex::PL_SCENE_NODE);
assert!(!node_keys.is_empty(), "Should have at least one scene node");
for key in &node_keys {
if let Some(data) = page.object_data(key) {
let mut cursor = Cursor::new(data);
let _ = cursor.read_i16().unwrap();
let node = SceneNodeData::read(&mut cursor).unwrap();
eprintln!(
"SceneNode '{}': {} scene objects, {} pool objects",
key.object_name,
node.scene_objects.len(),
node.pool_objects.len()
);
assert!(
!node.scene_objects.is_empty(),
"Cleft scene node should have scene objects"
);
}
}
}
}