|
| 1 | +use glam::DAffine2; |
| 2 | +use std::collections::HashMap; |
| 3 | +use std::num::NonZeroU64; |
| 4 | + |
| 5 | +use graph_craft::document::{NodeId, NodeNetwork}; |
| 6 | + |
| 7 | +#[derive(Debug, Clone)] |
| 8 | +pub struct DocumentMetadata { |
| 9 | + transforms: HashMap<NodeId, DAffine2>, |
| 10 | + structure: HashMap<LayerNodeIdentifier, NodeRelations>, |
| 11 | +} |
| 12 | + |
| 13 | +impl Default for DocumentMetadata { |
| 14 | + fn default() -> Self { |
| 15 | + Self { |
| 16 | + transforms: HashMap::new(), |
| 17 | + structure: HashMap::from_iter([(LayerNodeIdentifier::ROOT, NodeRelations::default())]), |
| 18 | + } |
| 19 | + } |
| 20 | +} |
| 21 | + |
| 22 | +impl DocumentMetadata { |
| 23 | + pub const fn root(&self) -> LayerNodeIdentifier { |
| 24 | + LayerNodeIdentifier::ROOT |
| 25 | + } |
| 26 | + fn get_structure(&self, node_identifier: LayerNodeIdentifier) -> Option<&NodeRelations> { |
| 27 | + self.structure.get(&node_identifier) |
| 28 | + } |
| 29 | + fn get_structure_mut(&mut self, node_identifier: LayerNodeIdentifier) -> &mut NodeRelations { |
| 30 | + self.structure.entry(node_identifier).or_default() |
| 31 | + } |
| 32 | +} |
| 33 | + |
| 34 | +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| 35 | +pub struct LayerNodeIdentifier(NonZeroU64); |
| 36 | +impl LayerNodeIdentifier { |
| 37 | + const ROOT: Self = LayerNodeIdentifier::new_unchecked(0); |
| 38 | + const fn new_unchecked(node_id: NodeId) -> Self { |
| 39 | + // Safety: will always be >=1 |
| 40 | + Self(unsafe { NonZeroU64::new_unchecked(node_id + 1) }) |
| 41 | + } |
| 42 | + pub fn new(node_id: NodeId, network: &NodeNetwork) -> Self { |
| 43 | + debug_assert!( |
| 44 | + is_layer_node(node_id, network), |
| 45 | + "Layer identifer constructed from non layer node {node_id}: {:#?}", |
| 46 | + network.nodes.get(&node_id) |
| 47 | + ); |
| 48 | + Self::new_unchecked(node_id) |
| 49 | + } |
| 50 | + pub fn to_node(self) -> NodeId { |
| 51 | + u64::from(self.0) - 1 |
| 52 | + } |
| 53 | + pub fn parent(self, document_metadata: &DocumentMetadata) -> Option<LayerNodeIdentifier> { |
| 54 | + document_metadata.get_structure(self).and_then(|relations| relations.parent) |
| 55 | + } |
| 56 | + pub fn previous_sibling(self, document_metadata: &DocumentMetadata) -> Option<LayerNodeIdentifier> { |
| 57 | + document_metadata.get_structure(self).and_then(|relations| relations.previous_sibling) |
| 58 | + } |
| 59 | + pub fn next_sibling(self, document_metadata: &DocumentMetadata) -> Option<LayerNodeIdentifier> { |
| 60 | + document_metadata.get_structure(self).and_then(|relations| relations.next_sibling) |
| 61 | + } |
| 62 | + pub fn first_child(self, document_metadata: &DocumentMetadata) -> Option<LayerNodeIdentifier> { |
| 63 | + document_metadata.get_structure(self).and_then(|relations| relations.first_child) |
| 64 | + } |
| 65 | + pub fn last_child(self, document_metadata: &DocumentMetadata) -> Option<LayerNodeIdentifier> { |
| 66 | + document_metadata.get_structure(self).and_then(|relations| relations.last_child) |
| 67 | + } |
| 68 | + pub fn has_children(self, document_metadata: &DocumentMetadata) -> bool { |
| 69 | + self.first_child(document_metadata).is_some() |
| 70 | + } |
| 71 | + pub fn children(self, document_metadata: &DocumentMetadata) -> AxisIter { |
| 72 | + AxisIter { |
| 73 | + layer_node: self.first_child(document_metadata), |
| 74 | + next_node: Self::next_sibling, |
| 75 | + document_metadata, |
| 76 | + } |
| 77 | + } |
| 78 | + pub fn ancestors(self, document_metadata: &DocumentMetadata) -> AxisIter { |
| 79 | + AxisIter { |
| 80 | + layer_node: Some(self), |
| 81 | + next_node: Self::parent, |
| 82 | + document_metadata, |
| 83 | + } |
| 84 | + } |
| 85 | + pub fn last_children(self, document_metadata: &DocumentMetadata) -> AxisIter { |
| 86 | + AxisIter { |
| 87 | + layer_node: Some(self), |
| 88 | + next_node: Self::last_child, |
| 89 | + document_metadata, |
| 90 | + } |
| 91 | + } |
| 92 | + pub fn decendants(self, document_metadata: &DocumentMetadata) -> DecendantsIter { |
| 93 | + DecendantsIter { |
| 94 | + front: self.first_child(document_metadata), |
| 95 | + back: self.last_child(document_metadata), |
| 96 | + document_metadata, |
| 97 | + } |
| 98 | + } |
| 99 | + pub fn push_front_child(self, document_metadata: &mut DocumentMetadata, new: LayerNodeIdentifier) { |
| 100 | + let parent = document_metadata.get_structure_mut(self); |
| 101 | + let old_first_child = parent.first_child.replace(new); |
| 102 | + parent.last_child.get_or_insert(new); |
| 103 | + if let Some(old_first_child) = old_first_child { |
| 104 | + document_metadata.get_structure_mut(old_first_child).previous_sibling = Some(new); |
| 105 | + document_metadata.get_structure_mut(new).next_sibling = Some(old_first_child); |
| 106 | + } |
| 107 | + document_metadata.get_structure_mut(new).parent = Some(self); |
| 108 | + } |
| 109 | + pub fn push_child(self, document_metadata: &mut DocumentMetadata, new: LayerNodeIdentifier) { |
| 110 | + let parent = document_metadata.get_structure_mut(self); |
| 111 | + let old_last_child = parent.last_child.replace(new); |
| 112 | + parent.first_child.get_or_insert(new); |
| 113 | + if let Some(old_last_child) = old_last_child { |
| 114 | + document_metadata.get_structure_mut(old_last_child).next_sibling = Some(new); |
| 115 | + document_metadata.get_structure_mut(new).previous_sibling = Some(old_last_child); |
| 116 | + } |
| 117 | + document_metadata.get_structure_mut(new).parent = Some(self); |
| 118 | + } |
| 119 | + pub fn add_before(self, document_metadata: &mut DocumentMetadata, new: LayerNodeIdentifier) { |
| 120 | + document_metadata.get_structure_mut(new).next_sibling = Some(self); |
| 121 | + document_metadata.get_structure_mut(new).parent = self.parent(document_metadata); |
| 122 | + let old_previous_sibling = document_metadata.get_structure_mut(self).previous_sibling.replace(new); |
| 123 | + if let Some(old_previous_sibling) = old_previous_sibling { |
| 124 | + document_metadata.get_structure_mut(old_previous_sibling).next_sibling = Some(new); |
| 125 | + document_metadata.get_structure_mut(new).previous_sibling = Some(old_previous_sibling); |
| 126 | + } else { |
| 127 | + self.parent(document_metadata) |
| 128 | + .map(|parent| document_metadata.get_structure_mut(parent)) |
| 129 | + .filter(|structure| structure.first_child == Some(self)) |
| 130 | + .map(|structure| structure.first_child = Some(new)); |
| 131 | + } |
| 132 | + } |
| 133 | + pub fn add_after(self, document_metadata: &mut DocumentMetadata, new: LayerNodeIdentifier) { |
| 134 | + document_metadata.get_structure_mut(new).previous_sibling = Some(self); |
| 135 | + document_metadata.get_structure_mut(new).parent = self.parent(document_metadata); |
| 136 | + let old_next_sibling = document_metadata.get_structure_mut(self).next_sibling.replace(new); |
| 137 | + if let Some(old_next_sibling) = old_next_sibling { |
| 138 | + document_metadata.get_structure_mut(old_next_sibling).previous_sibling = Some(new); |
| 139 | + document_metadata.get_structure_mut(new).next_sibling = Some(old_next_sibling); |
| 140 | + } else { |
| 141 | + self.parent(document_metadata) |
| 142 | + .map(|parent| document_metadata.get_structure_mut(parent)) |
| 143 | + .filter(|structure| structure.last_child == Some(self)) |
| 144 | + .map(|structure| structure.last_child = Some(new)); |
| 145 | + } |
| 146 | + } |
| 147 | + pub fn delete(self, document_metadata: &mut DocumentMetadata) { |
| 148 | + let previous_sibling = self.previous_sibling(document_metadata); |
| 149 | + let next_sibling = self.next_sibling(document_metadata); |
| 150 | + |
| 151 | + if let Some(previous_sibling) = previous_sibling.map(|node| document_metadata.get_structure_mut(node)) { |
| 152 | + previous_sibling.next_sibling = next_sibling; |
| 153 | + } |
| 154 | + |
| 155 | + if let Some(next_sibling) = next_sibling.map(|node| document_metadata.get_structure_mut(node)) { |
| 156 | + next_sibling.previous_sibling = previous_sibling; |
| 157 | + } |
| 158 | + let mut parent = self.parent(document_metadata).map(|parent| document_metadata.get_structure_mut(parent)); |
| 159 | + parent |
| 160 | + .as_mut() |
| 161 | + .filter(|structure| structure.first_child == Some(self)) |
| 162 | + .map(|structure| structure.first_child = next_sibling); |
| 163 | + parent.filter(|structure| structure.last_child == Some(self)).map(|structure| structure.last_child = previous_sibling); |
| 164 | + |
| 165 | + let mut delete = vec![self]; |
| 166 | + delete.extend(self.decendants(document_metadata)); |
| 167 | + for node in delete { |
| 168 | + document_metadata.structure.remove(&node); |
| 169 | + } |
| 170 | + } |
| 171 | +} |
| 172 | +impl From<NodeId> for LayerNodeIdentifier { |
| 173 | + fn from(node_id: NodeId) -> Self { |
| 174 | + Self::new_unchecked(node_id) |
| 175 | + } |
| 176 | +} |
| 177 | +impl From<LayerNodeIdentifier> for NodeId { |
| 178 | + fn from(identifer: LayerNodeIdentifier) -> Self { |
| 179 | + identifer.to_node() |
| 180 | + } |
| 181 | +} |
| 182 | +/// Iterator over specified axis. |
| 183 | +#[derive(Clone)] |
| 184 | +pub struct AxisIter<'a> { |
| 185 | + layer_node: Option<LayerNodeIdentifier>, |
| 186 | + next_node: fn(LayerNodeIdentifier, &DocumentMetadata) -> Option<LayerNodeIdentifier>, |
| 187 | + document_metadata: &'a DocumentMetadata, |
| 188 | +} |
| 189 | + |
| 190 | +impl<'a> Iterator for AxisIter<'a> { |
| 191 | + type Item = LayerNodeIdentifier; |
| 192 | + |
| 193 | + fn next(&mut self) -> Option<Self::Item> { |
| 194 | + let layer_node = self.layer_node.take(); |
| 195 | + self.layer_node = layer_node.and_then(|node| (self.next_node)(node, self.document_metadata)); |
| 196 | + layer_node |
| 197 | + } |
| 198 | +} |
| 199 | + |
| 200 | +#[derive(Clone)] |
| 201 | +pub struct DecendantsIter<'a> { |
| 202 | + front: Option<LayerNodeIdentifier>, |
| 203 | + back: Option<LayerNodeIdentifier>, |
| 204 | + document_metadata: &'a DocumentMetadata, |
| 205 | +} |
| 206 | + |
| 207 | +impl<'a> Iterator for DecendantsIter<'a> { |
| 208 | + type Item = LayerNodeIdentifier; |
| 209 | + |
| 210 | + fn next(&mut self) -> Option<Self::Item> { |
| 211 | + if self.front == self.back { |
| 212 | + self.back = None; |
| 213 | + self.front.take() |
| 214 | + } else { |
| 215 | + let layer_node = self.front.take(); |
| 216 | + if let Some(layer_node) = layer_node { |
| 217 | + self.front = layer_node |
| 218 | + .first_child(self.document_metadata) |
| 219 | + .or_else(|| layer_node.ancestors(self.document_metadata).find_map(|ancestor| ancestor.next_sibling(self.document_metadata))); |
| 220 | + } |
| 221 | + layer_node |
| 222 | + } |
| 223 | + } |
| 224 | +} |
| 225 | +impl<'a> DoubleEndedIterator for DecendantsIter<'a> { |
| 226 | + fn next_back(&mut self) -> Option<Self::Item> { |
| 227 | + if self.front == self.back { |
| 228 | + self.front = None; |
| 229 | + self.back.take() |
| 230 | + } else { |
| 231 | + let layer_node = self.back.take(); |
| 232 | + if let Some(layer_node) = layer_node { |
| 233 | + self.back = layer_node |
| 234 | + .previous_sibling(self.document_metadata) |
| 235 | + .and_then(|sibling| sibling.last_children(self.document_metadata).last()) |
| 236 | + .or_else(|| layer_node.parent(self.document_metadata)); |
| 237 | + } |
| 238 | + |
| 239 | + layer_node |
| 240 | + } |
| 241 | + } |
| 242 | +} |
| 243 | + |
| 244 | +#[derive(Debug, Clone, Copy, Default)] |
| 245 | +pub struct NodeRelations { |
| 246 | + parent: Option<LayerNodeIdentifier>, |
| 247 | + previous_sibling: Option<LayerNodeIdentifier>, |
| 248 | + next_sibling: Option<LayerNodeIdentifier>, |
| 249 | + first_child: Option<LayerNodeIdentifier>, |
| 250 | + last_child: Option<LayerNodeIdentifier>, |
| 251 | +} |
| 252 | + |
| 253 | +fn is_layer_node(node: NodeId, network: &NodeNetwork) -> bool { |
| 254 | + node == LayerNodeIdentifier::ROOT.to_node() || network.nodes.get(&node).is_some_and(|node| node.name == "Layer") |
| 255 | +} |
| 256 | + |
| 257 | +#[test] |
| 258 | +fn test_tree() { |
| 259 | + let mut document_metadata = DocumentMetadata::default(); |
| 260 | + let root = document_metadata.root(); |
| 261 | + let document_metadata = &mut document_metadata; |
| 262 | + root.push_child(document_metadata, LayerNodeIdentifier::new_unchecked(3)); |
| 263 | + assert_eq!(root.children(document_metadata).collect::<Vec<_>>(), vec![LayerNodeIdentifier::new_unchecked(3)]); |
| 264 | + root.push_child(document_metadata, LayerNodeIdentifier::new_unchecked(6)); |
| 265 | + assert_eq!(root.children(document_metadata).map(LayerNodeIdentifier::to_node).collect::<Vec<_>>(), vec![3, 6]); |
| 266 | + assert_eq!(root.decendants(document_metadata).map(LayerNodeIdentifier::to_node).collect::<Vec<_>>(), vec![3, 6]); |
| 267 | + LayerNodeIdentifier::new_unchecked(3).add_after(document_metadata, LayerNodeIdentifier::new_unchecked(4)); |
| 268 | + LayerNodeIdentifier::new_unchecked(3).add_before(document_metadata, LayerNodeIdentifier::new_unchecked(2)); |
| 269 | + LayerNodeIdentifier::new_unchecked(6).add_before(document_metadata, LayerNodeIdentifier::new_unchecked(5)); |
| 270 | + LayerNodeIdentifier::new_unchecked(6).add_after(document_metadata, LayerNodeIdentifier::new_unchecked(9)); |
| 271 | + LayerNodeIdentifier::new_unchecked(6).push_child(document_metadata, LayerNodeIdentifier::new_unchecked(8)); |
| 272 | + LayerNodeIdentifier::new_unchecked(6).push_front_child(document_metadata, LayerNodeIdentifier::new_unchecked(7)); |
| 273 | + root.push_front_child(document_metadata, LayerNodeIdentifier::new_unchecked(1)); |
| 274 | + assert_eq!(root.children(document_metadata).map(LayerNodeIdentifier::to_node).collect::<Vec<_>>(), vec![1, 2, 3, 4, 5, 6, 9]); |
| 275 | + assert_eq!( |
| 276 | + root.decendants(document_metadata).map(LayerNodeIdentifier::to_node).collect::<Vec<_>>(), |
| 277 | + vec![1, 2, 3, 4, 5, 6, 7, 8, 9] |
| 278 | + ); |
| 279 | + assert_eq!( |
| 280 | + root.decendants(document_metadata).map(LayerNodeIdentifier::to_node).rev().collect::<Vec<_>>(), |
| 281 | + vec![9, 8, 7, 6, 5, 4, 3, 2, 1] |
| 282 | + ); |
| 283 | + assert!(root.children(document_metadata).all(|child| child.parent(document_metadata) == Some(root))); |
| 284 | + LayerNodeIdentifier::new_unchecked(6).delete(document_metadata); |
| 285 | + LayerNodeIdentifier::new_unchecked(1).delete(document_metadata); |
| 286 | + assert_eq!(root.children(document_metadata).map(LayerNodeIdentifier::to_node).collect::<Vec<_>>(), vec![2, 3, 4, 5, 9]); |
| 287 | + assert_eq!(root.decendants(document_metadata).map(LayerNodeIdentifier::to_node).collect::<Vec<_>>(), vec![2, 3, 4, 5, 9]); |
| 288 | + assert_eq!(root.decendants(document_metadata).map(LayerNodeIdentifier::to_node).rev().collect::<Vec<_>>(), vec![9, 5, 4, 3, 2]); |
| 289 | +} |
0 commit comments