use std::{
fmt::{Debug, Display},
rc::Rc,
};
use nalgebra_glm::Mat4;
use crate::{
basic_types::{IDCounter, ID},
structure::Shape,
};
static ID_COUNTER: IDCounter = IDCounter::new();
pub struct Node {
id: u64,
label: String,
transform: Option<Mat4>,
shapes: Vec<Rc<Shape>>,
children: Vec<Node>,
}
impl Node {
pub fn new(label: String) -> Self {
let id = ID_COUNTER.gen();
Self {
id,
label,
transform: None,
shapes: Vec::new(),
children: Vec::new(),
}
}
pub fn get_id(&self) -> u64 {
self.id
}
pub fn is_leaf(&self) -> bool {
self.children.is_empty()
}
pub fn get_label(&self) -> &str {
&self.label
}
pub fn add_child(&mut self, child: Node) {
self.children.push(child);
}
pub fn get_children(&self) -> &[Node] {
&self.children
}
pub fn attach_shape(&mut self, shape: Rc<Shape>) {
self.shapes.push(shape);
}
pub fn get_shapes(&self) -> &[Rc<Shape>] {
&self.shapes
}
pub fn set_transform(&mut self, transform: Mat4) {
self.transform = Some(transform)
}
pub fn get_transform(&self) -> Option<Mat4> {
self.transform
}
}
impl Display for Node {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Node({})[label={}, #Children={}, #Shapes={}]",
self.id,
self.label,
self.children.len(),
self.shapes.len()
)
}
}
impl Debug for Node {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let children_ids: Vec<ID> = self.children.iter().map(|c| c.get_id()).collect();
let shape_ids: Vec<ID> = self.shapes.iter().map(|s| s.get_id()).collect();
write!(
f,
"Node({})[label={}, #Children={:?}, #Shapes={:?}]",
self.id, self.label, children_ids, shape_ids
)
}
}
impl PartialEq for Node {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl Eq for Node {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_node_basic() {
let mut node0 = Node::new("node".to_owned());
let node1 = Node::new("node".to_owned());
let node_id1 = node1.get_id();
assert!(node0.is_leaf());
assert!(node1.is_leaf());
assert_eq!(node0, node0);
assert_eq!(node1, node1);
assert_ne!(node0, node1);
node0.add_child(node1);
assert!(!node0.is_leaf());
assert_eq!(node0.get_children().len(), 1);
let node1 = &node0.get_children()[0];
assert_eq!(node1.get_id(), node_id1);
}
}