1use std::ops::{Index, IndexMut};
4use std::sync::atomic::{AtomicU64, Ordering};
5
6use apace_traits::node_id::NodeId;
7use slotmap::{Key as _, KeyData, SlotMap};
8
9use crate::Node;
10
11slotmap::new_key_type! {
12 struct NodeKey;
15}
16
17#[inline(always)]
18fn to_key(id: NodeId) -> NodeKey {
19 NodeKey::from(KeyData::from_ffi(id.as_u64()))
20}
21
22#[inline(always)]
23fn to_id(key: NodeKey) -> NodeId {
24 NodeId::from_u64(key.data().as_ffi())
25}
26
27pub struct NodeTree {
35 map: SlotMap<NodeKey, Node>,
36 geometry_generation: AtomicU64,
41 viewport_scroll: crate::Point<f64>,
44}
45
46impl NodeTree {
47 pub(crate) fn new() -> Self {
48 Self {
49 map: SlotMap::with_key(),
50 geometry_generation: AtomicU64::new(1),
51 viewport_scroll: crate::Point::ZERO,
52 }
53 }
54
55 pub fn viewport_scroll(&self) -> crate::Point<f64> {
56 self.viewport_scroll
57 }
58
59 pub(crate) fn set_viewport_scroll(&mut self, scroll: crate::Point<f64>) {
62 self.viewport_scroll = scroll;
63 self.bump_geometry_generation();
64 }
65
66 pub fn geometry_generation(&self) -> u64 {
68 self.geometry_generation.load(Ordering::Relaxed)
69 }
70
71 pub(crate) fn bump_geometry_generation(&self) {
72 self.geometry_generation.fetch_add(1, Ordering::Relaxed);
73 }
74
75 pub fn len(&self) -> usize {
77 self.map.len()
78 }
79
80 pub fn is_empty(&self) -> bool {
81 self.map.is_empty()
82 }
83
84 pub fn contains_key(&self, id: NodeId) -> bool {
86 self.map.contains_key(to_key(id))
87 }
88
89 pub fn get(&self, id: NodeId) -> Option<&Node> {
91 self.map.get(to_key(id))
92 }
93
94 pub fn get_mut(&mut self, id: NodeId) -> Option<&mut Node> {
96 self.map.get_mut(to_key(id))
97 }
98
99 pub(crate) fn insert_with_key(&mut self, f: impl FnOnce(NodeId) -> Node) -> NodeId {
101 to_id(self.map.insert_with_key(|key| f(to_id(key))))
102 }
103
104 pub(crate) fn remove(&mut self, id: NodeId) -> Option<Node> {
106 self.map.remove(to_key(id))
107 }
108
109 pub fn iter(&self) -> impl Iterator<Item = (NodeId, &Node)> {
111 self.map.iter().map(|(key, node)| (to_id(key), node))
112 }
113
114 pub fn iter_mut(&mut self) -> impl Iterator<Item = (NodeId, &mut Node)> {
116 self.map.iter_mut().map(|(key, node)| (to_id(key), node))
117 }
118}
119
120impl Index<NodeId> for NodeTree {
121 type Output = Node;
122
123 #[track_caller]
124 #[inline]
125 fn index(&self, id: NodeId) -> &Node {
126 &self.map[to_key(id)]
127 }
128}
129
130impl IndexMut<NodeId> for NodeTree {
131 #[track_caller]
132 #[inline]
133 fn index_mut(&mut self, id: NodeId) -> &mut Node {
134 &mut self.map[to_key(id)]
135 }
136}