From 6bcbb9f82f62b1f9aa00287110fbce64e1d2f0db Mon Sep 17 00:00:00 2001 From: Dennis Date: Tue, 4 Jan 2022 00:32:55 +0100 Subject: [PATCH] Replace recursive tree traversal with prefix matching --- editor/src/document/document_file.rs | 35 +++++++++++----------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/editor/src/document/document_file.rs b/editor/src/document/document_file.rs index 54cbc262c3..4d7142e66f 100644 --- a/editor/src/document/document_file.rs +++ b/editor/src/document/document_file.rs @@ -274,30 +274,23 @@ impl DocumentMessageHandler { } pub fn selected_layers_without_children(&self) -> Vec> { - // Traversing the layer tree recursively was chosen for both readability and instead of an n^2 comparison approach. - // A future optmiziation would be not needing to start at the root [] - fn recurse_layer_tree(ctx: &DocumentMessageHandler, mut path: Vec, without_children: &mut Vec>, selected: bool) { - if let Ok(folder) = ctx.graphene_document.folder(&path) { - for child in folder.list_layers() { - path.push(*child); - let selected_or_parent_selected = selected || ctx.selected_layers_contains(&path); - let selected_without_any_parent_selected = !selected && ctx.selected_layers_contains(&path); - if ctx.graphene_document.is_folder(&path) { - if selected_without_any_parent_selected { - without_children.push(path.clone()); - } - recurse_layer_tree(ctx, path.clone(), without_children, selected_or_parent_selected); - } else if selected_without_any_parent_selected { - without_children.push(path.clone()); - } - path.pop(); - } + let mut sorted_layers = self.selected_layers().collect::>(); + sorted_layers.sort(); + + if sorted_layers.is_empty() { + return vec![]; + } + + let mut current_path = sorted_layers.first().unwrap(); + let mut keep = vec![current_path.to_vec()]; + for path in &sorted_layers { + if !path.starts_with(current_path) { + keep.push(path.to_vec()); + current_path = path; } } - let mut without_children: Vec> = vec![]; - recurse_layer_tree(self, vec![], &mut without_children, false); - without_children + keep } pub fn selected_layers_contains(&self, path: &[LayerId]) -> bool {