From b03827f32bf8d610f91552e39018cec816a43a38 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler Date: Tue, 21 Jan 2025 18:15:13 +0100 Subject: [PATCH 01/15] Introduce `BlueprintTreeData` fixed bug in data fixed data --- Cargo.lock | 2 +- crates/viewer/re_blueprint_tree/Cargo.toml | 1 + .../re_blueprint_tree/src/blueprint_tree.rs | 2 +- crates/viewer/re_blueprint_tree/src/data.rs | 486 ++++++++++++++++++ crates/viewer/re_blueprint_tree/src/lib.rs | 1 + crates/viewer/re_ui/src/filter_widget.rs | 7 +- 6 files changed, 496 insertions(+), 3 deletions(-) create mode 100644 crates/viewer/re_blueprint_tree/src/data.rs diff --git a/Cargo.lock b/Cargo.lock index a9994e83c3b1..3b9a8bfef05c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5636,7 +5636,7 @@ name = "re_blueprint_tree" version = "0.22.0-alpha.1+dev" dependencies = [ "egui", - "egui_kittest", + "egui_tiles", "itertools 0.13.0", "re_chunk_store", "re_context_menu", diff --git a/crates/viewer/re_blueprint_tree/Cargo.toml b/crates/viewer/re_blueprint_tree/Cargo.toml index a6489b8d6326..4d6327fa1bde 100644 --- a/crates/viewer/re_blueprint_tree/Cargo.toml +++ b/crates/viewer/re_blueprint_tree/Cargo.toml @@ -31,6 +31,7 @@ re_viewer_context.workspace = true re_viewport_blueprint.workspace = true egui.workspace = true +egui_tiles.workspace = true itertools.workspace = true smallvec.workspace = true diff --git a/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs b/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs index 8fb9b8d967f0..18988ff09897 100644 --- a/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs +++ b/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs @@ -389,7 +389,7 @@ impl BlueprintTree { let is_item_hovered = ctx.selection_state().highlight_for_ui_element(&item) == HoverHighlight::Hovered; - let class = &view.class(ctx.view_class_registry); + let class = view.class(ctx.view_class_registry); let view_name = view.display_name_or_default(); let item_content = list_item::LabelContent::new(view_name.as_ref()) diff --git a/crates/viewer/re_blueprint_tree/src/data.rs b/crates/viewer/re_blueprint_tree/src/data.rs new file mode 100644 index 000000000000..09699d1a92e6 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/src/data.rs @@ -0,0 +1,486 @@ +//! Data structure describing the contents of the blueprint tree +//! +//! Notes: +//! - Design goal: single tree walking pass over the entire data. +//! +//! Missing: +//! - deferred tree walking (collapsed, non-filtered path) +//! - caching + +use std::ops::Range; + +use itertools::Itertools; +use smallvec::SmallVec; + +use re_entity_db::InstancePath; +use re_log_types::external::re_types_core::ViewClassIdentifier; +use re_log_types::{EntityPath, EntityPathPart}; +use re_types::blueprint::components::Visible; +use re_ui::filter_widget::FilterMatcher; +use re_viewer_context::{ + ContainerId, Contents, ContentsName, DataQueryResult, DataResultNode, ViewId, ViewerContext, +}; +use re_viewport_blueprint::{ContainerBlueprint, ViewBlueprint, ViewportBlueprint}; + +use crate::data_result_node_or_path::DataResultNodeOrPath; + +#[derive(Debug, Default)] +pub struct BlueprintTreeData { + pub root_container: Option, +} + +impl BlueprintTreeData { + pub fn from_blueprint_and_filter( + ctx: &ViewerContext<'_>, + viewport_blueprint: &ViewportBlueprint, + filter_matcher: &FilterMatcher, + ) -> Self { + re_tracing::profile_function!(); + + Self { + root_container: viewport_blueprint + .container(&viewport_blueprint.root_container) + .and_then(|container_blueprint| { + ContainerData::from_blueprint_and_filter( + ctx, + viewport_blueprint, + container_blueprint, + filter_matcher, + ) + }), + } + } +} + +// --- + +#[derive(Debug)] +pub enum ContentsData { + Container(ContainerData), + View(ViewData), +} + +#[derive(Debug)] +pub struct ContainerData { + pub id: ContainerId, + pub name: ContentsName, + pub kind: egui_tiles::ContainerKind, + pub visible: bool, + pub default_open: bool, + + pub children: Vec, +} + +impl ContainerData { + pub fn from_blueprint_and_filter( + ctx: &ViewerContext<'_>, + viewport_blueprint: &ViewportBlueprint, + container_blueprint: &ContainerBlueprint, + filter_matcher: &FilterMatcher, + ) -> Option { + let children = container_blueprint + .contents + .iter() + .filter_map(|content| match content { + Contents::Container(container_id) => { + if let Some(container_blueprint) = viewport_blueprint.container(container_id) { + Self::from_blueprint_and_filter( + ctx, + viewport_blueprint, + container_blueprint, + filter_matcher, + ) + .map(ContentsData::Container) + } else { + re_log::warn_once!( + "Failed to find container {container_id} in ViewportBlueprint" + ); + None + } + } + Contents::View(view_id) => { + if let Some(view_blueprint) = viewport_blueprint.view(view_id) { + ViewData::from_blueprint_and_filter(ctx, view_blueprint, filter_matcher) + .map(ContentsData::View) + } else { + re_log::warn_once!("Failed to find view {view_id} in ViewportBlueprint"); + None + } + } + }) + .collect_vec(); + + // everything was filtered out + if filter_matcher.is_active() && children.is_empty() { + return None; + } + + Some(Self { + id: container_blueprint.id, + name: container_blueprint.display_name_or_default(), + kind: container_blueprint.container_kind, + visible: container_blueprint.visible, + default_open: true, + children, + }) + } +} + +// --- + +#[derive(Debug)] +pub struct ViewData { + pub id: ViewId, + + pub class_identifier: ViewClassIdentifier, + + pub name: ContentsName, + pub visible: bool, + pub default_open: bool, + + pub origin_tree: Option, + pub projection_trees: Vec, +} + +impl ViewData { + fn from_blueprint_and_filter( + ctx: &ViewerContext<'_>, + view_blueprint: &ViewBlueprint, + filter_matcher: &FilterMatcher, + ) -> Option { + re_tracing::profile_function!(); + + let query_result = ctx.lookup_query_result(view_blueprint.id); + let result_tree = &query_result.tree; + + // + // In origin tree data results + // + + let mut hierarchy = Vec::with_capacity(10); + let origin_tree = DataResultData::from_data_result_and_filter( + ctx, + view_blueprint, + query_result, + &DataResultNodeOrPath::from_path_lookup(result_tree, &view_blueprint.space_origin), + false, + &mut hierarchy, + filter_matcher, + false, + ); + + if cfg!(debug_assertions) { + debug_assert!(hierarchy.is_empty()); + } else { + hierarchy.clear(); + } + + // + // Projection data results + // + + let mut projections = Vec::new(); + result_tree.visit(&mut |node| { + if node + .data_result + .entity_path + .starts_with(&view_blueprint.space_origin) + { + // If it's under the origin, we're not interested, stop recursing. + false + } else if node.data_result.tree_prefix_only { + // Keep recursing until we find a projection. + true + } else { + projections.push(node); + + // No further recursion needed in this branch, everything below is included + // in the projection (or shouldn't be included if the projection has already + // been filtered out). + false + } + }); + + let projection_trees = projections + .into_iter() + .filter_map(|node| { + let projection_tree = DataResultData::from_data_result_and_filter( + ctx, + view_blueprint, + query_result, + &DataResultNodeOrPath::DataResultNode(node), + true, + &mut hierarchy, + filter_matcher, + false, + ); + + if cfg!(debug_assertions) { + debug_assert!(hierarchy.is_empty()); + } else { + hierarchy.clear(); + } + + projection_tree + }) + .collect_vec(); + + if origin_tree.is_none() && projection_trees.is_empty() { + return None; + } + + let default_open = filter_matcher.is_active() + || origin_tree.as_ref().map_or(true, |data_result_data| { + default_open_for_data_result(data_result_data.children.len()) + }); + + Some(Self { + id: view_blueprint.id, + class_identifier: view_blueprint.class_identifier(), + name: view_blueprint.display_name_or_default(), + visible: view_blueprint.visible, + default_open, + origin_tree, + projection_trees, + }) + } +} + +// --- + +/// The kind of thing we may be displaying in the tree +#[derive(Debug)] +pub enum DataResultKind { + EmptyOriginPlaceholder, + + DataResult, + + OriginProjectionPlaceholder, +} + +#[derive(Debug)] +pub struct DataResultData { + pub kind: DataResultKind, + pub entity_path: EntityPath, + pub visible: bool, + + pub view_id: ViewId, + + pub label: String, + pub highlight_sections: SmallVec<[Range; 2]>, + + pub default_open: bool, + + pub children: Vec, +} + +impl DataResultData { + #[allow(clippy::too_many_arguments)] + fn from_data_result_and_filter( + ctx: &ViewerContext<'_>, + view_blueprint: &ViewBlueprint, + query_result: &DataQueryResult, + data_result_or_path: &DataResultNodeOrPath<'_>, + projection: bool, + hierarchy: &mut Vec, + filter_matcher: &FilterMatcher, + mut is_already_a_match: bool, + ) -> Option { + re_tracing::profile_function!(); + + // Early out. + if filter_matcher.matches_nothing() { + return None; + } + + let entity_path = data_result_or_path.path().clone(); + let data_result_node = data_result_or_path.data_result_node(); + let visible = data_result_node.is_some_and(|node| node.data_result.is_visible(ctx)); + + let (label, should_pop) = if let Some(entity_part) = entity_path.last() { + hierarchy.push(entity_part.clone()); + (entity_part.ui_string(), true) + } else { + ("/ (root)".to_owned(), false) + }; + + // + // Filtering + // + + // TODO(ab): we're currently only matching on the last part of `hierarchy`. Technically, + // this means that `herarchy` is not needed at all. It will however be needed when we match + // across multiple parts, so it's good to have it already. + let (entity_part_matches, highlight_sections) = if filter_matcher.matches_everything() { + // fast path (filter is inactive) + (true, SmallVec::new()) + } else if let Some(entity_part) = hierarchy.last() { + // Nominal case of matching the hierarchy. + if let Some(match_sections) = filter_matcher.find_matches(&entity_part.ui_string()) { + (true, match_sections.collect()) + } else { + (false, SmallVec::new()) + } + } else { + // `entity_path` is the root, it can never match anything + (false, SmallVec::new()) + }; + + // We want to keep entire branches if a single of its node matches. So we must propagate the + // "matched" state so we can make the right call when we reach leaf nodes. + is_already_a_match |= entity_part_matches; + + // + // "Nominal" data result node (extracted for deduplication). + // + + let view_id = view_blueprint.id; + let mut from_data_result_node = |data_result_node: &DataResultNode, + highlight_sections: SmallVec<_>, + entity_path: EntityPath, + label, + default_open| { + let mut children = data_result_node + .children + .iter() + .filter_map(|child_handle| { + let child_node = query_result.tree.lookup_node(*child_handle); + + debug_assert!( + child_node.is_some(), + "DataResultNode {data_result_node:?} has an invalid child" + ); + + child_node.and_then(|child_node| { + Self::from_data_result_and_filter( + ctx, + view_blueprint, + query_result, + &DataResultNodeOrPath::DataResultNode(child_node), + projection, + hierarchy, + filter_matcher, + is_already_a_match, + ) + }) + }) + .collect_vec(); + + children.sort_by(|a, b| a.entity_path.cmp(&b.entity_path)); + + (is_already_a_match || !children.is_empty()).then(|| Self { + kind: DataResultKind::DataResult, + entity_path, + visible, + view_id, + label, + highlight_sections, + default_open, + children, + }) + }; + + // + // Handle all situations + // + + let result = if projection { + // projections are collapsed by default + let default_open = filter_matcher.is_active(); + + if entity_path == view_blueprint.space_origin { + is_already_a_match.then(|| Self { + kind: DataResultKind::OriginProjectionPlaceholder, + entity_path, + visible, + view_id, + label, + highlight_sections, + default_open, + children: vec![], + }) + } else if let Some(data_result_node) = data_result_node { + from_data_result_node( + data_result_node, + highlight_sections, + entity_path, + label, + filter_matcher.is_active(), + ) + } else { + // TODO(ab): what are the circumstances for this? Should we warn about it? + None + } + } else { + // empty origin case + if entity_path == view_blueprint.space_origin && data_result_node.is_none() { + is_already_a_match.then(|| Self { + kind: DataResultKind::EmptyOriginPlaceholder, + entity_path, + visible, + view_id, + label, + highlight_sections, + default_open: false, // not hierarchical anyway + children: vec![], + }) + } else if let Some(data_result_node) = data_result_node { + let default_open = filter_matcher.is_active() + || default_open_for_data_result(data_result_node.children.len()); + + from_data_result_node( + data_result_node, + highlight_sections, + entity_path, + label, + default_open, + ) + } else { + // TODO(ab): what are the circumstances for this? Should we warn about it? + None + } + }; + + if should_pop { + hierarchy.pop(); + } + + result + } + + pub fn instance_path(&self) -> InstancePath { + self.entity_path.clone().into() + } + + /// Update the visibility of this data result. + pub fn update_visibility(&self, ctx: &ViewerContext<'_>, visible: bool) { + let query_result = ctx.lookup_query_result(self.view_id); + let result_tree = &query_result.tree; + if let Some(data_result) = result_tree.lookup_result_by_path(&self.entity_path) { + data_result.save_recursive_override_or_clear_if_redundant( + ctx, + &query_result.tree, + &Visible::from(visible), + ); + } + } + + /// Remove this data result from the view. + pub fn remove_data_result_from_view( + &self, + ctx: &ViewerContext<'_>, + viewport_blueprint: &ViewportBlueprint, + ) { + if let Some(view_blueprint) = viewport_blueprint.view(&self.view_id) { + view_blueprint + .contents + .remove_subtree_and_matching_rules(ctx, self.entity_path.clone()); + } + } +} + +/// If a group or view has a total of this number of elements, show its subtree by default? +//TODO(ab): taken from legacy implementation, does it still make sense? +fn default_open_for_data_result(num_children: usize) -> bool { + 2 <= num_children && num_children <= 3 +} diff --git a/crates/viewer/re_blueprint_tree/src/lib.rs b/crates/viewer/re_blueprint_tree/src/lib.rs index bc1f8000b387..7163bddc5aae 100644 --- a/crates/viewer/re_blueprint_tree/src/lib.rs +++ b/crates/viewer/re_blueprint_tree/src/lib.rs @@ -1,6 +1,7 @@ //! This crate implements the UI for the blueprint tree in the left panel. mod blueprint_tree; +pub(crate) mod data; mod data_result_node_or_path; pub use blueprint_tree::BlueprintTree; diff --git a/crates/viewer/re_ui/src/filter_widget.rs b/crates/viewer/re_ui/src/filter_widget.rs index 16b72f1e5d41..092dca3c1f61 100644 --- a/crates/viewer/re_ui/src/filter_widget.rs +++ b/crates/viewer/re_ui/src/filter_widget.rs @@ -191,6 +191,11 @@ impl FilterMatcher { } } + /// Is the filter currently active? + pub fn is_active(&self) -> bool { + self.lowercase_query.is_some() + } + /// Is the filter set to match everything? /// /// Can be used by client code to short-circuit more expansive matching logic. @@ -223,7 +228,7 @@ impl FilterMatcher { /// Returns `None` when there is no match. /// Returns `Some` when the filter is inactive (and thus matches everything), or if there is an /// actual match. - fn find_matches(&self, text: &str) -> Option> + '_> { + pub fn find_matches(&self, text: &str) -> Option> + '_> { let query = match self.lowercase_query.as_deref() { None => { return Some(Either::Left(std::iter::empty())); From 20d271c36d8c9fcc9e4cace108e1910e60a74a88 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler Date: Thu, 23 Jan 2025 14:52:27 +0100 Subject: [PATCH 02/15] Add snapshot tests covering various view blueprint trees layout test passing for old code improved test code fixed test --- Cargo.lock | 1 + .../re_blueprint_tree/src/blueprint_tree.rs | 2 +- .../view_structure_test/no-query/empty.png | 3 + .../no-query/multiple_proj.png | 3 + .../no-query/non_root_origin.png | 3 + .../no-query/proj_with_placeholder.png | 3 + .../no-query/root_origin.png | 3 + .../no-query/single_proj.png | 3 + .../no-query/unknown_origin.png | 3 + .../view_structure_test/query-path/empty.png | 3 + .../query-path/multiple_proj.png | 3 + .../query-path/non_root_origin.png | 3 + .../query-path/proj_with_placeholder.png | 3 + .../query-path/root_origin.png | 3 + .../query-path/single_proj.png | 3 + .../query-path/unknown_origin.png | 3 + .../view_structure_test/query-t/empty.png | 3 + .../query-t/multiple_proj.png | 3 + .../query-t/non_root_origin.png | 3 + .../query-t/proj_with_placeholder.png | 3 + .../query-t/root_origin.png | 3 + .../query-t/single_proj.png | 3 + .../query-t/unknown_origin.png | 3 + .../view_structure_test/query-void/empty.png | 3 + .../query-void/multiple_proj.png | 3 + .../query-void/non_root_origin.png | 3 + .../query-void/proj_with_placeholder.png | 3 + .../query-void/root_origin.png | 3 + .../query-void/single_proj.png | 3 + .../query-void/unknown_origin.png | 3 + .../tests/view_structure_test.rs | 200 ++++++++++++++++++ 31 files changed, 286 insertions(+), 1 deletion(-) create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/empty.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/multiple_proj.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/non_root_origin.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/proj_with_placeholder.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/root_origin.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/single_proj.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/unknown_origin.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/empty.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/multiple_proj.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/non_root_origin.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/proj_with_placeholder.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/root_origin.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/single_proj.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/unknown_origin.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/empty.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/multiple_proj.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/non_root_origin.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/proj_with_placeholder.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/root_origin.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/single_proj.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/unknown_origin.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/empty.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/multiple_proj.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/non_root_origin.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/proj_with_placeholder.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/root_origin.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/single_proj.png create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/unknown_origin.png create mode 100644 crates/viewer/re_blueprint_tree/tests/view_structure_test.rs diff --git a/Cargo.lock b/Cargo.lock index 3b9a8bfef05c..dd30a966c1f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5636,6 +5636,7 @@ name = "re_blueprint_tree" version = "0.22.0-alpha.1+dev" dependencies = [ "egui", + "egui_kittest", "egui_tiles", "itertools 0.13.0", "re_chunk_store", diff --git a/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs b/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs index 18988ff09897..45de078d12b7 100644 --- a/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs +++ b/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs @@ -1030,7 +1030,7 @@ impl BlueprintTree { self.candidate_drop_parent_container_id.as_ref() == Some(container_id) } - fn collapse_scope(&self) -> CollapseScope { + pub fn collapse_scope(&self) -> CollapseScope { match self.filter_state.session_id() { None => CollapseScope::BlueprintTree, Some(session_id) => CollapseScope::BlueprintTreeFiltered { session_id }, diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/empty.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/empty.png new file mode 100644 index 000000000000..c9e0993fa6c4 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/empty.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d1510b277bbf65c8a611b8d40ba3cd3ac1f4210644e76e9a1bd6e967989a5f1 +size 15428 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/multiple_proj.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/multiple_proj.png new file mode 100644 index 000000000000..88ef30df521c --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/multiple_proj.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cca67ba9bb1cabbb116a1a7efc9277fb139e6563e93c575f2c9d60bbe41ef837 +size 22066 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/non_root_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/non_root_origin.png new file mode 100644 index 000000000000..239e2d74123d --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/non_root_origin.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb9cbc8f2527196235106bd1d64f795d44f4f21965bdecbaf21453bd17335c5f +size 20070 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/proj_with_placeholder.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/proj_with_placeholder.png new file mode 100644 index 000000000000..559a159104b4 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/proj_with_placeholder.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:376195ce2c78131a841a1821ff671f385e573288ddec37d5c5d5650b675c4622 +size 29183 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/root_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/root_origin.png new file mode 100644 index 000000000000..7d21ee0c4570 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/root_origin.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4691797c61a5102ffd886b4710c8dc4b80a70b715d7a8b25018a6dfce4c98ff0 +size 24161 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/single_proj.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/single_proj.png new file mode 100644 index 000000000000..7d4c9b089603 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/single_proj.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7395f95a2a90fc21b7065ac0d69f54366b2894af313be320f2f978b15193ae96 +size 23788 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/unknown_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/unknown_origin.png new file mode 100644 index 000000000000..5176adc59a78 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/unknown_origin.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:083cbd36db0cd1bbf54ebf88dd8bb6fabf778e859f1b1cea9228a4b09aa2d23f +size 16721 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/empty.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/empty.png new file mode 100644 index 000000000000..1ba890fb1537 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/empty.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28b601ca8a0080da7219f9765fedb28bc6429a0f4ca963bbb5ee161a080e84b1 +size 10203 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/multiple_proj.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/multiple_proj.png new file mode 100644 index 000000000000..010be458fb8a --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/multiple_proj.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:35d2d48be2ec03f47a324eaebc80042554b13f49c47140bfeaa8857965e94b27 +size 20761 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/non_root_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/non_root_origin.png new file mode 100644 index 000000000000..f478928a2829 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/non_root_origin.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:290e00ace697a77e8441ff8e5a6b0885e7e6edf59fccc6f858d8f9b93fec5d06 +size 15051 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/proj_with_placeholder.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/proj_with_placeholder.png new file mode 100644 index 000000000000..624ce7b62f76 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/proj_with_placeholder.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd2762035276d3aca3e99ab3de647f5208b1dc244b7de59c74b387962a6ba35a +size 19876 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/root_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/root_origin.png new file mode 100644 index 000000000000..39325a1624d6 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/root_origin.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7fc9099bc9bce0336a1f82b849009709efbe6bf682d7422377d51b4873574502 +size 21422 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/single_proj.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/single_proj.png new file mode 100644 index 000000000000..6a50a73d88e6 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/single_proj.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40bf039f0c7eeb948e93a3a56928b6d06b76980f0df11d1167643a4920c5fb22 +size 22484 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/unknown_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/unknown_origin.png new file mode 100644 index 000000000000..1ba890fb1537 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/unknown_origin.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28b601ca8a0080da7219f9765fedb28bc6429a0f4ca963bbb5ee161a080e84b1 +size 10203 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/empty.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/empty.png new file mode 100644 index 000000000000..4a05b6f46985 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/empty.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5d221abb19b3e530beb74c287780f536e490c59dcade30b30f06a54dbf0c10e +size 9650 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/multiple_proj.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/multiple_proj.png new file mode 100644 index 000000000000..e04149cb42c3 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/multiple_proj.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:235cb85c828dcb94ae3343b94ab27d5073a92ffd15dcb9ea65b15024563f58cf +size 20257 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/non_root_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/non_root_origin.png new file mode 100644 index 000000000000..0c783b9bf9d0 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/non_root_origin.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28464a68f749aa952d3b67d6efe45d820b7157882b9e4c4de491fa32a772e0f5 +size 19413 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/proj_with_placeholder.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/proj_with_placeholder.png new file mode 100644 index 000000000000..978cb4c08beb --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/proj_with_placeholder.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67aa1073686f2f03bcd84a1ba1a0005256ae403d10d92421cd84ac654086b222 +size 26866 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/root_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/root_origin.png new file mode 100644 index 000000000000..31084b881928 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/root_origin.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21888ed224e75ec7e5e36d889f4944292c7fb16edad1dc1cc25821f29ab1dae3 +size 23599 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/single_proj.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/single_proj.png new file mode 100644 index 000000000000..7e4994add3aa --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/single_proj.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f8ebe3a4bfa35246fbcc0ad3e624328b69b36e926637951b9193ab3e28c04b0 +size 22032 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/unknown_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/unknown_origin.png new file mode 100644 index 000000000000..4a05b6f46985 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/unknown_origin.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5d221abb19b3e530beb74c287780f536e490c59dcade30b30f06a54dbf0c10e +size 9650 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/empty.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/empty.png new file mode 100644 index 000000000000..bf4a8cd4db6f --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/empty.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:65102d91a1f5f99c7eda9c17d4bedd66291788084f443e9e1d1ecdd1790ca5a6 +size 10232 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/multiple_proj.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/multiple_proj.png new file mode 100644 index 000000000000..6d5c8d147e6d --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/multiple_proj.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b7000931dba10b877f9333762a1efe33314f7a35e7ec2392cfae5db3d0cfc6b +size 19711 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/non_root_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/non_root_origin.png new file mode 100644 index 000000000000..9bcdecd6854f --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/non_root_origin.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42d6cb895d0c28c778155c0b7c99366e30ad6cba0c2b1567ff952da6f6709a41 +size 17939 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/proj_with_placeholder.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/proj_with_placeholder.png new file mode 100644 index 000000000000..9bcdecd6854f --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/proj_with_placeholder.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42d6cb895d0c28c778155c0b7c99366e30ad6cba0c2b1567ff952da6f6709a41 +size 17939 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/root_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/root_origin.png new file mode 100644 index 000000000000..10a359268b6a --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/root_origin.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c74ec0d271594999ac2f1c86b960176bb62cd8f8cdb2920450e24d035eba0cec +size 19523 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/single_proj.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/single_proj.png new file mode 100644 index 000000000000..dae559723ae3 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/single_proj.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a64ddb5afa41613ce6741c854c6fbd7d2af489eeb7eb5bdeae43a347e24bd79b +size 20557 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/unknown_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/unknown_origin.png new file mode 100644 index 000000000000..bf4a8cd4db6f --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-void/unknown_origin.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:65102d91a1f5f99c7eda9c17d4bedd66291788084f443e9e1d1ecdd1790ca5a6 +size 10232 diff --git a/crates/viewer/re_blueprint_tree/tests/view_structure_test.rs b/crates/viewer/re_blueprint_tree/tests/view_structure_test.rs new file mode 100644 index 000000000000..dd1e3e961da4 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/view_structure_test.rs @@ -0,0 +1,200 @@ +//! Test suite dedicated to snapshot the way we present various kinds of blueprint tree structures +//! with a focus on various view contents. + +use egui::Vec2; +use egui_kittest::{SnapshotError, SnapshotOptions}; +use itertools::Itertools; +use re_blueprint_tree::BlueprintTree; +use re_chunk_store::external::re_chunk::ChunkBuilder; +use re_chunk_store::RowId; +use re_log_types::{build_frame_nr, EntityPath}; +use re_types::archetypes::Points3D; +use re_viewer_context::test_context::TestContext; +use re_viewer_context::{RecommendedView, ViewClass}; +use re_viewport_blueprint::test_context_ext::TestContextExt; +use re_viewport_blueprint::{ViewBlueprint, ViewportBlueprint}; + +#[derive(Debug, Clone, Copy)] +enum RecordingKind { + /// No entities are logged. + Emtpy, + + /// Some placeholder entity hierarchy is logged. + Regular, +} + +struct TestCase { + name: &'static str, + + origin: EntityPath, + entity_filter: &'static str, + + recording_kind: RecordingKind, +} + +fn base_test_cases() -> impl Iterator { + [ + TestCase { + name: "empty", + origin: EntityPath::root(), + entity_filter: "$origin/**", + recording_kind: RecordingKind::Emtpy, + }, + TestCase { + name: "root_origin", + origin: EntityPath::root(), + entity_filter: "$origin/**", + recording_kind: RecordingKind::Regular, + }, + TestCase { + name: "non_root_origin", + origin: EntityPath::from("/path/to"), + entity_filter: "$origin/**", + + recording_kind: RecordingKind::Regular, + }, + TestCase { + name: "unknown_origin", + origin: EntityPath::from("/wrong/path"), + entity_filter: "$origin/**", + recording_kind: RecordingKind::Regular, + }, + TestCase { + name: "single_proj", + origin: EntityPath::from("/center/way"), + entity_filter: "$origin/**\n/path/to/**", + recording_kind: RecordingKind::Regular, + }, + TestCase { + name: "proj_with_placeholder", + origin: EntityPath::from("/path/to"), + entity_filter: "/**", + recording_kind: RecordingKind::Regular, + }, + TestCase { + name: "multiple_proj", + origin: EntityPath::from("/center/way"), + entity_filter: "$origin/**\n/path/to/right\n/path/to/the/**", + recording_kind: RecordingKind::Regular, + }, + ] + .into_iter() +} + +fn test_context(kind: RecordingKind) -> TestContext { + let mut test_context = TestContext::default(); + + test_context.register_view_class::(); + + match kind { + RecordingKind::Emtpy => {} + RecordingKind::Regular => { + test_context.log_entity("/path/to/left".into(), add_point_to_chunk_builder); + test_context.log_entity("/path/to/right".into(), add_point_to_chunk_builder); + test_context.log_entity("/path/to/the/void".into(), add_point_to_chunk_builder); + test_context.log_entity("/center/way".into(), add_point_to_chunk_builder); + } + } + + test_context +} + +fn add_point_to_chunk_builder(builder: ChunkBuilder) -> ChunkBuilder { + builder.with_archetype( + RowId::new(), + [build_frame_nr(0)], + &Points3D::new([[0.0, 0.0, 0.0]]), + ) +} + +#[test] +fn run_all_test_cases() { + let errors = [None, Some("t"), Some("void"), Some("path")] + .into_iter() + .flat_map(|filter_query| { + base_test_cases() + .map(move |test_case| (filter_query, run_test_case(test_case, filter_query))) + }) + .filter_map(|(filter_query, result)| result.err().map(|err| (filter_query, err))) + .collect_vec(); + + for (filter_query, error) in &errors { + eprintln!("ERR: filter '{filter_query:?}': {error:?}"); + } + + assert!(errors.is_empty(), "Some test cases failed"); +} + +fn run_test_case(test_case: TestCase, filter_query: Option<&str>) -> Result<(), SnapshotError> { + let mut test_context = test_context(test_case.recording_kind); + + let view_id = test_context.setup_viewport_blueprint(|_, blueprint| { + let view = ViewBlueprint::new( + re_view_spatial::SpatialView3D::identifier(), + RecommendedView { + origin: test_case.origin, + query_filter: test_case + .entity_filter + .try_into() + .expect("invalid entity filter"), + }, + ); + + let view_id = view.id; + blueprint.add_views(std::iter::once(view), None, None); + + // TODO(ab): add containers in the hierarchy (requires work on the container API, + // currently very cumbersome to use for testing purposes). + + view_id + }); + + let mut blueprint_tree = BlueprintTree::default(); + + // This trick here is to run the blueprint panel for a frame, such that it registers the current + // application id. This way, the blueprint panel will not discard the filter state we set up + // when it's run for the snapshot. + test_context.run_in_egui_central_panel(|ctx, ui| { + let blueprint = + ViewportBlueprint::try_from_db(ctx.store_context.blueprint, ctx.blueprint_query); + + blueprint_tree.show(ctx, &blueprint, ui); + }); + + if let Some(filter_query) = filter_query { + blueprint_tree.activate_filter(filter_query); + } + + let mut harness = test_context + .setup_kittest_for_rendering() + .with_size(Vec2::new(400.0, 800.0)) + .build_ui(|ui| { + test_context.run(&ui.ctx().clone(), |viewer_ctx| { + re_context_menu::collapse_expand::collapse_expand_view( + viewer_ctx, + &view_id, + blueprint_tree.collapse_scope(), + true, + ); + + let blueprint = ViewportBlueprint::try_from_db( + viewer_ctx.store_context.blueprint, + viewer_ctx.blueprint_query, + ); + + blueprint_tree.show(viewer_ctx, &blueprint, ui); + }); + + test_context.handle_system_commands(); + }); + + harness.run(); + + let options = SnapshotOptions::default().output_path(format!( + "tests/snapshots/view_structure_test/{}", + filter_query + .map(|query| format!("query-{query}")) + .unwrap_or("no-query".to_owned()) + )); + harness.try_snapshot_options(test_case.name, &options) +} From 63c6386d438ef5ce4f4a0055131bd29b4177595e Mon Sep 17 00:00:00 2001 From: Antoine Beyeler Date: Wed, 22 Jan 2025 18:37:13 +0100 Subject: [PATCH 03/15] Integration of `BlueprintTreeData` in the blueprint tree fixed blueprint --- .../re_blueprint_tree/src/blueprint_tree.rs | 694 ++++++------------ crates/viewer/re_ui/src/filter_widget.rs | 11 +- 2 files changed, 220 insertions(+), 485 deletions(-) diff --git a/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs b/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs index 45de078d12b7..164db62818c6 100644 --- a/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs +++ b/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs @@ -1,25 +1,23 @@ use egui::{Response, Ui}; -use itertools::Itertools; use smallvec::SmallVec; use re_context_menu::{context_menu_ui_for_item_with_context, SelectionUpdateBehavior}; use re_data_ui::item_ui::guess_instance_path_icon; use re_entity_db::InstancePath; use re_log_types::{ApplicationId, EntityPath}; -use re_types::blueprint::components::Visible; +use re_ui::filter_widget::format_matching_text; use re_ui::{ drag_and_drop::DropTarget, filter_widget, list_item, ContextExt as _, DesignTokens, UiExt as _, }; use re_viewer_context::{ contents_name_style, icon_for_container_kind, CollapseScope, ContainerId, Contents, - DataQueryResult, DataResultNode, DragAndDropFeedback, DragAndDropPayload, HoverHighlight, Item, - ItemContext, SystemCommandSender, ViewId, ViewerContext, -}; -use re_viewport_blueprint::{ - ui::show_add_view_or_container_modal, ViewBlueprint, ViewportBlueprint, + DragAndDropFeedback, DragAndDropPayload, HoverHighlight, Item, ItemContext, + SystemCommandSender, ViewId, ViewerContext, }; +use re_viewport_blueprint::{ui::show_add_view_or_container_modal, ViewportBlueprint}; -use crate::data_result_node_or_path::DataResultNodeOrPath; +use crate::data::BlueprintTreeData; +use crate::data::{ContainerData, ContentsData, DataResultData, DataResultKind, ViewData}; /// Holds the state of the blueprint tree UI. #[derive(Default)] @@ -37,7 +35,7 @@ pub struct BlueprintTree { /// See [`Self::is_candidate_drop_parent_container`] for details. candidate_drop_parent_container_id: Option, - /// Candidate parent container to be drawn on next frame. + /// Candidate parent container to be drawn on the next frame. /// /// We double-buffer this value to deal with ordering constraints. next_candidate_drop_parent_container_id: Option, @@ -62,9 +60,11 @@ impl BlueprintTree { pub fn show( &mut self, ctx: &ViewerContext<'_>, - viewport: &ViewportBlueprint, + viewport_blueprint: &ViewportBlueprint, ui: &mut egui::Ui, ) { + re_tracing::profile_function!(); + // Invalidate the filter widget if the store id has changed. if self.filter_state_app_id.as_ref() != Some(&ctx.store_context.app_id) { self.filter_state = Default::default(); @@ -90,9 +90,9 @@ impl BlueprintTree { } }) .menu_button(&re_ui::icons::MORE, |ui| { - add_new_view_or_container_menu_button(ctx, viewport, ui); + add_new_view_or_container_menu_button(ctx, viewport_blueprint, ui); set_blueprint_to_default_menu_buttons(ctx, ui); - set_blueprint_to_auto_menu_button(ctx, viewport, ui); + set_blueprint_to_auto_menu_button(ctx, viewport_blueprint, ui); }), ); }); @@ -102,14 +102,14 @@ impl BlueprintTree { // This call is excluded from `panel_content` because it has a ScrollArea, which should not be // inset. Instead, it calls panel_content itself inside the ScrollArea. - self.tree_ui(ctx, viewport, ui); + self.tree_ui(ctx, viewport_blueprint, ui); } /// Show the blueprint panel tree view. fn tree_ui( &mut self, ctx: &ViewerContext<'_>, - viewport: &ViewportBlueprint, + viewport_blueprint: &ViewportBlueprint, ui: &mut egui::Ui, ) { re_tracing::profile_function!(); @@ -118,20 +118,27 @@ impl BlueprintTree { self.candidate_drop_parent_container_id = self.next_candidate_drop_parent_container_id; self.next_candidate_drop_parent_container_id = None; - let filter_matcher = self.filter_state.filter(); + let blueprint_tree_data = + std::hint::black_box(BlueprintTreeData::from_blueprint_and_filter( + ctx, + viewport_blueprint, + &self.filter_state.filter(), + )); egui::ScrollArea::both() .id_salt("blueprint_tree_scroll_area") .auto_shrink([true, false]) .show(ui, |ui| { ui.panel_content(|ui| { - self.blueprint_tree_scroll_to_item = ctx - .focused_item - .as_ref() - .and_then(|item| self.handle_focused_item(ctx, viewport, ui, item)); + self.blueprint_tree_scroll_to_item = + ctx.focused_item.as_ref().and_then(|item| { + self.handle_focused_item(ctx, viewport_blueprint, ui, item) + }); list_item::list_item_scope(ui, "blueprint tree", |ui| { - self.root_container_ui(ctx, viewport, ui, &filter_matcher); + if let Some(root_container) = blueprint_tree_data.root_container { + self.root_container_ui(ctx, viewport_blueprint, ui, &root_container); + } }); let empty_space_response = @@ -145,7 +152,7 @@ impl BlueprintTree { // handle drag and drop interaction on empty space self.handle_empty_space_drag_and_drop_interaction( ctx, - viewport, + viewport_blueprint, ui, empty_space_response.rect, ); @@ -153,50 +160,6 @@ impl BlueprintTree { }); } - /// Check if the provided item should be scrolled to. - fn scroll_to_me_if_needed(&self, ui: &egui::Ui, item: &Item, response: &egui::Response) { - if Some(item) == self.blueprint_tree_scroll_to_item.as_ref() { - // Scroll only if the entity isn't already visible. This is important because that's what - // happens when double-clicking an entity _in the blueprint tree_. In such case, it would be - // annoying to induce a scroll motion. - if !ui.clip_rect().contains_rect(response.rect) { - response.scroll_to_me(Some(egui::Align::Center)); - } - } - } - - /// If a group or view has a total of this number of elements, show its subtree by default? - fn default_open_for_data_result(group: &DataResultNode) -> bool { - let num_children = group.children.len(); - 2 <= num_children && num_children <= 3 - } - - fn contents_ui( - &mut self, - ctx: &ViewerContext<'_>, - viewport: &ViewportBlueprint, - ui: &mut egui::Ui, - contents: &Contents, - parent_visible: bool, - filter_matcher: &filter_widget::FilterMatcher, - ) { - match contents { - Contents::Container(container_id) => { - self.container_ui( - ctx, - viewport, - ui, - container_id, - parent_visible, - filter_matcher, - ); - } - Contents::View(view_id) => { - self.view_ui(ctx, viewport, ui, view_id, parent_visible, filter_matcher); - } - }; - } - /// Display the root container. /// /// The root container is different from other containers in that it cannot be removed or dragged, and it cannot be @@ -204,42 +167,34 @@ impl BlueprintTree { fn root_container_ui( &mut self, ctx: &ViewerContext<'_>, - viewport: &ViewportBlueprint, + viewport_blueprint: &ViewportBlueprint, ui: &mut egui::Ui, - filter_matcher: &filter_widget::FilterMatcher, + container_data: &ContainerData, ) { - let container_id = viewport.root_container; - if !match_container(ctx, viewport, &container_id, filter_matcher) { - return; - } - - let Some(container_blueprint) = viewport.container(&container_id) else { - re_log::warn!("Failed to find root container {container_id} in ViewportBlueprint"); - return; - }; - - let item = Item::Container(container_id); - let container_name = container_blueprint.display_name_or_default(); + let item = Item::Container(container_data.id); let item_response = ui .list_item() .selected(ctx.selection().contains_item(&item)) .draggable(true) // allowed for consistency but results in an invalid drag - .drop_target_style(self.is_candidate_drop_parent_container(&container_id)) + .drop_target_style(self.is_candidate_drop_parent_container(&container_data.id)) .show_flat( ui, - list_item::LabelContent::new(format!("Viewport ({})", container_name.as_ref())) - .label_style(contents_name_style(&container_name)) - .with_icon(icon_for_container_kind(&container_blueprint.container_kind)), + list_item::LabelContent::new(format!( + "Viewport ({})", + container_data.name.as_ref() + )) + .label_style(contents_name_style(&container_data.name)) + .with_icon(icon_for_container_kind(&container_data.kind)), ); - for child in &container_blueprint.contents { - self.contents_ui(ctx, viewport, ui, child, true, filter_matcher); + for child in &container_data.children { + self.contents_ui(ctx, viewport_blueprint, ui, child, true); } context_menu_ui_for_item_with_context( ctx, - viewport, + viewport_blueprint, &item, // expand/collapse context menu actions need this information ItemContext::BlueprintTree { @@ -253,45 +208,49 @@ impl BlueprintTree { self.handle_root_container_drag_and_drop_interaction( ctx, - viewport, + viewport_blueprint, ui, - Contents::Container(container_id), + Contents::Container(container_data.id), &item_response, ); } + fn contents_ui( + &mut self, + ctx: &ViewerContext<'_>, + viewport_blueprint: &ViewportBlueprint, + ui: &mut egui::Ui, + contents_data: &ContentsData, + parent_visible: bool, + ) { + match contents_data { + ContentsData::Container(container_data) => { + self.container_ui(ctx, viewport_blueprint, ui, container_data, parent_visible); + } + ContentsData::View(view_data) => { + self.view_ui(ctx, viewport_blueprint, ui, view_data, parent_visible); + } + }; + } + fn container_ui( &mut self, ctx: &ViewerContext<'_>, viewport: &ViewportBlueprint, ui: &mut egui::Ui, - container_id: &ContainerId, + container_data: &ContainerData, parent_visible: bool, - filter_matcher: &filter_widget::FilterMatcher, ) { - if !match_container(ctx, viewport, container_id, filter_matcher) { - return; - } + let item = Item::Container(container_data.id); + let content = Contents::Container(container_data.id); - let item = Item::Container(*container_id); - let content = Contents::Container(*container_id); - - let Some(container_blueprint) = viewport.container(container_id) else { - re_log::warn_once!("Ignoring unknown container {container_id}"); - return; - }; - - let mut visible = container_blueprint.visible; + let mut visible = container_data.visible; let container_visible = visible && parent_visible; - let default_open = true; - - let container_name = container_blueprint.display_name_or_default(); - - let item_content = list_item::LabelContent::new(container_name.as_ref()) + let item_content = list_item::LabelContent::new(container_data.name.as_ref()) .subdued(!container_visible) - .label_style(contents_name_style(&container_name)) - .with_icon(icon_for_container_kind(&container_blueprint.container_kind)) + .label_style(contents_name_style(&container_data.name)) + .with_icon(icon_for_container_kind(&container_data.kind)) .with_buttons(|ui| { let vis_response = visibility_button_ui(ui, parent_visible, &mut visible); @@ -306,7 +265,7 @@ impl BlueprintTree { // Globally unique id - should only be one of these in view at one time. // We do this so that we can support "collapse/expand all" command. - let id = egui::Id::new(self.collapse_scope().container(*container_id)); + let id = egui::Id::new(self.collapse_scope().container(container_data.id)); let list_item::ShowCollapsingResponse { item_response: response, @@ -316,17 +275,20 @@ impl BlueprintTree { .list_item() .selected(ctx.selection().contains_item(&item)) .draggable(true) - .drop_target_style(self.is_candidate_drop_parent_container(container_id)) - .show_hierarchical_with_children(ui, id, default_open, item_content, |ui| { - for child in &container_blueprint.contents { - self.contents_ui(ctx, viewport, ui, child, container_visible, filter_matcher); - } - }); + .drop_target_style(self.is_candidate_drop_parent_container(&container_data.id)) + .show_hierarchical_with_children( + ui, + id, + container_data.default_open, + item_content, + |ui| { + for child in &container_data.children { + self.contents_ui(ctx, viewport, ui, child, container_visible); + } + }, + ); - let response = response.on_hover_text(format!( - "{:?} container", - container_blueprint.container_kind - )); + let response = response.on_hover_text(format!("{:?} container", container_data.kind)); context_menu_ui_for_item_with_context( ctx, @@ -357,43 +319,24 @@ impl BlueprintTree { fn view_ui( &mut self, ctx: &ViewerContext<'_>, - viewport: &ViewportBlueprint, + viewport_blueprint: &ViewportBlueprint, ui: &mut egui::Ui, - view_id: &ViewId, + view_data: &ViewData, container_visible: bool, - filter_matcher: &filter_widget::FilterMatcher, ) { - if !match_view(ctx, view_id, filter_matcher) { - return; - } - - let Some(view) = viewport.view(view_id) else { - re_log::warn_once!("Bug: asked to show a UI for a view that doesn't exist"); - return; - }; - debug_assert_eq!(view.id, *view_id); - - let query_result = ctx.lookup_query_result(view.id); - let result_tree = &query_result.tree; - - let mut visible = view.visible; + let mut visible = view_data.visible; let view_visible = visible && container_visible; - let item = Item::View(view.id); + let item = Item::View(view_data.id); - let root_node = result_tree.root_node(); - - // empty views should display as open by default to highlight the fact that they are empty - let default_open = self.filter_state.is_active() - || root_node.map_or(true, Self::default_open_for_data_result); + let class = ctx + .view_class_registry + .get_class_or_log_error(view_data.class_identifier); let is_item_hovered = ctx.selection_state().highlight_for_ui_element(&item) == HoverHighlight::Hovered; - let class = view.class(ctx.view_class_registry); - let view_name = view.display_name_or_default(); - - let item_content = list_item::LabelContent::new(view_name.as_ref()) - .label_style(contents_name_style(&view_name)) + let item_content = list_item::LabelContent::new(view_data.name.as_ref()) + .label_style(contents_name_style(&view_data.name)) .with_icon(class.icon()) .subdued(!view_visible) .with_buttons(|ui| { @@ -401,8 +344,8 @@ impl BlueprintTree { let response = remove_button_ui(ui, "Remove view from the viewport"); if response.clicked() { - viewport.mark_user_interaction(ctx); - viewport.remove_contents(Contents::View(*view_id)); + viewport_blueprint.mark_user_interaction(ctx); + viewport_blueprint.remove_contents(Contents::View(view_data.id)); } response | vis_response @@ -410,7 +353,7 @@ impl BlueprintTree { // Globally unique id - should only be one of these in view at one time. // We do this so that we can support "collapse/expand all" command. - let id = egui::Id::new(self.collapse_scope().view(*view_id)); + let id = egui::Id::new(self.collapse_scope().view(view_data.id)); let list_item::ShowCollapsingResponse { item_response: response, @@ -421,66 +364,25 @@ impl BlueprintTree { .selected(ctx.selection().contains_item(&item)) .draggable(true) .force_hovered(is_item_hovered) - .show_hierarchical_with_children(ui, id, default_open, item_content, |ui| { - // Always show the origin hierarchy first. - self.data_result_ui( - ctx, - viewport, - ui, - query_result, - &DataResultNodeOrPath::from_path_lookup(result_tree, &view.space_origin), - view, - view_visible, - false, - filter_matcher, - ); - - // Show 'projections' if there's any items that weren't part of the tree under origin but are directly included. - // The latter is important since `+ image/camera/**` necessarily has `image` and `image/camera` in the data result tree. - let mut projections = Vec::new(); - result_tree.visit(&mut |node| { - if node.data_result.entity_path.starts_with(&view.space_origin) { - false // If it's under the origin, we're not interested, stop recursing. - } else if node.data_result.tree_prefix_only { - true // Keep recursing until we find a projection. - } else { - // We found a projection, but we must check if it is ruled out by the - // filter. - if self.match_data_result( - query_result, - &DataResultNodeOrPath::DataResultNode(node), - view, - true, - filter_matcher, - ) { - projections.push(node); - } - - // No further recursion needed in this branch, everything below is included - // in the projection (or shouldn't be included if the projection has already - // been filtered out). - false - } - }); + .show_hierarchical_with_children(ui, id, view_data.default_open, item_content, |ui| { + if let Some(data_result_data) = &view_data.origin_tree { + self.data_result_ui( + ctx, + viewport_blueprint, + ui, + data_result_data, + view_visible, + ); + } - if !projections.is_empty() { + if !view_data.projection_trees.is_empty() { ui.list_item().interactive(false).show_flat( ui, list_item::LabelContent::new("Projections:").italics(true), ); - for projection in projections { - self.data_result_ui( - ctx, - viewport, - ui, - query_result, - &DataResultNodeOrPath::DataResultNode(projection), - view, - view_visible, - true, - filter_matcher, - ); + for projection in &view_data.projection_trees { + self.data_result_ui(ctx, viewport_blueprint, ui, projection, view_visible); } } }); @@ -488,12 +390,12 @@ impl BlueprintTree { let response = response.on_hover_text(format!("{} view", class.display_name())); if response.clicked() { - viewport.focus_tab(view.id); + viewport_blueprint.focus_tab(view_data.id); } context_menu_ui_for_item_with_context( ctx, - viewport, + viewport_blueprint, &item, // expand/collapse context menu actions need this information ItemContext::BlueprintTree { @@ -505,12 +407,12 @@ impl BlueprintTree { self.scroll_to_me_if_needed(ui, &item, &response); ctx.handle_select_hover_drag_interactions(&response, item, true); - let content = Contents::View(*view_id); + let content = Contents::View(view_data.id); - viewport.set_content_visibility(ctx, &content, visible); + viewport_blueprint.set_content_visibility(ctx, &content, visible); self.handle_drag_and_drop_interaction( ctx, - viewport, + viewport_blueprint, ui, content, &response, @@ -522,85 +424,87 @@ impl BlueprintTree { fn data_result_ui( &self, ctx: &ViewerContext<'_>, - viewport: &ViewportBlueprint, + viewport_blueprint: &ViewportBlueprint, ui: &mut egui::Ui, - query_result: &DataQueryResult, - node_or_path: &DataResultNodeOrPath<'_>, - view: &ViewBlueprint, + data_result_data: &DataResultData, view_visible: bool, - projection_mode: bool, - filter_matcher: &filter_widget::FilterMatcher, ) { - if !self.match_data_result( - query_result, - node_or_path, - view, - projection_mode, - filter_matcher, - ) { - return; - } + let item = Item::DataResult( + data_result_data.view_id, + data_result_data.entity_path.clone().into(), + ); - let entity_path = node_or_path.path(); - let display_origin_placeholder = projection_mode && entity_path == &view.space_origin; - if display_origin_placeholder { - if ui - .list_item() - .show_hierarchical( - ui, - list_item::LabelContent::new("$origin") - .subdued(true) - .italics(true) - .with_icon(&re_ui::icons::INTERNAL_LINK), - ) - .on_hover_text( - "This subtree corresponds to the View's origin, and is displayed above \ - the 'Projections' section. Click to select it.", - ) - .clicked() - { - ctx.selection_state().set_selection(Item::DataResult( - view.id, - InstancePath::entity_all(entity_path.clone()), + let item_content = match data_result_data.kind { + DataResultKind::EmptyOriginPlaceholder | DataResultKind::DataResult => { + let is_empty_origin_placeholder = matches!( + data_result_data.kind, + DataResultKind::EmptyOriginPlaceholder + ); + + let item_content = list_item::LabelContent::new(format_matching_text( + ctx.egui_ctx, + &data_result_data.label, + data_result_data.highlight_sections.iter().cloned(), + is_empty_origin_placeholder.then(|| ui.visuals().warn_fg_color), + )) + .with_icon(guess_instance_path_icon( + ctx, + &data_result_data.instance_path(), )); - } - return; - } - let data_result_node = node_or_path.data_result_node(); + if is_empty_origin_placeholder { + item_content.subdued(true) + } else { + item_content + .subdued(!view_visible || !data_result_data.visible) + .with_buttons(|ui: &mut egui::Ui| { + let mut visible_after = data_result_data.visible; + let vis_response = + visibility_button_ui(ui, view_visible, &mut visible_after); + if visible_after != data_result_data.visible { + data_result_data.update_visibility(ctx, visible_after); + } + + let response = remove_button_ui( + ui, + "Remove this entity and all its children from the view", + ); + if response.clicked() { + data_result_data + .remove_data_result_from_view(ctx, viewport_blueprint); + } - let item = Item::DataResult(view.id, entity_path.clone().into()); - let is_selected = ctx.selection().contains_item(&item); - let is_item_hovered = - ctx.selection_state().highlight_for_ui_element(&item) == HoverHighlight::Hovered; + response | vis_response + }) + } + } - let visible = data_result_node.is_some_and(|n| n.data_result.is_visible(ctx)); - let empty_origin = entity_path == &view.space_origin && data_result_node.is_none(); + DataResultKind::OriginProjectionPlaceholder => { + if ui + .list_item() + .show_hierarchical( + ui, + list_item::LabelContent::new("$origin") + .subdued(true) + .italics(true) + .with_icon(&re_ui::icons::INTERNAL_LINK), + ) + .on_hover_text( + "This subtree corresponds to the view's origin, and is displayed above \ + the 'Projections' section. Click to select it.", + ) + .clicked() + { + ctx.selection_state().set_selection(item); + } - let item_label = if entity_path.is_root() { - "/ (root)".to_owned() - } else { - entity_path - .iter() - .last() - .map_or("unknown".to_owned(), |e| e.ui_string()) - }; - let item_label = if ctx.recording().is_known_entity(entity_path) { - filter_matcher - .matches_formatted(ui.ctx(), &item_label) - .unwrap_or_else(|| item_label.into()) - } else { - ui.ctx().warning_text(item_label).into() + return; + } }; - let subdued = !view_visible || !visible; - - let mut item_content = list_item::LabelContent::new(item_label) - .with_icon(guess_instance_path_icon( - ctx, - &InstancePath::from(entity_path.clone()), - )) - .subdued(subdued); + let is_selected = ctx.selection().contains_item(&item); + let is_item_hovered = + ctx.selection_state().highlight_for_ui_element(&item) == HoverHighlight::Hovered; let list_item = ui .list_item() @@ -608,76 +512,28 @@ impl BlueprintTree { .selected(is_selected) .force_hovered(is_item_hovered); - // We force the origin to be displayed, even if it's fully empty, in which case it can be - // neither shown/hidden nor removed. - if !empty_origin { - item_content = item_content.with_buttons(|ui: &mut egui::Ui| { - let mut visible_after = visible; - let vis_response = visibility_button_ui(ui, view_visible, &mut visible_after); - if visible_after != visible { - if let Some(data_result_node) = data_result_node { - data_result_node - .data_result - .save_recursive_override_or_clear_if_redundant( - ctx, - &query_result.tree, - &Visible::from(visible_after), - ); - } - } - - let response = - remove_button_ui(ui, "Remove this entity and all its children from the view"); - if response.clicked() { - view.contents - .remove_subtree_and_matching_rules(ctx, entity_path.clone()); - } - - response | vis_response - }); - } - // If there's any children on the data result nodes, show them, otherwise we're good with this list item as is. - let has_children = data_result_node.is_some_and(|n| !n.children.is_empty()); - let response = if let (true, Some(node)) = (has_children, data_result_node) { - // Don't default open projections. - let default_open = self.filter_state.is_active() - || (entity_path.starts_with(&view.space_origin) - && Self::default_open_for_data_result(node)); - + let has_children = !data_result_data.children.is_empty(); //data_result_node.is_some_and(|n| !n.children.is_empty()); + let response = if has_children { // Globally unique id - should only be one of these in view at one time. // We do this so that we can support "collapse/expand all" command. - let id = egui::Id::new( - self.collapse_scope() - .data_result(view.id, entity_path.clone()), - ); + let id = egui::Id::new(self.collapse_scope().data_result( + data_result_data.view_id, + data_result_data.entity_path.clone(), + )); list_item - .show_hierarchical_with_children(ui, id, default_open, item_content, |ui| { - for child in node.children.iter().sorted_by_key(|c| { - query_result - .tree - .lookup_result(**c) - .map_or(&view.space_origin, |c| &c.entity_path) - }) { - let Some(child_node) = query_result.tree.lookup_node(*child) else { - debug_assert!(false, "DataResultNode {node:?} has an invalid child"); - continue; - }; - - self.data_result_ui( - ctx, - viewport, - ui, - query_result, - &DataResultNodeOrPath::DataResultNode(child_node), - view, - view_visible, - projection_mode, - filter_matcher, - ); - } - }) + .show_hierarchical_with_children( + ui, + id, + data_result_data.default_open, + item_content, + |ui| { + for child in &data_result_data.children { + self.data_result_ui(ctx, viewport_blueprint, ui, child, view_visible); + } + }, + ) .item_response } else { list_item.show_hierarchical(ui, item_content) @@ -691,11 +547,14 @@ impl BlueprintTree { ctx, &query, ctx.recording(), - entity_path, + &data_result_data.entity_path, include_subtree, ); - if empty_origin { + if matches!( + data_result_data.kind, + DataResultKind::EmptyOriginPlaceholder + ) { ui.label(ui.ctx().warning_text( "This view's query did not match any data under the space origin", )); @@ -704,7 +563,7 @@ impl BlueprintTree { context_menu_ui_for_item_with_context( ctx, - viewport, + viewport_blueprint, &item, // expand/collapse context menu actions need this information ItemContext::BlueprintTree { @@ -717,80 +576,16 @@ impl BlueprintTree { ctx.handle_select_hover_drag_interactions(&response, item, true); } - /// Should this data result (and its children) be displayed? - fn match_data_result( - &self, - query_result: &DataQueryResult, - node_or_path: &DataResultNodeOrPath<'_>, - view: &ViewBlueprint, - projection_mode: bool, - filter_matcher: &filter_widget::FilterMatcher, - ) -> bool { - let entity_path = node_or_path.path(); - let display_origin_placeholder = projection_mode && entity_path == &view.space_origin; - - if filter_matcher.matches_nothing() { - return false; - } - - // Filter is inactive or otherwise whitelisting everything. - if filter_matcher.matches_everything() { - return true; - } - - // We never display the origin placeholder if the filter is active, because if the - // `$origin` subtree matched something, it would be visible in the non-projected - // data-results. - if display_origin_placeholder && self.filter_state.is_active() { - return false; - } - - // Is the current path a match? - // - // This is subtle! If we are in projection mode, we check for all parts starting at the - // root for a match. However, if we are _not_ in projection mode, we skip checking the - // origin part (which is always the first part of the entity path in this case), because - // that part is not displayed and, as such, should not trigger a match. - if entity_path - .iter() - .skip( - if !projection_mode && entity_path.starts_with(&view.space_origin) { - view.space_origin.len() - } else { - 0 - }, - ) - .any(|entity_part| filter_matcher.matches(&entity_part.ui_string())) - { - return true; - } - - // Our subtree contains a match. - if let Some(node) = node_or_path.data_result_node() { - if query_result - .tree - .find_node_by(Some(node), |node| { - // If are in projection mode, we must reject anything that is the origin or - // its child. If there was a match there, then it would be displayed in the - // non-projected data results. - if projection_mode - && node.data_result.entity_path.starts_with(&view.space_origin) - { - return false; - } - - node.data_result - .entity_path - .last() - .is_some_and(|entity_part| filter_matcher.matches(&entity_part.ui_string())) - }) - .is_some() - { - return true; + /// Check if the provided item should be scrolled to. + fn scroll_to_me_if_needed(&self, ui: &egui::Ui, item: &Item, response: &egui::Response) { + if Some(item) == self.blueprint_tree_scroll_to_item.as_ref() { + // Scroll only if the entity isn't already visible. This is important because that's what + // happens when double-clicking an entity _in the blueprint tree_. In such case, it would be + // annoying to induce a scroll motion. + if !ui.clip_rect().contains_rect(response.rect) { + response.scroll_to_me(Some(egui::Align::Center)); } } - - false } // ---------------------------------------------------------------------------- @@ -1157,69 +952,6 @@ impl BlueprintTree { // ---------------------------------------------------------------------------- -fn match_container( - ctx: &ViewerContext<'_>, - viewport: &ViewportBlueprint, - container_id: &ContainerId, - filter_matcher: &filter_widget::FilterMatcher, -) -> bool { - if filter_matcher.matches_everything() { - return true; - } - - if filter_matcher.matches_nothing() { - return false; - } - - viewport - .find_contents_in_container_by( - &|content| { - // dont recurse infinitely - if content == &Contents::Container(*container_id) { - return false; - } - - match content { - Contents::Container(container_id) => { - match_container(ctx, viewport, container_id, filter_matcher) - } - Contents::View(view_id) => match_view(ctx, view_id, filter_matcher), - } - }, - container_id, - ) - .is_some() -} - -/// Does this view match the provided filter? -fn match_view( - ctx: &ViewerContext<'_>, - view_id: &ViewId, - filter_matcher: &filter_widget::FilterMatcher, -) -> bool { - if filter_matcher.matches_everything() { - return true; - } - - if filter_matcher.matches_nothing() { - return false; - }; - - let query_result = ctx.lookup_query_result(*view_id); - let result_tree = &query_result.tree; - - result_tree - .find_node_by(None, |node| { - node.data_result - .entity_path - .last() - .is_some_and(|entity_part| filter_matcher.matches(&entity_part.ui_string())) - }) - .is_some() -} - -// ---------------------------------------------------------------------------- - /// Add a button to trigger the addition of a new view or container. fn add_new_view_or_container_menu_button( ctx: &ViewerContext<'_>, diff --git a/crates/viewer/re_ui/src/filter_widget.rs b/crates/viewer/re_ui/src/filter_widget.rs index 092dca3c1f61..a79d20e68d4d 100644 --- a/crates/viewer/re_ui/src/filter_widget.rs +++ b/crates/viewer/re_ui/src/filter_widget.rs @@ -262,7 +262,7 @@ impl FilterMatcher { /// actual match. pub fn matches_formatted(&self, ctx: &egui::Context, text: &str) -> Option { self.find_matches(text) - .map(|match_iter| format_matching_text(ctx, text, match_iter)) + .map(|match_iter| format_matching_text(ctx, text, match_iter, None)) } } @@ -272,10 +272,13 @@ pub fn format_matching_text( ctx: &egui::Context, text: &str, match_iter: impl Iterator>, + text_color: Option, ) -> egui::WidgetText { let mut current = 0; let mut job = egui::text::LayoutJob::default(); + let color = text_color.unwrap_or(Color32::PLACEHOLDER); + for Range { start, end } in match_iter { if current < start { job.append( @@ -283,7 +286,7 @@ pub fn format_matching_text( 0.0, egui::TextFormat { font_id: egui::TextStyle::Body.resolve(&ctx.style()), - color: Color32::PLACEHOLDER, + color, ..Default::default() }, ); @@ -294,7 +297,7 @@ pub fn format_matching_text( 0.0, egui::TextFormat { font_id: egui::TextStyle::Body.resolve(&ctx.style()), - color: Color32::PLACEHOLDER, + color, background: ctx.style().visuals.selection.bg_fill, ..Default::default() }, @@ -309,7 +312,7 @@ pub fn format_matching_text( 0.0, egui::TextFormat { font_id: egui::TextStyle::Body.resolve(&ctx.style()), - color: Color32::PLACEHOLDER, + color, ..Default::default() }, ); From 62735738955068dc8bf8e48f17c308dbfb572291 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler Date: Thu, 23 Jan 2025 16:07:32 +0100 Subject: [PATCH 04/15] Updated test snapshot based on the new implementation fix test snapshot --- .../snapshots/blueprint_panel_filter_active_above_origin.png | 4 ++-- .../tests/snapshots/view_structure_test/no-query/empty.png | 4 ++-- .../view_structure_test/query-path/multiple_proj.png | 4 ++-- .../view_structure_test/query-path/non_root_origin.png | 4 ++-- .../view_structure_test/query-path/proj_with_placeholder.png | 4 ++-- .../snapshots/view_structure_test/query-path/single_proj.png | 4 ++-- .../view_structure_test/query-path/unknown_origin.png | 4 ++-- .../view_structure_test/query-t/proj_with_placeholder.png | 4 ++-- .../snapshots/view_structure_test/query-t/root_origin.png | 4 ++-- .../snapshots/view_structure_test/query-t/unknown_origin.png | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/blueprint_panel_filter_active_above_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/blueprint_panel_filter_active_above_origin.png index a7fa222be7b6..ccd83e0307ae 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/blueprint_panel_filter_active_above_origin.png +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/blueprint_panel_filter_active_above_origin.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2f6d2f7f5ee34fa4fc0609c55a3dca06cea2984d1d6a99569014e8801fcb07a0 -size 22280 +oid sha256:7357c66c618ecbdfbd1f3af3cdc6f684336e90926c99b3358b4964fd07b77090 +size 24034 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/empty.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/empty.png index c9e0993fa6c4..5b571fb638a0 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/empty.png +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/no-query/empty.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5d1510b277bbf65c8a611b8d40ba3cd3ac1f4210644e76e9a1bd6e967989a5f1 -size 15428 +oid sha256:deb78300c1479f2b096e8d8de36a1e6c966dc713b264cf62587e0691e56cf4ad +size 15302 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/multiple_proj.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/multiple_proj.png index 010be458fb8a..1ba890fb1537 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/multiple_proj.png +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/multiple_proj.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:35d2d48be2ec03f47a324eaebc80042554b13f49c47140bfeaa8857965e94b27 -size 20761 +oid sha256:28b601ca8a0080da7219f9765fedb28bc6429a0f4ca963bbb5ee161a080e84b1 +size 10203 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/non_root_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/non_root_origin.png index f478928a2829..1ba890fb1537 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/non_root_origin.png +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/non_root_origin.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:290e00ace697a77e8441ff8e5a6b0885e7e6edf59fccc6f858d8f9b93fec5d06 -size 15051 +oid sha256:28b601ca8a0080da7219f9765fedb28bc6429a0f4ca963bbb5ee161a080e84b1 +size 10203 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/proj_with_placeholder.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/proj_with_placeholder.png index 624ce7b62f76..c7c94cca8c4b 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/proj_with_placeholder.png +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/proj_with_placeholder.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dd2762035276d3aca3e99ab3de647f5208b1dc244b7de59c74b387962a6ba35a -size 19876 +oid sha256:27c98e696b61320f03b47a7f91a38e8cc0bd186dbc7661c0d2b36b4ea38f54b7 +size 21630 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/single_proj.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/single_proj.png index 6a50a73d88e6..1ba890fb1537 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/single_proj.png +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/single_proj.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:40bf039f0c7eeb948e93a3a56928b6d06b76980f0df11d1167643a4920c5fb22 -size 22484 +oid sha256:28b601ca8a0080da7219f9765fedb28bc6429a0f4ca963bbb5ee161a080e84b1 +size 10203 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/unknown_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/unknown_origin.png index 1ba890fb1537..90ca003c2647 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/unknown_origin.png +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-path/unknown_origin.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28b601ca8a0080da7219f9765fedb28bc6429a0f4ca963bbb5ee161a080e84b1 -size 10203 +oid sha256:79b5e3b2a8565ec802d43ead2f95ad46dfae013b643399860dd0a2ab63708a52 +size 16647 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/proj_with_placeholder.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/proj_with_placeholder.png index 978cb4c08beb..92fe911ee3df 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/proj_with_placeholder.png +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/proj_with_placeholder.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:67aa1073686f2f03bcd84a1ba1a0005256ae403d10d92421cd84ac654086b222 -size 26866 +oid sha256:5735ced6fd972b257cb7a3d9c65fc81495fa5c01c76af4df85c79ced033d26c9 +size 28591 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/root_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/root_origin.png index 31084b881928..62bd11e2412a 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/root_origin.png +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/root_origin.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:21888ed224e75ec7e5e36d889f4944292c7fb16edad1dc1cc25821f29ab1dae3 -size 23599 +oid sha256:d51d3c378e5ef7a31dee7a05a7192b3c2a4c301f3976fcff7a896a73dcb4442f +size 23569 diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/unknown_origin.png b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/unknown_origin.png index 4a05b6f46985..d3be09a32d34 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/unknown_origin.png +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test/query-t/unknown_origin.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5d221abb19b3e530beb74c287780f536e490c59dcade30b30f06a54dbf0c10e -size 9650 +oid sha256:be54ffe77e68e2e896807f5afd08bbfe75d51cffaefdaa1add891b8bcf1e56cb +size 16015 From b1292bc188fce887a63a089855b44c2e3e11688c Mon Sep 17 00:00:00 2001 From: Antoine Beyeler Date: Thu, 23 Jan 2025 20:22:29 +0100 Subject: [PATCH 05/15] Add insta tests on `BlueprintTreeData` --- Cargo.lock | 57 +++++++ crates/viewer/re_blueprint_tree/Cargo.toml | 16 +- crates/viewer/re_blueprint_tree/src/data.rs | 6 + crates/viewer/re_blueprint_tree/src/lib.rs | 5 + .../view_structure_test__no-query-empty.snap | 32 ++++ ...tructure_test__no-query-multiple_proj.snap | 71 +++++++++ ...ucture_test__no-query-non_root_origin.snap | 83 ++++++++++ ..._test__no-query-proj_with_placeholder.snap | 134 ++++++++++++++++ ..._structure_test__no-query-root_origin.snap | 123 +++++++++++++++ ..._structure_test__no-query-single_proj.snap | 94 +++++++++++ ...ructure_test__no-query-unknown_origin.snap | 34 ++++ ...view_structure_test__query-path-empty.snap | 5 + ...ucture_test__query-path-multiple_proj.snap | 5 + ...ture_test__query-path-non_root_origin.snap | 5 + ...est__query-path-proj_with_placeholder.snap | 55 +++++++ ...tructure_test__query-path-root_origin.snap | 104 ++++++++++++ ...tructure_test__query-path-single_proj.snap | 5 + ...cture_test__query-path-unknown_origin.snap | 36 +++++ .../view_structure_test__query-t-empty.snap | 5 + ...structure_test__query-t-multiple_proj.snap | 64 ++++++++ ...ructure_test__query-t-non_root_origin.snap | 91 +++++++++++ ...e_test__query-t-proj_with_placeholder.snap | 148 ++++++++++++++++++ ...w_structure_test__query-t-root_origin.snap | 135 ++++++++++++++++ ...w_structure_test__query-t-single_proj.snap | 91 +++++++++++ ...tructure_test__query-t-unknown_origin.snap | 36 +++++ ...view_structure_test__query-void-empty.snap | 5 + ...ucture_test__query-void-multiple_proj.snap | 50 ++++++ ...ture_test__query-void-non_root_origin.snap | 61 ++++++++ ...est__query-void-proj_with_placeholder.snap | 61 ++++++++ ...tructure_test__query-void-root_origin.snap | 80 ++++++++++ ...tructure_test__query-void-single_proj.snap | 61 ++++++++ ...cture_test__query-void-unknown_origin.snap | 5 + .../tests/view_structure_test.rs | 107 +++++++++---- .../viewer/re_viewer_context/src/contents.rs | 1 + .../re_viewer_context/src/test_context.rs | 42 ++++- .../viewer/re_viewport_blueprint/src/view.rs | 17 +- 36 files changed, 1890 insertions(+), 40 deletions(-) create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-empty.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-multiple_proj.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-non_root_origin.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-proj_with_placeholder.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-root_origin.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-single_proj.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-unknown_origin.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-empty.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-multiple_proj.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-non_root_origin.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-proj_with_placeholder.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-root_origin.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-single_proj.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-unknown_origin.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-empty.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-multiple_proj.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-non_root_origin.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-proj_with_placeholder.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-root_origin.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-single_proj.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-unknown_origin.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-empty.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-multiple_proj.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-non_root_origin.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-proj_with_placeholder.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-root_origin.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-single_proj.snap create mode 100644 crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-unknown_origin.snap diff --git a/Cargo.lock b/Cargo.lock index dd30a966c1f7..d0b1b67580eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3635,6 +3635,9 @@ dependencies = [ "console", "lazy_static", "linked-hash-map", + "pest", + "pest_derive", + "serde", "similar", ] @@ -4940,6 +4943,51 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pest" +version = "2.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" +dependencies = [ + "memchr", + "thiserror 2.0.7", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "pest_meta" +version = "2.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + [[package]] name = "petgraph" version = "0.6.5" @@ -5638,7 +5686,9 @@ dependencies = [ "egui", "egui_kittest", "egui_tiles", + "insta", "itertools 0.13.0", + "re_blueprint_tree", "re_chunk_store", "re_context_menu", "re_data_ui", @@ -5651,6 +5701,7 @@ dependencies = [ "re_view_spatial", "re_viewer_context", "re_viewport_blueprint", + "serde", "smallvec", ] @@ -9212,6 +9263,12 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + [[package]] name = "uds_windows" version = "1.1.0" diff --git a/crates/viewer/re_blueprint_tree/Cargo.toml b/crates/viewer/re_blueprint_tree/Cargo.toml index 4d6327fa1bde..f52ae4b1fb89 100644 --- a/crates/viewer/re_blueprint_tree/Cargo.toml +++ b/crates/viewer/re_blueprint_tree/Cargo.toml @@ -18,6 +18,11 @@ workspace = true [package.metadata.docs.rs] all-features = true +[features] +default = [] +testing = ["dep:serde"] + + [dependencies] re_context_menu.workspace = true re_data_ui.workspace = true @@ -33,13 +38,20 @@ re_viewport_blueprint.workspace = true egui.workspace = true egui_tiles.workspace = true itertools.workspace = true +serde = { workspace = true, optional = true } smallvec.workspace = true [dev-dependencies] -re_viewer_context = { workspace = true, features = ["testing"] } -re_viewport_blueprint = { workspace = true, features = ["testing"] } +# Trick to reliably auto-enable the testing feature when running tests +# see: https://github.com/rust-lang/cargo/issues/2911#issuecomment-1483256987 +re_blueprint_tree = { path = ".", default-features = false, features = ["testing"] } + re_chunk_store.workspace = true re_view_spatial.workspace = true +re_viewer_context = { workspace = true, features = ["testing"] } +re_viewport_blueprint = { workspace = true, features = ["testing"] } egui_kittest.workspace = true +insta = { workspace = true, features = ["redactions", "yaml"] } + diff --git a/crates/viewer/re_blueprint_tree/src/data.rs b/crates/viewer/re_blueprint_tree/src/data.rs index 09699d1a92e6..5438ef91f85b 100644 --- a/crates/viewer/re_blueprint_tree/src/data.rs +++ b/crates/viewer/re_blueprint_tree/src/data.rs @@ -25,6 +25,7 @@ use re_viewport_blueprint::{ContainerBlueprint, ViewBlueprint, ViewportBlueprint use crate::data_result_node_or_path::DataResultNodeOrPath; #[derive(Debug, Default)] +#[cfg_attr(feature = "testing", derive(serde::Serialize, serde::Deserialize))] pub struct BlueprintTreeData { pub root_container: Option, } @@ -55,12 +56,14 @@ impl BlueprintTreeData { // --- #[derive(Debug)] +#[cfg_attr(feature = "testing", derive(serde::Serialize, serde::Deserialize))] pub enum ContentsData { Container(ContainerData), View(ViewData), } #[derive(Debug)] +#[cfg_attr(feature = "testing", derive(serde::Serialize, serde::Deserialize))] pub struct ContainerData { pub id: ContainerId, pub name: ContentsName, @@ -129,6 +132,7 @@ impl ContainerData { // --- #[derive(Debug)] +#[cfg_attr(feature = "testing", derive(serde::Serialize, serde::Deserialize))] pub struct ViewData { pub id: ViewId, @@ -250,6 +254,7 @@ impl ViewData { /// The kind of thing we may be displaying in the tree #[derive(Debug)] +#[cfg_attr(feature = "testing", derive(serde::Serialize, serde::Deserialize))] pub enum DataResultKind { EmptyOriginPlaceholder, @@ -259,6 +264,7 @@ pub enum DataResultKind { } #[derive(Debug)] +#[cfg_attr(feature = "testing", derive(serde::Serialize, serde::Deserialize))] pub struct DataResultData { pub kind: DataResultKind, pub entity_path: EntityPath, diff --git a/crates/viewer/re_blueprint_tree/src/lib.rs b/crates/viewer/re_blueprint_tree/src/lib.rs index 7163bddc5aae..39cb4b301d8a 100644 --- a/crates/viewer/re_blueprint_tree/src/lib.rs +++ b/crates/viewer/re_blueprint_tree/src/lib.rs @@ -1,6 +1,11 @@ //! This crate implements the UI for the blueprint tree in the left panel. mod blueprint_tree; + +#[cfg(feature = "testing")] +pub mod data; + +#[cfg(not(feature = "testing"))] pub(crate) mod data; mod data_result_node_or_path; diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-empty.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-empty.snap new file mode 100644 index 000000000000..2feaee91c8e0 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-empty.snap @@ -0,0 +1,32 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: / + visible: true + default_open: false + origin_tree: + kind: EmptyOriginPlaceholder + entity_path: [] + visible: false + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: / (root) + highlight_sections: [] + default_open: false + children: [] + projection_trees: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-multiple_proj.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-multiple_proj.snap new file mode 100644 index 000000000000..1381aa8dd448 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-multiple_proj.snap @@ -0,0 +1,71 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: center/way + visible: true + default_open: false + origin_tree: + kind: DataResult + entity_path: + - center + - way + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: way + highlight_sections: [] + default_open: false + children: [] + projection_trees: + - kind: DataResult + entity_path: + - path + - to + - right + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: right + highlight_sections: [] + default_open: false + children: [] + - kind: DataResult + entity_path: + - path + - to + - the + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: the + highlight_sections: [] + default_open: false + children: + - kind: DataResult + entity_path: + - path + - to + - the + - void + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: void + highlight_sections: [] + default_open: false + children: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-non_root_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-non_root_origin.snap new file mode 100644 index 000000000000..1c34f08bb8dd --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-non_root_origin.snap @@ -0,0 +1,83 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: path/to + visible: true + default_open: true + origin_tree: + kind: DataResult + entity_path: + - path + - to + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: to + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - left + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: left + highlight_sections: [] + default_open: false + children: [] + - kind: DataResult + entity_path: + - path + - to + - right + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: right + highlight_sections: [] + default_open: false + children: [] + - kind: DataResult + entity_path: + - path + - to + - the + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: the + highlight_sections: [] + default_open: false + children: + - kind: DataResult + entity_path: + - path + - to + - the + - void + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: void + highlight_sections: [] + default_open: false + children: [] + projection_trees: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-proj_with_placeholder.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-proj_with_placeholder.snap new file mode 100644 index 000000000000..b88695c0da9c --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-proj_with_placeholder.snap @@ -0,0 +1,134 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: path/to + visible: true + default_open: true + origin_tree: + kind: DataResult + entity_path: + - path + - to + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: to + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - left + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: left + highlight_sections: [] + default_open: false + children: [] + - kind: DataResult + entity_path: + - path + - to + - right + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: right + highlight_sections: [] + default_open: false + children: [] + - kind: DataResult + entity_path: + - path + - to + - the + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: the + highlight_sections: [] + default_open: false + children: + - kind: DataResult + entity_path: + - path + - to + - the + - void + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: void + highlight_sections: [] + default_open: false + children: [] + projection_trees: + - kind: DataResult + entity_path: [] + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: / (root) + highlight_sections: [] + default_open: false + children: + - kind: DataResult + entity_path: + - center + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: center + highlight_sections: [] + default_open: false + children: + - kind: DataResult + entity_path: + - center + - way + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: way + highlight_sections: [] + default_open: false + children: [] + - kind: DataResult + entity_path: + - path + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: path + highlight_sections: [] + default_open: false + children: + - kind: OriginProjectionPlaceholder + entity_path: + - path + - to + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: to + highlight_sections: [] + default_open: false + children: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-root_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-root_origin.snap new file mode 100644 index 000000000000..f9343e6d008b --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-root_origin.snap @@ -0,0 +1,123 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: / + visible: true + default_open: true + origin_tree: + kind: DataResult + entity_path: [] + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: / (root) + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - center + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: center + highlight_sections: [] + default_open: false + children: + - kind: DataResult + entity_path: + - center + - way + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: way + highlight_sections: [] + default_open: false + children: [] + - kind: DataResult + entity_path: + - path + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: path + highlight_sections: [] + default_open: false + children: + - kind: DataResult + entity_path: + - path + - to + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: to + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - left + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: left + highlight_sections: [] + default_open: false + children: [] + - kind: DataResult + entity_path: + - path + - to + - right + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: right + highlight_sections: [] + default_open: false + children: [] + - kind: DataResult + entity_path: + - path + - to + - the + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: the + highlight_sections: [] + default_open: false + children: + - kind: DataResult + entity_path: + - path + - to + - the + - void + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: void + highlight_sections: [] + default_open: false + children: [] + projection_trees: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-single_proj.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-single_proj.snap new file mode 100644 index 000000000000..ce683663ce9a --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-single_proj.snap @@ -0,0 +1,94 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: center/way + visible: true + default_open: false + origin_tree: + kind: DataResult + entity_path: + - center + - way + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: way + highlight_sections: [] + default_open: false + children: [] + projection_trees: + - kind: DataResult + entity_path: + - path + - to + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: to + highlight_sections: [] + default_open: false + children: + - kind: DataResult + entity_path: + - path + - to + - left + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: left + highlight_sections: [] + default_open: false + children: [] + - kind: DataResult + entity_path: + - path + - to + - right + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: right + highlight_sections: [] + default_open: false + children: [] + - kind: DataResult + entity_path: + - path + - to + - the + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: the + highlight_sections: [] + default_open: false + children: + - kind: DataResult + entity_path: + - path + - to + - the + - void + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: void + highlight_sections: [] + default_open: false + children: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-unknown_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-unknown_origin.snap new file mode 100644 index 000000000000..0c48dcf8b8db --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-unknown_origin.snap @@ -0,0 +1,34 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: wrong/path + visible: true + default_open: false + origin_tree: + kind: EmptyOriginPlaceholder + entity_path: + - wrong + - path + visible: false + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: path + highlight_sections: [] + default_open: false + children: [] + projection_trees: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-empty.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-empty.snap new file mode 100644 index 000000000000..6007f31692d5 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-empty.snap @@ -0,0 +1,5 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: ~ diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-multiple_proj.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-multiple_proj.snap new file mode 100644 index 000000000000..6007f31692d5 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-multiple_proj.snap @@ -0,0 +1,5 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: ~ diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-non_root_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-non_root_origin.snap new file mode 100644 index 000000000000..6007f31692d5 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-non_root_origin.snap @@ -0,0 +1,5 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: ~ diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-proj_with_placeholder.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-proj_with_placeholder.snap new file mode 100644 index 000000000000..c44ad29efbf7 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-proj_with_placeholder.snap @@ -0,0 +1,55 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: path/to + visible: true + default_open: true + origin_tree: ~ + projection_trees: + - kind: DataResult + entity_path: [] + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: / (root) + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: path + highlight_sections: + - start: 0 + end: 4 + default_open: true + children: + - kind: OriginProjectionPlaceholder + entity_path: + - path + - to + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: to + highlight_sections: [] + default_open: true + children: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-root_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-root_origin.snap new file mode 100644 index 000000000000..ddacdc45341b --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-root_origin.snap @@ -0,0 +1,104 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: / + visible: true + default_open: true + origin_tree: + kind: DataResult + entity_path: [] + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: / (root) + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: path + highlight_sections: + - start: 0 + end: 4 + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: to + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - left + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: left + highlight_sections: [] + default_open: true + children: [] + - kind: DataResult + entity_path: + - path + - to + - right + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: right + highlight_sections: [] + default_open: true + children: [] + - kind: DataResult + entity_path: + - path + - to + - the + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: the + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - the + - void + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: void + highlight_sections: [] + default_open: true + children: [] + projection_trees: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-single_proj.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-single_proj.snap new file mode 100644 index 000000000000..6007f31692d5 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-single_proj.snap @@ -0,0 +1,5 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: ~ diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-unknown_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-unknown_origin.snap new file mode 100644 index 000000000000..a51aa4a4aaa1 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-unknown_origin.snap @@ -0,0 +1,36 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: wrong/path + visible: true + default_open: true + origin_tree: + kind: EmptyOriginPlaceholder + entity_path: + - wrong + - path + visible: false + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: path + highlight_sections: + - start: 0 + end: 4 + default_open: false + children: [] + projection_trees: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-empty.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-empty.snap new file mode 100644 index 000000000000..6007f31692d5 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-empty.snap @@ -0,0 +1,5 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: ~ diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-multiple_proj.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-multiple_proj.snap new file mode 100644 index 000000000000..51ab5d9ab110 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-multiple_proj.snap @@ -0,0 +1,64 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: center/way + visible: true + default_open: true + origin_tree: ~ + projection_trees: + - kind: DataResult + entity_path: + - path + - to + - right + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: right + highlight_sections: + - start: 4 + end: 5 + default_open: true + children: [] + - kind: DataResult + entity_path: + - path + - to + - the + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: the + highlight_sections: + - start: 0 + end: 1 + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - the + - void + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: void + highlight_sections: [] + default_open: true + children: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-non_root_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-non_root_origin.snap new file mode 100644 index 000000000000..a6476d68cb0e --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-non_root_origin.snap @@ -0,0 +1,91 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: path/to + visible: true + default_open: true + origin_tree: + kind: DataResult + entity_path: + - path + - to + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: to + highlight_sections: + - start: 0 + end: 1 + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - left + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: left + highlight_sections: + - start: 3 + end: 4 + default_open: true + children: [] + - kind: DataResult + entity_path: + - path + - to + - right + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: right + highlight_sections: + - start: 4 + end: 5 + default_open: true + children: [] + - kind: DataResult + entity_path: + - path + - to + - the + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: the + highlight_sections: + - start: 0 + end: 1 + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - the + - void + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: void + highlight_sections: [] + default_open: true + children: [] + projection_trees: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-proj_with_placeholder.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-proj_with_placeholder.snap new file mode 100644 index 000000000000..dbf1a33d5f1b --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-proj_with_placeholder.snap @@ -0,0 +1,148 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: path/to + visible: true + default_open: true + origin_tree: + kind: DataResult + entity_path: + - path + - to + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: to + highlight_sections: + - start: 0 + end: 1 + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - left + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: left + highlight_sections: + - start: 3 + end: 4 + default_open: true + children: [] + - kind: DataResult + entity_path: + - path + - to + - right + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: right + highlight_sections: + - start: 4 + end: 5 + default_open: true + children: [] + - kind: DataResult + entity_path: + - path + - to + - the + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: the + highlight_sections: + - start: 0 + end: 1 + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - the + - void + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: void + highlight_sections: [] + default_open: true + children: [] + projection_trees: + - kind: DataResult + entity_path: [] + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: / (root) + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - center + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: center + highlight_sections: + - start: 3 + end: 4 + default_open: true + children: + - kind: DataResult + entity_path: + - center + - way + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: way + highlight_sections: [] + default_open: true + children: [] + - kind: DataResult + entity_path: + - path + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: path + highlight_sections: + - start: 2 + end: 3 + default_open: true + children: + - kind: OriginProjectionPlaceholder + entity_path: + - path + - to + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: to + highlight_sections: + - start: 0 + end: 1 + default_open: true + children: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-root_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-root_origin.snap new file mode 100644 index 000000000000..93868b845c45 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-root_origin.snap @@ -0,0 +1,135 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: / + visible: true + default_open: true + origin_tree: + kind: DataResult + entity_path: [] + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: / (root) + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - center + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: center + highlight_sections: + - start: 3 + end: 4 + default_open: true + children: + - kind: DataResult + entity_path: + - center + - way + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: way + highlight_sections: [] + default_open: true + children: [] + - kind: DataResult + entity_path: + - path + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: path + highlight_sections: + - start: 2 + end: 3 + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: to + highlight_sections: + - start: 0 + end: 1 + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - left + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: left + highlight_sections: + - start: 3 + end: 4 + default_open: true + children: [] + - kind: DataResult + entity_path: + - path + - to + - right + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: right + highlight_sections: + - start: 4 + end: 5 + default_open: true + children: [] + - kind: DataResult + entity_path: + - path + - to + - the + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: the + highlight_sections: + - start: 0 + end: 1 + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - the + - void + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: void + highlight_sections: [] + default_open: true + children: [] + projection_trees: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-single_proj.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-single_proj.snap new file mode 100644 index 000000000000..2e7f7e65577f --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-single_proj.snap @@ -0,0 +1,91 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: center/way + visible: true + default_open: true + origin_tree: ~ + projection_trees: + - kind: DataResult + entity_path: + - path + - to + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: to + highlight_sections: + - start: 0 + end: 1 + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - left + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: left + highlight_sections: + - start: 3 + end: 4 + default_open: true + children: [] + - kind: DataResult + entity_path: + - path + - to + - right + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: right + highlight_sections: + - start: 4 + end: 5 + default_open: true + children: [] + - kind: DataResult + entity_path: + - path + - to + - the + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: the + highlight_sections: + - start: 0 + end: 1 + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - the + - void + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: void + highlight_sections: [] + default_open: true + children: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-unknown_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-unknown_origin.snap new file mode 100644 index 000000000000..02f9a114f0d0 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-unknown_origin.snap @@ -0,0 +1,36 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: wrong/path + visible: true + default_open: true + origin_tree: + kind: EmptyOriginPlaceholder + entity_path: + - wrong + - path + visible: false + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: path + highlight_sections: + - start: 2 + end: 3 + default_open: false + children: [] + projection_trees: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-empty.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-empty.snap new file mode 100644 index 000000000000..6007f31692d5 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-empty.snap @@ -0,0 +1,5 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: ~ diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-multiple_proj.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-multiple_proj.snap new file mode 100644 index 000000000000..0ee5c05a2c6f --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-multiple_proj.snap @@ -0,0 +1,50 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: center/way + visible: true + default_open: true + origin_tree: ~ + projection_trees: + - kind: DataResult + entity_path: + - path + - to + - the + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: the + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - the + - void + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: void + highlight_sections: + - start: 0 + end: 4 + default_open: true + children: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-non_root_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-non_root_origin.snap new file mode 100644 index 000000000000..289f2abdf691 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-non_root_origin.snap @@ -0,0 +1,61 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: path/to + visible: true + default_open: true + origin_tree: + kind: DataResult + entity_path: + - path + - to + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: to + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - the + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: the + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - the + - void + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: void + highlight_sections: + - start: 0 + end: 4 + default_open: true + children: [] + projection_trees: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-proj_with_placeholder.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-proj_with_placeholder.snap new file mode 100644 index 000000000000..289f2abdf691 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-proj_with_placeholder.snap @@ -0,0 +1,61 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: path/to + visible: true + default_open: true + origin_tree: + kind: DataResult + entity_path: + - path + - to + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: to + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - the + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: the + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - the + - void + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: void + highlight_sections: + - start: 0 + end: 4 + default_open: true + children: [] + projection_trees: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-root_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-root_origin.snap new file mode 100644 index 000000000000..40b426d93b85 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-root_origin.snap @@ -0,0 +1,80 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: / + visible: true + default_open: true + origin_tree: + kind: DataResult + entity_path: [] + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: / (root) + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: path + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: to + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - the + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: the + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - the + - void + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: void + highlight_sections: + - start: 0 + end: 4 + default_open: true + children: [] + projection_trees: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-single_proj.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-single_proj.snap new file mode 100644 index 000000000000..1843f67695e4 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-single_proj.snap @@ -0,0 +1,61 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: + id: + id: "" + name: + Placeholder: Grid + kind: Grid + visible: true + default_open: true + children: + - View: + id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + class_identifier: 3D + name: + Placeholder: center/way + visible: true + default_open: true + origin_tree: ~ + projection_trees: + - kind: DataResult + entity_path: + - path + - to + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: to + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - the + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: the + highlight_sections: [] + default_open: true + children: + - kind: DataResult + entity_path: + - path + - to + - the + - void + visible: true + view_id: + id: 0864e1b8-cec4-1b82-5b17-b9d628b8f4fe + label: void + highlight_sections: + - start: 0 + end: 4 + default_open: true + children: [] diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-unknown_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-unknown_origin.snap new file mode 100644 index 000000000000..6007f31692d5 --- /dev/null +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-unknown_origin.snap @@ -0,0 +1,5 @@ +--- +source: crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +expression: blueprint_tree_data +--- +root_container: ~ diff --git a/crates/viewer/re_blueprint_tree/tests/view_structure_test.rs b/crates/viewer/re_blueprint_tree/tests/view_structure_test.rs index dd1e3e961da4..247fd0f6ba10 100644 --- a/crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +++ b/crates/viewer/re_blueprint_tree/tests/view_structure_test.rs @@ -4,16 +4,21 @@ use egui::Vec2; use egui_kittest::{SnapshotError, SnapshotOptions}; use itertools::Itertools; + +use re_blueprint_tree::data::BlueprintTreeData; use re_blueprint_tree::BlueprintTree; use re_chunk_store::external::re_chunk::ChunkBuilder; use re_chunk_store::RowId; use re_log_types::{build_frame_nr, EntityPath}; use re_types::archetypes::Points3D; +use re_ui::filter_widget::FilterState; use re_viewer_context::test_context::TestContext; -use re_viewer_context::{RecommendedView, ViewClass}; +use re_viewer_context::{RecommendedView, ViewClass, ViewId}; use re_viewport_blueprint::test_context_ext::TestContextExt; use re_viewport_blueprint::{ViewBlueprint, ViewportBlueprint}; +const VIEW_ID: &str = "this-is-a-view-id"; + #[derive(Debug, Clone, Copy)] enum RecordingKind { /// No entities are logged. @@ -81,12 +86,16 @@ fn base_test_cases() -> impl Iterator { .into_iter() } -fn test_context(kind: RecordingKind) -> TestContext { +fn filter_queries() -> impl Iterator> { + [None, Some("t"), Some("void"), Some("path")].into_iter() +} + +fn test_context(test_case: &TestCase) -> TestContext { let mut test_context = TestContext::default(); test_context.register_view_class::(); - match kind { + match test_case.recording_kind { RecordingKind::Emtpy => {} RecordingKind::Regular => { test_context.log_entity("/path/to/left".into(), add_point_to_chunk_builder); @@ -96,6 +105,22 @@ fn test_context(kind: RecordingKind) -> TestContext { } } + test_context.setup_viewport_blueprint(|_, blueprint| { + let view = ViewBlueprint::new_with_id( + re_view_spatial::SpatialView3D::identifier(), + RecommendedView { + origin: test_case.origin.clone(), + query_filter: test_case + .entity_filter + .try_into() + .expect("invalid entity filter"), + }, + ViewId::hashed_from_str(VIEW_ID), + ); + + blueprint.add_views(std::iter::once(view), None, None); + }); + test_context } @@ -108,12 +133,11 @@ fn add_point_to_chunk_builder(builder: ChunkBuilder) -> ChunkBuilder { } #[test] -fn run_all_test_cases() { - let errors = [None, Some("t"), Some("void"), Some("path")] - .into_iter() +fn test_all_snapshot_test_cases() { + let errors = filter_queries() .flat_map(|filter_query| { base_test_cases() - .map(move |test_case| (filter_query, run_test_case(test_case, filter_query))) + .map(move |test_case| (filter_query, run_test_case(&test_case, filter_query))) }) .filter_map(|(filter_query, result)| result.err().map(|err| (filter_query, err))) .collect_vec(); @@ -125,29 +149,9 @@ fn run_all_test_cases() { assert!(errors.is_empty(), "Some test cases failed"); } -fn run_test_case(test_case: TestCase, filter_query: Option<&str>) -> Result<(), SnapshotError> { - let mut test_context = test_context(test_case.recording_kind); - - let view_id = test_context.setup_viewport_blueprint(|_, blueprint| { - let view = ViewBlueprint::new( - re_view_spatial::SpatialView3D::identifier(), - RecommendedView { - origin: test_case.origin, - query_filter: test_case - .entity_filter - .try_into() - .expect("invalid entity filter"), - }, - ); - - let view_id = view.id; - blueprint.add_views(std::iter::once(view), None, None); - - // TODO(ab): add containers in the hierarchy (requires work on the container API, - // currently very cumbersome to use for testing purposes). - - view_id - }); +fn run_test_case(test_case: &TestCase, filter_query: Option<&str>) -> Result<(), SnapshotError> { + let mut test_context = test_context(test_case); + let view_id = ViewId::hashed_from_str(VIEW_ID); let mut blueprint_tree = BlueprintTree::default(); @@ -198,3 +202,46 @@ fn run_test_case(test_case: TestCase, filter_query: Option<&str>) -> Result<(), )); harness.try_snapshot_options(test_case.name, &options) } + +// --- + +#[test] +fn test_all_insta_test_cases() { + for test_case in base_test_cases() { + for filter_query in filter_queries() { + let test_context = test_context(&test_case); + + let blueprint_tree_data = + test_context.run_once_in_egui_central_panel(|viewer_ctx, _| { + let blueprint = ViewportBlueprint::try_from_db( + viewer_ctx.store_context.blueprint, + viewer_ctx.blueprint_query, + ); + + let mut filter_state = FilterState::default(); + + if let Some(filter_query) = filter_query { + filter_state.activate(filter_query); + } + + BlueprintTreeData::from_blueprint_and_filter( + viewer_ctx, + &blueprint, + &filter_state.filter(), + ) + }); + + let snapshot_name = format!( + "{}-{}", + filter_query + .map(|query| format!("query-{query}")) + .unwrap_or("no-query".to_owned()), + test_case.name + ); + + insta::assert_yaml_snapshot!(snapshot_name, blueprint_tree_data, { + ".root_container.id.id" => "" + }); + } + } +} diff --git a/crates/viewer/re_viewer_context/src/contents.rs b/crates/viewer/re_viewer_context/src/contents.rs index 558fbe8ad941..2290c5c44bd4 100644 --- a/crates/viewer/re_viewer_context/src/contents.rs +++ b/crates/viewer/re_viewer_context/src/contents.rs @@ -101,6 +101,7 @@ impl From for Contents { /// The name of a [`Contents`]. #[derive(Clone, Debug)] +#[cfg_attr(feature = "testing", derive(serde::Serialize, serde::Deserialize))] pub enum ContentsName { /// This [`Contents`] has been given a name by the user. Named(String), diff --git a/crates/viewer/re_viewer_context/src/test_context.rs b/crates/viewer/re_viewer_context/src/test_context.rs index 21e1ac379b1d..d00d5ef41eff 100644 --- a/crates/viewer/re_viewer_context/src/test_context.rs +++ b/crates/viewer/re_viewer_context/src/test_context.rs @@ -305,8 +305,9 @@ impl TestContext { /// Notes: /// - Uses [`egui::__run_test_ctx`]. /// - There is a possibility that the closure will be called more than once, see - /// [`egui::Context::run`]. - //TODO(ab): replace this with a kittest-based helper. + /// [`egui::Context::run`]. Use [`Self::run_once_in_egui_central_panel`] if you want to ensure + /// that the closure is called exactly once. + //TODO(ab): should this be removed entirely in favor of `run_once_in_egui_central_panel`? pub fn run_in_egui_central_panel( &self, mut func: impl FnMut(&ViewerContext<'_>, &mut egui::Ui), @@ -322,6 +323,36 @@ impl TestContext { }); } + /// Run the given function once with a [`ViewerContext`] produced by the [`Self`], in the + /// context of an [`egui::CentralPanel`]. + /// + /// IMPORTANT: call [`Self::handle_system_commands`] after calling this function if your test + /// relies on system commands. + /// + /// Notes: + /// - Uses [`egui::__run_test_ctx`]. + pub fn run_once_in_egui_central_panel( + &self, + func: impl FnOnce(&ViewerContext<'_>, &mut egui::Ui) -> R, + ) -> R { + let mut func = Some(func); + let mut result = None; + + egui::__run_test_ctx(|ctx| { + egui::CentralPanel::default().show(ctx, |ui| { + let egui_ctx = ui.ctx().clone(); + + self.run(&egui_ctx, |ctx| { + if let Some(func) = func.take() { + result = Some(func(ctx, ui)); + } + }); + }); + }); + + result.expect("Function should have been called at least once") + } + /// Best-effort attempt to meaningfully handle some of the system commands. pub fn handle_system_commands(&mut self) { while let Some(command) = self.command_receiver.recv_system() { @@ -379,10 +410,9 @@ impl TestContext { SystemCommand::FileSaver(_) => handled = false, } - eprintln!( - "{} system command: {command_name:?}", - if handled { "Handled" } else { "Ignored" } - ); + if !handled { + eprintln!("Ignored system command: {command_name:?}",); + } } } } diff --git a/crates/viewer/re_viewport_blueprint/src/view.rs b/crates/viewer/re_viewport_blueprint/src/view.rs index 5b65507fd3be..84e14ca6c4a4 100644 --- a/crates/viewer/re_viewport_blueprint/src/view.rs +++ b/crates/viewer/re_viewport_blueprint/src/view.rs @@ -66,11 +66,24 @@ impl ViewBlueprint { /// Creates a new [`ViewBlueprint`] with a single [`ViewContents`]. /// - /// This [`ViewBlueprint`] is ephemeral. If you want to make it permanent you + /// This [`ViewBlueprint`] is ephemeral. If you want to make it permanent, you /// must call [`Self::save_to_blueprint_store`]. pub fn new(view_class: ViewClassIdentifier, recommended: RecommendedView) -> Self { - let id = ViewId::random(); + Self::new_with_id(view_class, recommended, ViewId::random()) + } + /// Creates a new [`ViewBlueprint`] with a single [`ViewContents`], using the provided id. + /// + /// Useful for testing contexts where random ids are not desired. Avoid using in production + /// code. + /// + /// This [`ViewBlueprint`] is ephemeral. If you want to make it permanent, you + /// must call [`Self::save_to_blueprint_store`]. + pub fn new_with_id( + view_class: ViewClassIdentifier, + recommended: RecommendedView, + id: ViewId, + ) -> Self { let path_subs = EntityPathSubs::new_with_origin(&recommended.origin); let query_filter = recommended.query_filter.resolve_forgiving(&path_subs); From e0dbdf45d37ac463a2c745593ce490cb0a22c238 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler Date: Thu, 23 Jan 2025 22:09:22 +0100 Subject: [PATCH 06/15] Fix lint --- crates/viewer/re_blueprint_tree/Cargo.toml | 5 +++-- crates/viewer/re_blueprint_tree/src/data.rs | 2 +- .../viewer/re_blueprint_tree/tests/view_structure_test.rs | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/crates/viewer/re_blueprint_tree/Cargo.toml b/crates/viewer/re_blueprint_tree/Cargo.toml index f52ae4b1fb89..7e97d4332761 100644 --- a/crates/viewer/re_blueprint_tree/Cargo.toml +++ b/crates/viewer/re_blueprint_tree/Cargo.toml @@ -45,7 +45,9 @@ smallvec.workspace = true [dev-dependencies] # Trick to reliably auto-enable the testing feature when running tests # see: https://github.com/rust-lang/cargo/issues/2911#issuecomment-1483256987 -re_blueprint_tree = { path = ".", default-features = false, features = ["testing"] } +re_blueprint_tree = { path = ".", default-features = false, features = [ + "testing", +] } re_chunk_store.workspace = true re_view_spatial.workspace = true @@ -54,4 +56,3 @@ re_viewport_blueprint = { workspace = true, features = ["testing"] } egui_kittest.workspace = true insta = { workspace = true, features = ["redactions", "yaml"] } - diff --git a/crates/viewer/re_blueprint_tree/src/data.rs b/crates/viewer/re_blueprint_tree/src/data.rs index 5438ef91f85b..d4322c7018a0 100644 --- a/crates/viewer/re_blueprint_tree/src/data.rs +++ b/crates/viewer/re_blueprint_tree/src/data.rs @@ -315,7 +315,7 @@ impl DataResultData { // // TODO(ab): we're currently only matching on the last part of `hierarchy`. Technically, - // this means that `herarchy` is not needed at all. It will however be needed when we match + // this means that `hierarchy` is not needed at all. It will however be needed when we match // across multiple parts, so it's good to have it already. let (entity_part_matches, highlight_sections) = if filter_matcher.matches_everything() { // fast path (filter is inactive) diff --git a/crates/viewer/re_blueprint_tree/tests/view_structure_test.rs b/crates/viewer/re_blueprint_tree/tests/view_structure_test.rs index 247fd0f6ba10..3ae257a85b1a 100644 --- a/crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +++ b/crates/viewer/re_blueprint_tree/tests/view_structure_test.rs @@ -22,7 +22,7 @@ const VIEW_ID: &str = "this-is-a-view-id"; #[derive(Debug, Clone, Copy)] enum RecordingKind { /// No entities are logged. - Emtpy, + Empty, /// Some placeholder entity hierarchy is logged. Regular, @@ -43,7 +43,7 @@ fn base_test_cases() -> impl Iterator { name: "empty", origin: EntityPath::root(), entity_filter: "$origin/**", - recording_kind: RecordingKind::Emtpy, + recording_kind: RecordingKind::Empty, }, TestCase { name: "root_origin", @@ -96,7 +96,7 @@ fn test_context(test_case: &TestCase) -> TestContext { test_context.register_view_class::(); match test_case.recording_kind { - RecordingKind::Emtpy => {} + RecordingKind::Empty => {} RecordingKind::Regular => { test_context.log_entity("/path/to/left".into(), add_point_to_chunk_builder); test_context.log_entity("/path/to/right".into(), add_point_to_chunk_builder); From f31ae02656a06cf5d7d835dc6ee5a29584678705 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler Date: Fri, 24 Jan 2025 09:52:15 +0100 Subject: [PATCH 07/15] Clean up test --- Cargo.lock | 1 - crates/viewer/re_blueprint_tree/Cargo.toml | 6 ------ .../tests/blueprint_tree_tests.rs | 16 ++++++++++------ .../tests/view_structure_test.rs | 6 ++++-- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d0b1b67580eb..98b02685a281 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5688,7 +5688,6 @@ dependencies = [ "egui_tiles", "insta", "itertools 0.13.0", - "re_blueprint_tree", "re_chunk_store", "re_context_menu", "re_data_ui", diff --git a/crates/viewer/re_blueprint_tree/Cargo.toml b/crates/viewer/re_blueprint_tree/Cargo.toml index 7e97d4332761..daba6ada7340 100644 --- a/crates/viewer/re_blueprint_tree/Cargo.toml +++ b/crates/viewer/re_blueprint_tree/Cargo.toml @@ -43,12 +43,6 @@ smallvec.workspace = true [dev-dependencies] -# Trick to reliably auto-enable the testing feature when running tests -# see: https://github.com/rust-lang/cargo/issues/2911#issuecomment-1483256987 -re_blueprint_tree = { path = ".", default-features = false, features = [ - "testing", -] } - re_chunk_store.workspace = true re_view_spatial.workspace = true re_viewer_context = { workspace = true, features = ["testing"] } diff --git a/crates/viewer/re_blueprint_tree/tests/blueprint_tree_tests.rs b/crates/viewer/re_blueprint_tree/tests/blueprint_tree_tests.rs index a5763373ac07..a07681b53fd9 100644 --- a/crates/viewer/re_blueprint_tree/tests/blueprint_tree_tests.rs +++ b/crates/viewer/re_blueprint_tree/tests/blueprint_tree_tests.rs @@ -1,3 +1,5 @@ +#![cfg(feature = "testing")] + use egui::Vec2; use re_blueprint_tree::BlueprintTree; @@ -5,7 +7,9 @@ use re_chunk_store::external::re_chunk::ChunkBuilder; use re_chunk_store::RowId; use re_log_types::build_frame_nr; use re_types::archetypes::Points3D; -use re_viewer_context::{test_context::TestContext, CollapseScope, RecommendedView, ViewClass}; +use re_viewer_context::{ + test_context::TestContext, CollapseScope, RecommendedView, ViewClass, ViewId, +}; use re_viewport_blueprint::{ test_context_ext::TestContextExt as _, ViewBlueprint, ViewportBlueprint, }; @@ -51,19 +55,19 @@ fn collapse_expand_all_blueprint_panel_should_match_snapshot() { test_context.log_entity("/path/to/entity1".into(), add_point_to_chunk_builder); test_context.log_entity("/another/way/to/entity2".into(), add_point_to_chunk_builder); - let view_id = test_context.setup_viewport_blueprint(|_ctx, blueprint| { - let view = ViewBlueprint::new( + let view_id = ViewId::hashed_from_str("some-view-id-hash"); + + test_context.setup_viewport_blueprint(|_ctx, blueprint| { + let view = ViewBlueprint::new_with_id( re_view_spatial::SpatialView3D::identifier(), RecommendedView::root(), + view_id, ); - let view_id = view.id; blueprint.add_views(std::iter::once(view), None, None); // TODO(ab): add containers in the hierarchy (requires work on the container API, // currently very cumbersome to use for testing purposes). - - view_id }); let mut blueprint_tree = BlueprintTree::default(); diff --git a/crates/viewer/re_blueprint_tree/tests/view_structure_test.rs b/crates/viewer/re_blueprint_tree/tests/view_structure_test.rs index 3ae257a85b1a..8c318f4fb374 100644 --- a/crates/viewer/re_blueprint_tree/tests/view_structure_test.rs +++ b/crates/viewer/re_blueprint_tree/tests/view_structure_test.rs @@ -1,5 +1,7 @@ -//! Test suite dedicated to snapshot the way we present various kinds of blueprint tree structures -//! with a focus on various view contents. +//! Snapshot testTest suite dedicated to snapshot the way we present various kinds of blueprint tree structures +//! with a focus on various view contents and filter configuration. + +#![cfg(feature = "testing")] use egui::Vec2; use egui_kittest::{SnapshotError, SnapshotOptions}; From eeae695da8c335fac24573676915cb277d776fbc Mon Sep 17 00:00:00 2001 From: Antoine Beyeler Date: Fri, 24 Jan 2025 11:25:25 +0100 Subject: [PATCH 08/15] Docstring and rename --- .../re_blueprint_tree/src/blueprint_tree.rs | 2 +- crates/viewer/re_blueprint_tree/src/data.rs | 43 ++++++++++++++----- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs b/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs index 164db62818c6..40019fe750ef 100644 --- a/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs +++ b/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs @@ -435,7 +435,7 @@ impl BlueprintTree { ); let item_content = match data_result_data.kind { - DataResultKind::EmptyOriginPlaceholder | DataResultKind::DataResult => { + DataResultKind::EmptyOriginPlaceholder | DataResultKind::EntityPart => { let is_empty_origin_placeholder = matches!( data_result_data.kind, DataResultKind::EmptyOriginPlaceholder diff --git a/crates/viewer/re_blueprint_tree/src/data.rs b/crates/viewer/re_blueprint_tree/src/data.rs index d4322c7018a0..70fc6d03e59d 100644 --- a/crates/viewer/re_blueprint_tree/src/data.rs +++ b/crates/viewer/re_blueprint_tree/src/data.rs @@ -1,11 +1,12 @@ //! Data structure describing the contents of the blueprint tree //! -//! Notes: -//! - Design goal: single tree walking pass over the entire data. +//! The design goal of these structures is to cover the entire underlying tree (container hierarchy +//! and data result hierarchies) by walking it once entirely, applying filtering on the way. //! -//! Missing: -//! - deferred tree walking (collapsed, non-filtered path) -//! - caching +//! This is done regardless of whether the data is actually used by the UI (e.g. if everything is +//! collapsed). Benchmarks have indicated that this approach incurs a negligible overhead compared +//! to the overall cost of having large blueprint trees (a.k.a the many-entities performance +//! issues). use std::ops::Range; @@ -24,6 +25,7 @@ use re_viewport_blueprint::{ContainerBlueprint, ViewBlueprint, ViewportBlueprint use crate::data_result_node_or_path::DataResultNodeOrPath; +/// Top-level blueprint tree structure. #[derive(Debug, Default)] #[cfg_attr(feature = "testing", derive(serde::Serialize, serde::Deserialize))] pub struct BlueprintTreeData { @@ -55,6 +57,7 @@ impl BlueprintTreeData { // --- +/// Data for either a container or a view (both of which possible child of a container). #[derive(Debug)] #[cfg_attr(feature = "testing", derive(serde::Serialize, serde::Deserialize))] pub enum ContentsData { @@ -62,6 +65,7 @@ pub enum ContentsData { View(ViewData), } +/// Data related to a single container and its children. #[derive(Debug)] #[cfg_attr(feature = "testing", derive(serde::Serialize, serde::Deserialize))] pub struct ContainerData { @@ -131,6 +135,7 @@ impl ContainerData { // --- +/// Data related to a single view and its content. #[derive(Debug)] #[cfg_attr(feature = "testing", derive(serde::Serialize, serde::Deserialize))] pub struct ViewData { @@ -142,7 +147,15 @@ pub struct ViewData { pub visible: bool, pub default_open: bool, + /// The origin tree contains the data results contained in the subtree defined by the view + /// origin. They are presented first in the blueprint tree. pub origin_tree: Option, + + /// Projection trees are the various trees contained data results which are outside the view + /// origin subtrees. They are presented after a "Projections:" label in the blueprint tree. + /// + /// These trees may be super-trees of the view origin trees. In that case, the view origin + /// subtree is represented by a stub item, see [`DataResultKind::OriginProjectionPlaceholder`]. pub projection_trees: Vec, } @@ -252,14 +265,19 @@ impl ViewData { // --- -/// The kind of thing we may be displaying in the tree +/// The various kind of things that may be represented in a data result tree. #[derive(Debug)] #[cfg_attr(feature = "testing", derive(serde::Serialize, serde::Deserialize))] pub enum DataResultKind { - EmptyOriginPlaceholder, + /// This is a regular entity part of a data result (or the tree that contains it). + EntityPart, - DataResult, + /// When the view has no data result contained in the view origin subtree, we still display the + /// origin with a warning styling to highlight what is likely an undesired view configuration. + EmptyOriginPlaceholder, + /// Since the view origin tree is displayed on its own, we don't repeat it within projections + /// and instead replace it with this placeholder. OriginProjectionPlaceholder, } @@ -272,11 +290,16 @@ pub struct DataResultData { pub view_id: ViewId, + /// Label that should be used for display. + /// + /// This typically corresponds to `entity_path.last().ui_string()` but covers corner cases. pub label: String, + + /// The sections within the label that correspond to a filter match and should thus be + /// highlighted. pub highlight_sections: SmallVec<[Range; 2]>, pub default_open: bool, - pub children: Vec, } @@ -375,7 +398,7 @@ impl DataResultData { children.sort_by(|a, b| a.entity_path.cmp(&b.entity_path)); (is_already_a_match || !children.is_empty()).then(|| Self { - kind: DataResultKind::DataResult, + kind: DataResultKind::EntityPart, entity_path, visible, view_id, From 93f9ca26041e00e347b9b1bd1f1c610eef4d5537 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler Date: Fri, 24 Jan 2025 17:24:42 +0100 Subject: [PATCH 09/15] fix snapshots post rename --- ...structure_test__no-query-multiple_proj.snap | 8 ++++---- ...ructure_test__no-query-non_root_origin.snap | 10 +++++----- ...e_test__no-query-proj_with_placeholder.snap | 18 +++++++++--------- ...w_structure_test__no-query-root_origin.snap | 18 +++++++++--------- ...w_structure_test__no-query-single_proj.snap | 12 ++++++------ ...test__query-path-proj_with_placeholder.snap | 4 ++-- ...structure_test__query-path-root_origin.snap | 14 +++++++------- ..._structure_test__query-t-multiple_proj.snap | 6 +++--- ...tructure_test__query-t-non_root_origin.snap | 10 +++++----- ...re_test__query-t-proj_with_placeholder.snap | 18 +++++++++--------- ...ew_structure_test__query-t-root_origin.snap | 18 +++++++++--------- ...ew_structure_test__query-t-single_proj.snap | 10 +++++----- ...ructure_test__query-void-multiple_proj.snap | 4 ++-- ...cture_test__query-void-non_root_origin.snap | 6 +++--- ...test__query-void-proj_with_placeholder.snap | 6 +++--- ...structure_test__query-void-root_origin.snap | 10 +++++----- ...structure_test__query-void-single_proj.snap | 6 +++--- 17 files changed, 89 insertions(+), 89 deletions(-) diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-multiple_proj.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-multiple_proj.snap index 1381aa8dd448..9da05a081b2e 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-multiple_proj.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-multiple_proj.snap @@ -20,7 +20,7 @@ root_container: visible: true default_open: false origin_tree: - kind: DataResult + kind: EntityPart entity_path: - center - way @@ -32,7 +32,7 @@ root_container: default_open: false children: [] projection_trees: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -44,7 +44,7 @@ root_container: highlight_sections: [] default_open: false children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -56,7 +56,7 @@ root_container: highlight_sections: [] default_open: false children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-non_root_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-non_root_origin.snap index 1c34f08bb8dd..dcd755fb910b 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-non_root_origin.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-non_root_origin.snap @@ -20,7 +20,7 @@ root_container: visible: true default_open: true origin_tree: - kind: DataResult + kind: EntityPart entity_path: - path - to @@ -31,7 +31,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -43,7 +43,7 @@ root_container: highlight_sections: [] default_open: false children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -55,7 +55,7 @@ root_container: highlight_sections: [] default_open: false children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -67,7 +67,7 @@ root_container: highlight_sections: [] default_open: false children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-proj_with_placeholder.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-proj_with_placeholder.snap index b88695c0da9c..358a6ce9c6fc 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-proj_with_placeholder.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-proj_with_placeholder.snap @@ -20,7 +20,7 @@ root_container: visible: true default_open: true origin_tree: - kind: DataResult + kind: EntityPart entity_path: - path - to @@ -31,7 +31,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -43,7 +43,7 @@ root_container: highlight_sections: [] default_open: false children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -55,7 +55,7 @@ root_container: highlight_sections: [] default_open: false children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -67,7 +67,7 @@ root_container: highlight_sections: [] default_open: false children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -81,7 +81,7 @@ root_container: default_open: false children: [] projection_trees: - - kind: DataResult + - kind: EntityPart entity_path: [] visible: true view_id: @@ -90,7 +90,7 @@ root_container: highlight_sections: [] default_open: false children: - - kind: DataResult + - kind: EntityPart entity_path: - center visible: true @@ -100,7 +100,7 @@ root_container: highlight_sections: [] default_open: false children: - - kind: DataResult + - kind: EntityPart entity_path: - center - way @@ -111,7 +111,7 @@ root_container: highlight_sections: [] default_open: false children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path visible: true diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-root_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-root_origin.snap index f9343e6d008b..50a8535ede56 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-root_origin.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-root_origin.snap @@ -20,7 +20,7 @@ root_container: visible: true default_open: true origin_tree: - kind: DataResult + kind: EntityPart entity_path: [] visible: true view_id: @@ -29,7 +29,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - center visible: true @@ -39,7 +39,7 @@ root_container: highlight_sections: [] default_open: false children: - - kind: DataResult + - kind: EntityPart entity_path: - center - way @@ -50,7 +50,7 @@ root_container: highlight_sections: [] default_open: false children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path visible: true @@ -60,7 +60,7 @@ root_container: highlight_sections: [] default_open: false children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -71,7 +71,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -83,7 +83,7 @@ root_container: highlight_sections: [] default_open: false children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -95,7 +95,7 @@ root_container: highlight_sections: [] default_open: false children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -107,7 +107,7 @@ root_container: highlight_sections: [] default_open: false children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-single_proj.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-single_proj.snap index ce683663ce9a..71442e1cc5a8 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-single_proj.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__no-query-single_proj.snap @@ -20,7 +20,7 @@ root_container: visible: true default_open: false origin_tree: - kind: DataResult + kind: EntityPart entity_path: - center - way @@ -32,7 +32,7 @@ root_container: default_open: false children: [] projection_trees: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -43,7 +43,7 @@ root_container: highlight_sections: [] default_open: false children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -55,7 +55,7 @@ root_container: highlight_sections: [] default_open: false children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -67,7 +67,7 @@ root_container: highlight_sections: [] default_open: false children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -79,7 +79,7 @@ root_container: highlight_sections: [] default_open: false children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-proj_with_placeholder.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-proj_with_placeholder.snap index c44ad29efbf7..47f2c260bd61 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-proj_with_placeholder.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-proj_with_placeholder.snap @@ -21,7 +21,7 @@ root_container: default_open: true origin_tree: ~ projection_trees: - - kind: DataResult + - kind: EntityPart entity_path: [] visible: true view_id: @@ -30,7 +30,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path visible: true diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-root_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-root_origin.snap index ddacdc45341b..bfd26e4b5e73 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-root_origin.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-path-root_origin.snap @@ -20,7 +20,7 @@ root_container: visible: true default_open: true origin_tree: - kind: DataResult + kind: EntityPart entity_path: [] visible: true view_id: @@ -29,7 +29,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path visible: true @@ -41,7 +41,7 @@ root_container: end: 4 default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -52,7 +52,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -64,7 +64,7 @@ root_container: highlight_sections: [] default_open: true children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -76,7 +76,7 @@ root_container: highlight_sections: [] default_open: true children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -88,7 +88,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-multiple_proj.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-multiple_proj.snap index 51ab5d9ab110..00df3f243346 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-multiple_proj.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-multiple_proj.snap @@ -21,7 +21,7 @@ root_container: default_open: true origin_tree: ~ projection_trees: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -35,7 +35,7 @@ root_container: end: 5 default_open: true children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -49,7 +49,7 @@ root_container: end: 1 default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-non_root_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-non_root_origin.snap index a6476d68cb0e..1bf6580755fb 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-non_root_origin.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-non_root_origin.snap @@ -20,7 +20,7 @@ root_container: visible: true default_open: true origin_tree: - kind: DataResult + kind: EntityPart entity_path: - path - to @@ -33,7 +33,7 @@ root_container: end: 1 default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -47,7 +47,7 @@ root_container: end: 4 default_open: true children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -61,7 +61,7 @@ root_container: end: 5 default_open: true children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -75,7 +75,7 @@ root_container: end: 1 default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-proj_with_placeholder.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-proj_with_placeholder.snap index dbf1a33d5f1b..1881ef1c6d2c 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-proj_with_placeholder.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-proj_with_placeholder.snap @@ -20,7 +20,7 @@ root_container: visible: true default_open: true origin_tree: - kind: DataResult + kind: EntityPart entity_path: - path - to @@ -33,7 +33,7 @@ root_container: end: 1 default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -47,7 +47,7 @@ root_container: end: 4 default_open: true children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -61,7 +61,7 @@ root_container: end: 5 default_open: true children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -75,7 +75,7 @@ root_container: end: 1 default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -89,7 +89,7 @@ root_container: default_open: true children: [] projection_trees: - - kind: DataResult + - kind: EntityPart entity_path: [] visible: true view_id: @@ -98,7 +98,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - center visible: true @@ -110,7 +110,7 @@ root_container: end: 4 default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - center - way @@ -121,7 +121,7 @@ root_container: highlight_sections: [] default_open: true children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path visible: true diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-root_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-root_origin.snap index 93868b845c45..bc93b1e4ac60 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-root_origin.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-root_origin.snap @@ -20,7 +20,7 @@ root_container: visible: true default_open: true origin_tree: - kind: DataResult + kind: EntityPart entity_path: [] visible: true view_id: @@ -29,7 +29,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - center visible: true @@ -41,7 +41,7 @@ root_container: end: 4 default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - center - way @@ -52,7 +52,7 @@ root_container: highlight_sections: [] default_open: true children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path visible: true @@ -64,7 +64,7 @@ root_container: end: 3 default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -77,7 +77,7 @@ root_container: end: 1 default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -91,7 +91,7 @@ root_container: end: 4 default_open: true children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -105,7 +105,7 @@ root_container: end: 5 default_open: true children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -119,7 +119,7 @@ root_container: end: 1 default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-single_proj.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-single_proj.snap index 2e7f7e65577f..3d415da35869 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-single_proj.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-t-single_proj.snap @@ -21,7 +21,7 @@ root_container: default_open: true origin_tree: ~ projection_trees: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -34,7 +34,7 @@ root_container: end: 1 default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -48,7 +48,7 @@ root_container: end: 4 default_open: true children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -62,7 +62,7 @@ root_container: end: 5 default_open: true children: [] - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -76,7 +76,7 @@ root_container: end: 1 default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-multiple_proj.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-multiple_proj.snap index 0ee5c05a2c6f..9bc9f2b0b871 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-multiple_proj.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-multiple_proj.snap @@ -21,7 +21,7 @@ root_container: default_open: true origin_tree: ~ projection_trees: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -33,7 +33,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-non_root_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-non_root_origin.snap index 289f2abdf691..a592391fcf7c 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-non_root_origin.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-non_root_origin.snap @@ -20,7 +20,7 @@ root_container: visible: true default_open: true origin_tree: - kind: DataResult + kind: EntityPart entity_path: - path - to @@ -31,7 +31,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -43,7 +43,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-proj_with_placeholder.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-proj_with_placeholder.snap index 289f2abdf691..a592391fcf7c 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-proj_with_placeholder.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-proj_with_placeholder.snap @@ -20,7 +20,7 @@ root_container: visible: true default_open: true origin_tree: - kind: DataResult + kind: EntityPart entity_path: - path - to @@ -31,7 +31,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -43,7 +43,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-root_origin.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-root_origin.snap index 40b426d93b85..11a4c73875ba 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-root_origin.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-root_origin.snap @@ -20,7 +20,7 @@ root_container: visible: true default_open: true origin_tree: - kind: DataResult + kind: EntityPart entity_path: [] visible: true view_id: @@ -29,7 +29,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path visible: true @@ -39,7 +39,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -50,7 +50,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -62,7 +62,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to diff --git a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-single_proj.snap b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-single_proj.snap index 1843f67695e4..9be22058589b 100644 --- a/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-single_proj.snap +++ b/crates/viewer/re_blueprint_tree/tests/snapshots/view_structure_test__query-void-single_proj.snap @@ -21,7 +21,7 @@ root_container: default_open: true origin_tree: ~ projection_trees: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -32,7 +32,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to @@ -44,7 +44,7 @@ root_container: highlight_sections: [] default_open: true children: - - kind: DataResult + - kind: EntityPart entity_path: - path - to From a7a33c689abd15379604c60eac8f48fe054c6857 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler Date: Tue, 28 Jan 2025 09:24:55 +0100 Subject: [PATCH 10/15] Review comments --- crates/viewer/re_blueprint_tree/src/blueprint_tree.rs | 11 +++++------ crates/viewer/re_blueprint_tree/src/data.rs | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs b/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs index 40019fe750ef..38b921c25c20 100644 --- a/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs +++ b/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs @@ -118,12 +118,11 @@ impl BlueprintTree { self.candidate_drop_parent_container_id = self.next_candidate_drop_parent_container_id; self.next_candidate_drop_parent_container_id = None; - let blueprint_tree_data = - std::hint::black_box(BlueprintTreeData::from_blueprint_and_filter( - ctx, - viewport_blueprint, - &self.filter_state.filter(), - )); + let blueprint_tree_data = BlueprintTreeData::from_blueprint_and_filter( + ctx, + viewport_blueprint, + &self.filter_state.filter(), + ); egui::ScrollArea::both() .id_salt("blueprint_tree_scroll_area") diff --git a/crates/viewer/re_blueprint_tree/src/data.rs b/crates/viewer/re_blueprint_tree/src/data.rs index 70fc6d03e59d..2c1f3aa5013b 100644 --- a/crates/viewer/re_blueprint_tree/src/data.rs +++ b/crates/viewer/re_blueprint_tree/src/data.rs @@ -6,7 +6,7 @@ //! This is done regardless of whether the data is actually used by the UI (e.g. if everything is //! collapsed). Benchmarks have indicated that this approach incurs a negligible overhead compared //! to the overall cost of having large blueprint trees (a.k.a the many-entities performance -//! issues). +//! issues: https://github.com/rerun-io/rerun/issues/8233). use std::ops::Range; From 4fdff3fdc4448b5430a84b6ab995721c6814bbe6 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Tue, 28 Jan 2025 09:25:25 +0100 Subject: [PATCH 11/15] Update crates/viewer/re_blueprint_tree/src/data.rs Co-authored-by: Emil Ernerfeldt --- crates/viewer/re_blueprint_tree/src/data.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/viewer/re_blueprint_tree/src/data.rs b/crates/viewer/re_blueprint_tree/src/data.rs index 2c1f3aa5013b..a944b3b52a5f 100644 --- a/crates/viewer/re_blueprint_tree/src/data.rs +++ b/crates/viewer/re_blueprint_tree/src/data.rs @@ -186,11 +186,8 @@ impl ViewData { false, ); - if cfg!(debug_assertions) { - debug_assert!(hierarchy.is_empty()); - } else { - hierarchy.clear(); - } + debug_assert!(hierarchy.is_empty()); + hierarchy.clear(); // // Projection data results From 08750bebaf55e65dc6e5802be67b4eda69478c9b Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Tue, 28 Jan 2025 09:25:43 +0100 Subject: [PATCH 12/15] Update crates/viewer/re_blueprint_tree/src/data.rs Co-authored-by: Emil Ernerfeldt --- crates/viewer/re_blueprint_tree/src/data.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/viewer/re_blueprint_tree/src/data.rs b/crates/viewer/re_blueprint_tree/src/data.rs index a944b3b52a5f..078ca4e7b5ea 100644 --- a/crates/viewer/re_blueprint_tree/src/data.rs +++ b/crates/viewer/re_blueprint_tree/src/data.rs @@ -229,11 +229,8 @@ impl ViewData { false, ); - if cfg!(debug_assertions) { - debug_assert!(hierarchy.is_empty()); - } else { - hierarchy.clear(); - } + debug_assert!(hierarchy.is_empty()); + hierarchy.clear(); projection_tree }) From fba8175ec4d5dd00eab4c35c5ff51b69dfdedda5 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Tue, 28 Jan 2025 09:26:10 +0100 Subject: [PATCH 13/15] Update crates/viewer/re_blueprint_tree/src/data.rs Co-authored-by: Emil Ernerfeldt --- crates/viewer/re_blueprint_tree/src/data.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/viewer/re_blueprint_tree/src/data.rs b/crates/viewer/re_blueprint_tree/src/data.rs index 078ca4e7b5ea..4633ff8fc880 100644 --- a/crates/viewer/re_blueprint_tree/src/data.rs +++ b/crates/viewer/re_blueprint_tree/src/data.rs @@ -291,7 +291,7 @@ pub struct DataResultData { /// The sections within the label that correspond to a filter match and should thus be /// highlighted. - pub highlight_sections: SmallVec<[Range; 2]>, + pub highlight_sections: SmallVec<[Range; 1]>, pub default_open: bool, pub children: Vec, From 0f4c3c056c6824fd9f7d0fb9ea39caa4ef841f58 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler Date: Tue, 28 Jan 2025 09:33:29 +0100 Subject: [PATCH 14/15] Review comments --- crates/viewer/re_blueprint_tree/src/data.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/viewer/re_blueprint_tree/src/data.rs b/crates/viewer/re_blueprint_tree/src/data.rs index 4633ff8fc880..30deb28d9606 100644 --- a/crates/viewer/re_blueprint_tree/src/data.rs +++ b/crates/viewer/re_blueprint_tree/src/data.rs @@ -171,7 +171,7 @@ impl ViewData { let result_tree = &query_result.tree; // - // In origin tree data results + // Data results within the view origin subtree // let mut hierarchy = Vec::with_capacity(10); @@ -190,7 +190,7 @@ impl ViewData { hierarchy.clear(); // - // Projection data results + // Data results outside the view origin subtree (a.k.a projections) // let mut projections = Vec::new(); From f6ec5328a53e8b3dfde5082766bebb7b30e93d90 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler Date: Tue, 28 Jan 2025 09:34:07 +0100 Subject: [PATCH 15/15] lint --- crates/viewer/re_blueprint_tree/src/data.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/viewer/re_blueprint_tree/src/data.rs b/crates/viewer/re_blueprint_tree/src/data.rs index 30deb28d9606..63c5a36f0b62 100644 --- a/crates/viewer/re_blueprint_tree/src/data.rs +++ b/crates/viewer/re_blueprint_tree/src/data.rs @@ -6,7 +6,7 @@ //! This is done regardless of whether the data is actually used by the UI (e.g. if everything is //! collapsed). Benchmarks have indicated that this approach incurs a negligible overhead compared //! to the overall cost of having large blueprint trees (a.k.a the many-entities performance -//! issues: https://github.com/rerun-io/rerun/issues/8233). +//! issues: ). use std::ops::Range;