1#![doc = include_str!("../README.md")]
2#![deny(rust_2018_idioms)]
3#![deny(missing_docs)]
4#![deny(rustdoc::broken_intra_doc_links)]
5
6use std::{cmp::Eq, collections::HashMap};
7use thunderdome::{Arena, Index};
8
9mod child_iter;
10mod detatch_iter;
11mod iter;
12mod iter_mut;
13
14pub use child_iter::SceneGraphChildIter;
15pub use detatch_iter::{DetachedNode, SceneGraphDetachIter};
16pub use iter::SceneGraphIter;
17pub use iter_mut::SceneGraphIterMut;
18
19#[derive(Debug)]
32pub struct SceneGraph<T> {
33 pub root: T,
35 arena: Arena<Node<T>>,
36 root_children: Option<Children>,
37}
38
39impl<T> SceneGraph<T> {
40 pub const fn new(root: T) -> Self {
42 Self {
43 arena: Arena::new(),
44 root,
45 root_children: None,
46 }
47 }
48
49 pub fn clear(&mut self) {
55 self.arena.clear();
56 self.root_children = None;
57 }
58
59 pub fn len(&self) -> usize {
61 self.arena.len()
62 }
63
64 pub fn is_empty(&self) -> bool {
66 self.root_children.is_none()
67 }
68
69 pub fn attach_at_root(&mut self, value: T) -> NodeIndex {
73 self.attach(NodeIndex::Root, value).unwrap()
74 }
75
76 pub fn attach(&mut self, parent: NodeIndex, value: T) -> Result<NodeIndex, ParentNodeNotFound> {
78 let new_idx = self.arena.insert(Node::new(value, parent));
80 self.place_node(parent, new_idx)?;
81
82 Ok(NodeIndex::Branch(new_idx))
83 }
84
85 pub fn attach_graph(
88 &mut self,
89 parent: NodeIndex,
90 mut other_graph: SceneGraph<T>,
91 ) -> Result<(NodeIndex, HashMap<NodeIndex, NodeIndex>), ParentNodeNotFound> {
92 let other_root = other_graph.root;
93 let new_root_idx = self.attach(parent, other_root)?;
94
95 let mut helper_map = HashMap::new();
96 helper_map.insert(NodeIndex::Root, new_root_idx);
97
98 let detach_iter = SceneGraphDetachIter::new(&mut other_graph.arena, NodeIndex::Root, other_graph.root_children);
99
100 for detached_node in detach_iter {
101 let parent_place = helper_map.get(&detached_node.parent_idx).unwrap();
102 let new_idx = self.attach(*parent_place, detached_node.node_value).unwrap();
103
104 helper_map.insert(detached_node.node_idx, new_idx);
105 }
106
107 Ok((new_root_idx, helper_map))
108 }
109
110 pub fn detach(&mut self, node_index: NodeIndex) -> Option<SceneGraph<T>> {
116 let node_index = match node_index {
117 NodeIndex::Root => return None,
118 NodeIndex::Branch(idx) => idx,
119 };
120
121 let node = self.arena.remove(node_index)?;
122 let mut new_sg = SceneGraph::new(node.value);
123
124 let mut helper_map = std::collections::HashMap::new();
125 helper_map.insert(NodeIndex::Branch(node_index), NodeIndex::Root);
126
127 for detached_node in SceneGraphDetachIter::new(&mut self.arena, NodeIndex::Branch(node_index), node.children) {
128 println!("detached_node = {:#?}", detached_node);
129
130 let parent_place = match detached_node.parent_idx {
131 NodeIndex::Root => NodeIndex::Root,
132 NodeIndex::Branch(_) => *helper_map.get(&detached_node.parent_idx).unwrap(),
133 };
134 let new_idx = new_sg.attach(parent_place, detached_node.node_value).unwrap();
135
136 helper_map.insert(detached_node.node_idx, new_idx);
137 }
138
139 self.fix_parent(node.next_sibling, node.last_sibling, node.parent, node_index);
140
141 Some(new_sg)
142 }
143
144 pub fn move_node(&mut self, moving_node_idx: NodeIndex, new_parent: NodeIndex) -> Result<(), NodeDoesNotExist> {
147 let moving_node_idx = match moving_node_idx {
148 NodeIndex::Root => return Err(NodeDoesNotExist),
149 NodeIndex::Branch(idx) => {
150 if !self.arena.contains(idx) {
151 return Err(NodeDoesNotExist);
152 }
153
154 idx
155 }
156 };
157
158 if let NodeIndex::Branch(idx) = new_parent {
159 if !self.arena.contains(idx) {
160 return Err(NodeDoesNotExist);
161 }
162 }
163
164 let moving_node = self.arena.get_mut(moving_node_idx).expect("we checked earlier");
166 let old_parent = moving_node.parent;
167 moving_node.parent = new_parent;
168
169 let next_sibling = moving_node.next_sibling;
170 moving_node.next_sibling = None;
171 let last_sibling = moving_node.last_sibling;
172
173 self.fix_parent(next_sibling, last_sibling, old_parent, moving_node_idx);
175
176 self.place_node(new_parent, moving_node_idx)
178 .expect("we checked earlier");
179
180 Ok(())
181 }
182
183 pub fn remove(&mut self, node_index: NodeIndex) {
186 let index = match node_index {
187 NodeIndex::Root => panic!("you cannot remove the root"),
188 NodeIndex::Branch(index) => index,
189 };
190
191 let Some(node) = self.arena.remove(index) else { return };
192
193 for _v in SceneGraphDetachIter::new(&mut self.arena, node_index, node.children) {}
195
196 self.fix_parent(node.next_sibling, node.last_sibling, node.parent, index);
197 }
198
199 pub fn contains(&self, node_index: NodeIndex) -> bool {
201 match node_index {
202 NodeIndex::Root => true,
203 NodeIndex::Branch(idx) => self.arena.contains(idx),
204 }
205 }
206
207 pub fn get(&self, node_index: NodeIndex) -> Option<&Node<T>> {
210 match node_index {
211 NodeIndex::Root => None,
212 NodeIndex::Branch(idx) => self.arena.get(idx),
213 }
214 }
215
216 pub fn get_mut(&mut self, node_index: NodeIndex) -> Option<&mut Node<T>> {
219 match node_index {
220 NodeIndex::Root => None,
221 NodeIndex::Branch(idx) => self.arena.get_mut(idx),
222 }
223 }
224
225 pub fn root(&self) -> &T {
227 &self.root
228 }
229
230 pub fn root_mut(&mut self) -> &mut T {
232 &mut self.root
233 }
234
235 pub fn parent(&self, node_index: NodeIndex) -> Option<NodeIndex> {
240 self.get(node_index).map(|v| v.parent)
241 }
242
243 pub fn iter_mut(&mut self) -> SceneGraphIterMut<'_, T> {
245 SceneGraphIterMut::new(self, NodeIndex::Root)
246 }
247
248 pub fn iter(&self) -> SceneGraphIter<'_, T> {
250 self.iter_from_node(NodeIndex::Root).unwrap()
251 }
252
253 pub fn iter_out_of_order(&self) -> impl Iterator<Item = (NodeIndex, &T)> {
255 self.arena.iter().map(|(k, v)| (NodeIndex::Branch(k), &v.value))
256 }
257
258 pub fn iter_from_node(&self, node_index: NodeIndex) -> Result<SceneGraphIter<'_, T>, NodeDoesNotExist> {
260 let (parent_value, children) = match node_index {
261 NodeIndex::Root => (&self.root, self.root_children.as_ref()),
262 NodeIndex::Branch(idx) => {
263 let node = self.arena.get(idx).ok_or(NodeDoesNotExist)?;
264
265 (&node.value, node.children.as_ref())
266 }
267 };
268
269 Ok(SceneGraphIter::new(self, parent_value, children))
270 }
271
272 pub fn iter_mut_from_node(&mut self, node_index: NodeIndex) -> Result<SceneGraphIterMut<'_, T>, NodeDoesNotExist> {
274 match node_index {
275 NodeIndex::Root => {}
276 NodeIndex::Branch(idx) => {
277 if !self.arena.contains(idx) {
278 return Err(NodeDoesNotExist);
279 }
280 }
281 };
282
283 Ok(SceneGraphIterMut::new(self, node_index))
284 }
285
286 pub fn iter_detach_from_root(&mut self) -> SceneGraphDetachIter<'_, T> {
290 SceneGraphDetachIter::new(&mut self.arena, NodeIndex::Root, self.root_children.take())
291 }
292
293 pub fn iter_detach(&mut self, node_index: NodeIndex) -> Result<SceneGraphDetachIter<'_, T>, NodeDoesNotExist> {
296 let children = match node_index {
297 NodeIndex::Root => self.root_children.take(),
298 NodeIndex::Branch(br) => match self.arena.get_mut(br) {
299 Some(v) => v.children.take(),
300 None => return Err(NodeDoesNotExist),
301 },
302 };
303
304 Ok(SceneGraphDetachIter::new(&mut self.arena, node_index, children))
305 }
306
307 pub fn iter_direct_children(
320 &self,
321 parent_index: NodeIndex,
322 ) -> Result<SceneGraphChildIter<'_, T>, NodeDoesNotExist> {
323 if let NodeIndex::Branch(idx) = parent_index {
324 self.arena.get(idx).ok_or(NodeDoesNotExist)?;
325 }
326
327 Ok(SceneGraphChildIter::new(self, parent_index))
328 }
329
330 fn place_node(&mut self, new_parent: NodeIndex, node_to_place: Index) -> Result<(), ParentNodeNotFound> {
332 let parent_children = match new_parent {
334 NodeIndex::Root => &mut self.root_children,
335 NodeIndex::Branch(idx) => &mut self.arena.get_mut(idx).ok_or(ParentNodeNotFound)?.children,
336 };
337
338 match parent_children.as_mut() {
340 Some(children) => {
341 let old_last = children.last;
342 children.last = node_to_place;
343
344 let mut last_sibling = &mut self.arena[old_last];
345 last_sibling.next_sibling = Some(node_to_place);
346
347 self.arena[node_to_place].last_sibling = Some(old_last);
349 }
350 None => {
351 *parent_children = Some(Children {
353 first: node_to_place,
354 last: node_to_place,
355 });
356 }
357 };
358
359 Ok(())
360 }
361
362 fn fix_parent(
364 &mut self,
365 removed_next_sibling: Option<Index>,
366 removed_last_sibling: Option<Index>,
367 removed_parent: NodeIndex,
368 removed_idx: Index,
369 ) {
370 let mut parent_children = match removed_parent {
373 NodeIndex::Root => self.root_children.unwrap(),
374 NodeIndex::Branch(idx) => self.arena[idx].children.unwrap(),
375 };
376
377 if parent_children.first == parent_children.last && parent_children.first == removed_idx {
378 match removed_parent {
379 NodeIndex::Root => self.root_children = None,
380 NodeIndex::Branch(idx) => self.arena[idx].children = None,
381 };
382 } else {
383 if parent_children.first == removed_idx {
386 parent_children.first = removed_next_sibling.unwrap();
387 }
388
389 if parent_children.last == removed_idx {
390 parent_children.last = removed_last_sibling.unwrap();
391 }
392
393 if let Some(last_sibling) = removed_last_sibling {
394 let last_sibling = self.arena.get_mut(last_sibling).unwrap();
395 last_sibling.next_sibling = removed_next_sibling;
396 }
397
398 if let Some(next_sibling) = removed_next_sibling {
399 let next_sibling = self.arena.get_mut(next_sibling).unwrap();
400 next_sibling.last_sibling = removed_last_sibling;
401 }
402
403 match removed_parent {
405 NodeIndex::Root => self.root_children = Some(parent_children),
406 NodeIndex::Branch(idx) => self.arena[idx].children = Some(parent_children),
407 };
408 }
409 }
410}
411
412impl<'a, T> IntoIterator for &'a SceneGraph<T> {
413 type Item = (&'a T, &'a T);
414
415 type IntoIter = SceneGraphIter<'a, T>;
416
417 fn into_iter(self) -> Self::IntoIter {
418 self.iter()
419 }
420}
421
422impl<'a, T> IntoIterator for &'a mut SceneGraph<T> {
423 type Item = (&'a mut T, &'a mut T);
424
425 type IntoIter = SceneGraphIterMut<'a, T>;
426
427 fn into_iter(self) -> Self::IntoIter {
428 self.iter_mut()
429 }
430}
431
432#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
435pub struct Node<T> {
436 pub value: T,
438 parent: NodeIndex,
439 children: Option<Children>,
440 last_sibling: Option<Index>,
441 next_sibling: Option<Index>,
442}
443
444impl<T> Node<T> {
445 fn new(value: T, parent: NodeIndex) -> Self {
446 Self {
447 value,
448 parent,
449 last_sibling: None,
450 next_sibling: None,
451 children: None,
452 }
453 }
454
455 pub fn has_children(&self) -> bool {
457 self.children.is_some()
458 }
459
460 pub fn iter_direct_children<'a>(&'a self, sg: &'a SceneGraph<T>) -> SceneGraphChildIter<'a, T> {
474 SceneGraphChildIter::with_children(sg, self.children.as_ref())
475 }
476
477 pub fn parent(&self) -> NodeIndex {
479 self.parent
480 }
481}
482
483#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
484struct Children {
485 first: Index,
486 last: Index,
487}
488
489impl<T> std::fmt::Debug for Node<T> {
490 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
491 f.debug_struct("Node")
492 .field("parent", &self.parent)
493 .field("children", &self.children)
494 .field("next_sibling", &self.next_sibling)
495 .finish()
496 }
497}
498
499#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
501pub enum NodeIndex {
502 Root,
504
505 Branch(thunderdome::Index),
507}
508
509impl NodeIndex {
510 #[must_use]
514 pub fn is_root(&self) -> bool {
515 matches!(self, Self::Root)
516 }
517}
518
519#[derive(Debug, PartialEq, Eq, thiserror::Error)]
520#[error("parent node not found")]
521pub struct ParentNodeNotFound;
523
524#[derive(Debug, PartialEq, Eq, thiserror::Error)]
525#[error("node does not exist")]
526pub struct NodeDoesNotExist;
528
529#[cfg(test)]
530mod tests {
531 use super::*;
532
533 fn get_values(sg: &SceneGraph<&'static str>) -> Vec<&'static str> {
534 let mut out = vec![];
535 for (_, v) in sg.iter() {
536 out.push(*v);
537 }
538
539 out
540 }
541
542 #[test]
543 fn basic_attach() {
544 let mut sg = SceneGraph::new("Root");
545 let root_idx = NodeIndex::Root;
546 sg.attach(root_idx, "First Child").unwrap();
547 let second_child = sg.attach(root_idx, "Second Child").unwrap();
548 sg.attach(second_child, "First Grandchild").unwrap();
549
550 assert_eq!(get_values(&sg), vec!["First Child", "Second Child", "First Grandchild"]);
551 }
552
553 #[test]
554 fn attach_internals() {
555 let mut sg = SceneGraph::new("Root");
556
557 assert_eq!(sg.root_children, None);
558
559 let root_idx = NodeIndex::Root;
560
561 let first_idx = sg.attach(root_idx, "First Child").unwrap();
562
563 assert_eq!(NodeIndex::Branch(sg.root_children.unwrap().first), first_idx);
565 assert_eq!(NodeIndex::Branch(sg.root_children.unwrap().last), first_idx);
566
567 let second_idx = sg.attach(root_idx, "Second Child").unwrap();
568
569 assert_eq!(NodeIndex::Branch(sg.root_children.unwrap().first), first_idx);
570 assert_eq!(NodeIndex::Branch(sg.root_children.unwrap().last), second_idx);
571
572 assert_eq!(
573 sg.get(first_idx).unwrap().next_sibling.map(NodeIndex::Branch),
574 Some(second_idx)
575 );
576 assert_eq!(sg.get(first_idx).unwrap().last_sibling, None);
577
578 assert_eq!(sg.get(second_idx).unwrap().next_sibling, None);
579 assert_eq!(
580 sg.get(second_idx).unwrap().last_sibling.map(NodeIndex::Branch),
581 Some(first_idx)
582 );
583 }
584
585 #[test]
586 fn detach_basic() {
587 let mut sg = SceneGraph::new("Root");
588 let first_child = sg.attach_at_root("First Child");
589 let second_child = sg.attach_at_root("Second Child");
590 let third_child = sg.attach_at_root("Third Child");
591
592 let second_child = sg.detach(second_child).unwrap();
593 assert_eq!(*second_child.root(), "Second Child");
594
595 assert_eq!(NodeIndex::Branch(sg.root_children.unwrap().first), first_child);
596 assert_eq!(NodeIndex::Branch(sg.root_children.unwrap().last), third_child);
597
598 assert_eq!(sg.get(first_child).unwrap().last_sibling, None);
599 assert_eq!(
600 sg.get(first_child).unwrap().next_sibling.map(NodeIndex::Branch),
601 Some(third_child)
602 );
603
604 assert_eq!(
605 sg.get(third_child).unwrap().last_sibling.map(NodeIndex::Branch),
606 Some(first_child)
607 );
608 assert_eq!(sg.get(third_child).unwrap().next_sibling, None);
609
610 assert_eq!(get_values(&sg), vec!["First Child", "Third Child"]);
611
612 let g = sg.attach(third_child, "First Grandchild").unwrap();
613 sg.attach(g, "Second Grandchild").unwrap();
614 let g_3 = sg.attach(g, "Third Grandchild").unwrap();
615 sg.attach(g_3, "First Greatgrandchild").unwrap();
616
617 let third_child_tree = sg.detach(third_child).unwrap();
618 assert_eq!(get_values(&sg), vec!["First Child"]);
619 assert_eq!(
620 get_values(&third_child_tree),
621 vec![
622 "First Grandchild",
623 "Second Grandchild",
624 "Third Grandchild",
625 "First Greatgrandchild"
626 ]
627 );
628 assert_eq!(*third_child_tree.root(), "Third Child");
629 }
630
631 #[test]
632 fn move_node() {
633 let mut sg = SceneGraph::new("Root");
634 let fg = sg.attach(NodeIndex::Root, "First Child").unwrap();
635 sg.attach(fg, "First Grandchild").unwrap();
636 sg.attach(fg, "Second Grandchild").unwrap();
637 sg.attach(fg, "Third Grandchild").unwrap();
638 let second_child = sg.attach(NodeIndex::Root, "Second Child").unwrap();
639
640 assert_eq!(
641 Vec::from_iter(sg.iter_direct_children(fg).unwrap().cloned()),
642 vec!["First Grandchild", "Second Grandchild", "Third Grandchild",]
643 );
644
645 sg.move_node(fg, second_child).unwrap();
646
647 assert_eq!(
648 Vec::from_iter(sg.iter_direct_children(NodeIndex::Root).unwrap().cloned()),
649 vec!["Second Child",]
650 );
651
652 assert_eq!(
653 Vec::from_iter(sg.iter_direct_children(fg).unwrap().cloned()),
654 vec!["First Grandchild", "Second Grandchild", "Third Grandchild",]
655 );
656
657 assert_eq!(
658 Vec::from_iter(sg.iter_direct_children(second_child).unwrap().cloned()),
659 vec!["First Child",]
660 );
661 }
662
663 #[test]
664 fn clear_works() {
665 let input_node: Vec<_> = (0..50_000).map(|v| format!("Node_{}", v)).collect();
666 let mut sg = SceneGraph::new("Root");
667
668 for v in input_node.iter() {
669 sg.attach_at_root(v);
670 }
671
672 sg.clear();
673
674 assert_eq!(sg.len(), 0);
675 assert!(sg.is_empty());
676 assert!(sg.root_children.is_none());
677 assert!(sg.arena.is_empty());
678 }
679}