scene_graph/
child_iter.rs

1use crate::{Children, NodeIndex, SceneGraph};
2
3/// An iterator over only the immediate children of a node in a [SceneGraph].
4/// See [iter_direct_children] for more information.
5/// 
6/// [iter_direct_children]: SceneGraph::iter_direct_children
7pub struct SceneGraphChildIter<'a, T> {
8    sg: &'a SceneGraph<T>,
9    current_node: Option<thunderdome::Index>,
10}
11
12impl<'a, T> SceneGraphChildIter<'a, T> {
13    pub(crate) fn new(sg: &'a SceneGraph<T>, root_index: NodeIndex) -> Self {
14        let children = match root_index {
15            NodeIndex::Root => sg.root_children.as_ref(),
16            NodeIndex::Branch(idx) => sg.arena[idx].children.as_ref(),
17        };
18
19        Self::with_children(sg, children)
20    }
21
22    pub(crate) fn with_children(sg: &'a SceneGraph<T>, children: Option<&'a Children>) -> Self {
23        SceneGraphChildIter {
24            sg,
25            current_node: children.map(|v| v.first),
26        }
27    }
28}
29
30impl<'a, T> Iterator for SceneGraphChildIter<'a, T> {
31    type Item = &'a T;
32
33    fn next(&mut self) -> Option<Self::Item> {
34        let yield_me = self.sg.arena.get(self.current_node?).unwrap();
35        self.current_node = yield_me.next_sibling;
36
37        Some(&yield_me.value)
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44
45    #[test]
46    fn scene_graph_returns_nothing_on_empty_iteration() {
47        let scene_graph = SceneGraph::new("Root");
48
49        assert!(
50            scene_graph
51                .iter_direct_children(NodeIndex::Root)
52                .unwrap()
53                .next()
54                .is_none()
55        );
56    }
57
58    #[test]
59    fn normal_iteration() {
60        let mut sg = SceneGraph::new("Root");
61        let root_idx = NodeIndex::Root;
62        let fg = sg.attach(root_idx, "First Child").unwrap();
63        sg.attach(fg, "First Grandchild").unwrap();
64        sg.attach(fg, "Second Grandchild").unwrap();
65        sg.attach(fg, "Third Grandchild").unwrap();
66
67        assert_eq!(
68            Vec::from_iter(sg.iter_direct_children(fg).unwrap().cloned()),
69            vec!["First Grandchild", "Second Grandchild", "Third Grandchild"]
70        );
71    }
72}