#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct CocosNode {
pub name: String,
pub position: [f32; 3],
pub children: Vec<CocosNode>,
}
impl CocosNode {
pub fn new(name: &str) -> Self {
Self {
name: name.to_string(),
position: [0.0; 3],
children: Vec::new(),
}
}
pub fn add_child(&mut self, child: CocosNode) {
self.children.push(child);
}
pub fn total_node_count(&self) -> usize {
1 + self
.children
.iter()
.map(|c| c.total_node_count())
.sum::<usize>()
}
}
#[derive(Debug, Clone)]
pub struct CocosScene {
pub name: String,
pub root: CocosNode,
}
impl CocosScene {
pub fn new(name: &str) -> Self {
Self {
name: name.to_string(),
root: CocosNode::new("Canvas"),
}
}
pub fn total_node_count(&self) -> usize {
self.root.total_node_count()
}
}
pub fn export_cocos_json(scene: &CocosScene) -> String {
format!(
"{{\"scene\":\"{}\",\"node_count\":{}}}",
scene.name,
scene.total_node_count()
)
}
pub fn find_node<'a>(node: &'a CocosNode, name: &str) -> Option<&'a CocosNode> {
if node.name == name {
return Some(node);
}
node.children.iter().find_map(|c| find_node(c, name))
}
pub fn scene_depth(node: &CocosNode) -> usize {
if node.children.is_empty() {
return 1;
}
1 + node.children.iter().map(scene_depth).max().unwrap_or(0)
}
#[cfg(test)]
mod tests {
use super::*;
fn sample_scene() -> CocosScene {
let mut scene = CocosScene::new("MainScene");
let mut child = CocosNode::new("Player");
child.add_child(CocosNode::new("Weapon"));
scene.root.add_child(child);
scene
}
#[test]
fn test_total_node_count() {
let s = sample_scene();
assert_eq!(s.total_node_count(), 3);
}
#[test]
fn test_export_cocos_json_not_empty() {
let s = sample_scene();
assert!(!export_cocos_json(&s).is_empty());
}
#[test]
fn test_export_cocos_json_contains_name() {
let s = sample_scene();
assert!(export_cocos_json(&s).contains("MainScene"));
}
#[test]
fn test_find_node_found() {
let s = sample_scene();
assert!(find_node(&s.root, "Player").is_some());
}
#[test]
fn test_find_node_deep() {
let s = sample_scene();
assert!(find_node(&s.root, "Weapon").is_some());
}
#[test]
fn test_find_node_not_found() {
let s = sample_scene();
assert!(find_node(&s.root, "Enemy").is_none());
}
#[test]
fn test_scene_depth() {
let s = sample_scene();
assert_eq!(scene_depth(&s.root), 3);
}
#[test]
fn test_empty_scene_node_count() {
let s = CocosScene::new("Empty");
assert_eq!(s.total_node_count(), 1);
}
}