scene_graph/
iter.rs

1use crate::{Children, Node, SceneGraph};
2
3/// An iterator over the SceneGraph. See [iter] for more information.
4/// 
5/// [iter]: SceneGraph::iter
6pub struct SceneGraphIter<'a, T> {
7    sg: &'a SceneGraph<T>,
8    stacks: Vec<StackState<'a, T>>,
9}
10
11impl<'a, T> SceneGraphIter<'a, T> {
12    pub(crate) fn new(sg: &'a SceneGraph<T>, root_value: &'a T, root_children: Option<&'a Children>) -> Self {
13        let mut stacks = Vec::new();
14        if let Some(first_child) = root_children.map(|v| v.first) {
15            stacks.push(StackState::new(root_value, &sg.arena[first_child]));
16        };
17        SceneGraphIter { sg, stacks }
18    }
19}
20
21impl<'a, T> Iterator for SceneGraphIter<'a, T> {
22    type Item = (&'a T, &'a T);
23
24    fn next(&mut self) -> Option<Self::Item> {
25        // if we're out of stack frames, we die here
26        let stack_frame = self.stacks.pop()?;
27
28        // if there's a sibling, push it onto the to do list!
29        if let Some(next_sibling) = stack_frame.current_child.next_sibling {
30            self.stacks
31                .push(StackState::new(stack_frame.parent_value, &self.sg.arena[next_sibling]));
32        }
33
34        if let Some(first_child) = stack_frame.current_child.children.map(|v| v.first) {
35            self.stacks.push(StackState::new(
36                &stack_frame.current_child.value,
37                &self.sg.arena[first_child],
38            ));
39        }
40
41        Some((stack_frame.parent_value, &stack_frame.current_child.value))
42    }
43}
44
45#[derive(Debug)]
46struct StackState<'a, T> {
47    parent_value: &'a T,
48    current_child: &'a Node<T>,
49}
50
51impl<'a, T> StackState<'a, T> {
52    fn new(parent: &'a T, first_child: &'a Node<T>) -> Self {
53        Self {
54            parent_value: parent,
55            current_child: first_child,
56        }
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use crate::NodeIndex;
63
64    use super::*;
65
66    #[test]
67    fn scene_graph_returns_nothing_on_empty_iteration() {
68        let scene_graph = SceneGraph::new("Root");
69
70        assert!(scene_graph.iter().next().is_none());
71    }
72
73    #[test]
74    fn normal_iteration() {
75        let mut sg = SceneGraph::new("Root");
76        let root_idx = NodeIndex::Root;
77        sg.attach(root_idx, "First Child").unwrap();
78
79        let second_child = sg.attach(root_idx, "Second Child").unwrap();
80        sg.attach(second_child, "First Grandchild").unwrap();
81
82        assert_eq!(
83            Vec::from_iter(sg.iter().map(|(_parent, value)| value).cloned()),
84            vec!["First Child", "Second Child", "First Grandchild"]
85        );
86    }
87
88    #[test]
89    fn stagger_iteration() {
90        let mut sg = SceneGraph::new("Root");
91        let root_idx = NodeIndex::Root;
92        let child = sg.attach(root_idx, "First Child").unwrap();
93        sg.attach(child, "Second Child").unwrap();
94
95        assert_eq!(
96            Vec::from_iter(sg.iter().map(|(_parent, value)| value).cloned()),
97            vec!["First Child", "Second Child"]
98        );
99    }
100
101    #[test]
102    fn single_iteration() {
103        let mut sg = SceneGraph::new("Root");
104        let root_idx = NodeIndex::Root;
105        sg.attach(root_idx, "First Child").unwrap();
106
107        assert_eq!(
108            Vec::from_iter(sg.iter().map(|(_parent, value)| value).cloned()),
109            vec!["First Child",]
110        );
111    }
112}