From 72e638c5da62213409acdbab9db6f8aa73bc9e71 Mon Sep 17 00:00:00 2001 From: TrueDoctor Date: Tue, 18 Jan 2022 22:21:44 +0100 Subject: [PATCH] Generify functions in document.rs (#488) * Generify functions in document.rs --- editor/src/document/transformation.rs | 2 +- editor/src/viewport_tools/tools/select.rs | 4 +- graphene/src/document.rs | 51 +++++++++++++++-------- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/editor/src/document/transformation.rs b/editor/src/document/transformation.rs index 1bdb3c8b..1461e2a2 100644 --- a/editor/src/document/transformation.rs +++ b/editor/src/document/transformation.rs @@ -242,7 +242,7 @@ impl<'a> Selected<'a> { let transformation = pivot * delta * pivot.inverse(); // TODO: Cache the result of `shallowest_unique_layers` to avoid this heavy computation every frame of movement, see https://github.com/GraphiteEditor/Graphite/pull/481 - for layer_path in Document::shallowest_unique_layers(self.selected.iter().map(|path| path.as_slice())) { + for layer_path in Document::shallowest_unique_layers(self.selected.iter()) { let parent_folder_path = &layer_path[..layer_path.len() - 1]; let original_layer_transforms = *self.original_transforms.get(layer_path).unwrap(); diff --git a/editor/src/viewport_tools/tools/select.rs b/editor/src/viewport_tools/tools/select.rs index 350d403a..dd281564 100644 --- a/editor/src/viewport_tools/tools/select.rs +++ b/editor/src/viewport_tools/tools/select.rs @@ -236,10 +236,10 @@ impl Fsm for SelectToolFsmState { let closest_move = data.snap_handler.snap_layers(document, &data.layers_dragging, mouse_delta); // TODO: Cache the result of `shallowest_unique_layers` to avoid this heavy computation every frame of movement, see https://github.com/GraphiteEditor/Graphite/pull/481 - for path in Document::shallowest_unique_layers(data.layers_dragging.iter().map(|path| path.as_slice())) { + for path in Document::shallowest_unique_layers(data.layers_dragging.iter()) { responses.push_front( Operation::TransformLayerInViewport { - path: path.to_vec(), + path: path.clone(), transform: DAffine2::from_translation(mouse_delta + closest_move).to_cols_array(), } .into(), diff --git a/graphene/src/document.rs b/graphene/src/document.rs index 604d0bca..c78afa85 100644 --- a/graphene/src/document.rs +++ b/graphene/src/document.rs @@ -57,10 +57,10 @@ impl Document { /// Returns a reference to the requested folder. Fails if the path does not exist, /// or if the requested layer is not of type folder. - pub fn folder(&self, path: &[LayerId]) -> Result<&Folder, DocumentError> { + pub fn folder(&self, path: impl AsRef<[LayerId]>) -> Result<&Folder, DocumentError> { let mut root = &self.root; - for id in path { - root = root.as_folder()?.layer(*id).ok_or_else(|| DocumentError::LayerNotFound(path.into()))?; + for id in path.as_ref() { + root = root.as_folder()?.layer(*id).ok_or_else(|| DocumentError::LayerNotFound(path.as_ref().into()))?; } root.as_folder() } @@ -98,11 +98,16 @@ impl Document { layers.reduce(|a, b| &a[..a.iter().zip(b.iter()).take_while(|&(a, b)| a == b).count()]).unwrap_or_default() } - pub fn folders<'a>(&'a self, layers: impl Iterator) -> impl Iterator { - layers.filter(|layer| self.is_folder(layer)) + /// Filters out the non folders from an iterator of paths. + /// Takes and Iterator over &[LayerId] or &Vec. + pub fn folders<'a, T>(&'a self, layers: impl Iterator + 'a) -> impl Iterator + 'a + where + T: AsRef<[LayerId]> + std::cmp::Ord + 'a, + { + layers.filter(|layer| self.is_folder(layer.as_ref())) } - // Returns the shallowest folder given the selection, even if the selection doesn't contain any folders + /// Returns the shallowest folder given the selection, even if the selection doesn't contain any folders pub fn shallowest_common_folder<'a>(&self, layers: impl Iterator) -> Result<&'a [LayerId], DocumentError> { let common_prefix_of_path = self.common_layer_path_prefix(layers); @@ -112,23 +117,35 @@ impl Document { }) } - // Return returns all folders that are not contained in any other of the given folders - pub fn shallowest_folders<'a>(&'a self, layers: impl Iterator) -> Vec<&[LayerId]> { + /// Returns all folders that are not contained in any other of the given folders + /// Takes and Iterator over &[LayerId] or &Vec. + pub fn shallowest_folders<'a, T>(&'a self, layers: impl Iterator) -> Vec + where + T: AsRef<[LayerId]> + std::cmp::Ord + 'a, + { Self::shallowest_unique_layers(self.folders(layers)) } - // Return returns all layers that are not contained in any other of the given folders - pub fn shallowest_unique_layers<'a>(layers: impl Iterator) -> Vec<&'a [LayerId]> { + /// Returns all layers that are not contained in any other of the given folders + /// Takes and Iterator over &[LayerId] or &Vec. + pub fn shallowest_unique_layers<'a, T>(layers: impl Iterator) -> Vec + where + T: AsRef<[LayerId]> + std::cmp::Ord + 'a, + { let mut sorted_layers: Vec<_> = layers.collect(); sorted_layers.sort(); // Sorting here creates groups of similar UUID paths - sorted_layers.dedup_by(|a, b| a.starts_with(b)); + sorted_layers.dedup_by(|a, b| a.as_ref().starts_with(b.as_ref())); sorted_layers } - // Deepest to shallowest (longest to shortest path length) - pub fn sorted_folders_by_depth<'a>(&'a self, layers: impl Iterator) -> Vec<&'a [LayerId]> { + /// Deepest to shallowest (longest to shortest path length) + /// Takes and Iterator over &[LayerId] or &Vec. + pub fn sorted_folders_by_depth<'a, T>(&'a self, layers: impl Iterator) -> Vec + where + T: AsRef<[LayerId]> + std::cmp::Ord + 'a, + { let mut folders: Vec<_> = self.folders(layers).collect(); - folders.sort_by_key(|a| std::cmp::Reverse(a.len())); + folders.sort_by_key(|a| std::cmp::Reverse(a.as_ref().len())); folders } @@ -140,8 +157,8 @@ impl Document { } } - pub fn is_folder(&self, path: &[LayerId]) -> bool { - return self.folder(path).is_ok(); + pub fn is_folder(&self, path: impl AsRef<[LayerId]>) -> bool { + return self.folder(path.as_ref()).is_ok(); } // Determines which layer is closer to the root, if path_a return true, if path_b return false @@ -262,7 +279,7 @@ impl Document { if !self.layer(path)?.visible { return Ok(()); } - if let Ok(folder) = self.folder(path) { + if let Ok(folder) = self.folder(&path) { for layer in folder.layer_ids.iter() { path.push(*layer); self.visible_layers(path, paths)?;