diff --git a/Cargo.lock b/Cargo.lock index fbb70bc12b1a..68e83333cacd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4836,6 +4836,7 @@ dependencies = [ "nohash-hasher", "re_data_store", "re_entity_db", + "re_log", "re_log_types", "re_query", "re_tracing", diff --git a/crates/re_space_view/Cargo.toml b/crates/re_space_view/Cargo.toml index b2d8c32d5a5e..6c030d61987c 100644 --- a/crates/re_space_view/Cargo.toml +++ b/crates/re_space_view/Cargo.toml @@ -25,6 +25,7 @@ default = [] re_data_store.workspace = true re_entity_db.workspace = true re_log_types.workspace = true +re_log.workspace = true re_query.workspace = true re_tracing.workspace = true re_types_core.workspace = true diff --git a/crates/re_space_view/src/view_property_ui.rs b/crates/re_space_view/src/view_property_ui.rs index 9fb83ba619d4..07e926fc82a2 100644 --- a/crates/re_space_view/src/view_property_ui.rs +++ b/crates/re_space_view/src/view_property_ui.rs @@ -1,5 +1,7 @@ -use ahash::HashMap; -use re_types_core::{Archetype, ArchetypeFieldInfo, ArchetypeInfo, ComponentName}; +use re_types_core::{ + reflection::{ArchetypeFieldReflection, ArchetypeReflection}, + Archetype, ArchetypeName, ArchetypeReflectionMarker, ComponentName, +}; use re_ui::{list_item, UiExt as _}; use re_viewer_context::{ ComponentFallbackProvider, ComponentUiTypes, QueryContext, SpaceViewId, SpaceViewState, @@ -10,30 +12,44 @@ use re_viewport_blueprint::entity_path_for_view_property; /// Display the UI for editing all components of a blueprint archetype. /// /// Note that this will show default values for components that are null. -pub fn view_property_ui( +pub fn view_property_ui( ctx: &ViewerContext<'_>, ui: &mut egui::Ui, view_id: SpaceViewId, fallback_provider: &dyn ComponentFallbackProvider, view_state: &dyn SpaceViewState, ) { - view_property_ui_impl(ctx, ui, view_id, A::info(), view_state, fallback_provider); + let name = A::name(); + if let Some(reflection) = ctx.reflection.archetypes.get(&name) { + view_property_ui_impl( + ctx, + ui, + view_id, + name, + reflection, + view_state, + fallback_provider, + ); + } else { + // The `ArchetypeReflectionMarker` bound should make this impossible. + re_log::warn_once!("Missing reflection data for archetype {name:?}."); + } } fn view_property_ui_impl( ctx: &ViewerContext<'_>, ui: &mut egui::Ui, view_id: SpaceViewId, - archetype: ArchetypeInfo, + name: ArchetypeName, + reflection: &ArchetypeReflection, view_state: &dyn SpaceViewState, fallback_provider: &dyn ComponentFallbackProvider, ) { - let blueprint_path = - entity_path_for_view_property(view_id, ctx.blueprint_db().tree(), archetype.name); + let blueprint_path = entity_path_for_view_property(view_id, ctx.blueprint_db().tree(), name); let query_ctx = QueryContext { viewer_ctx: ctx, target_entity_path: &blueprint_path, - archetype_name: Some(archetype.name), + archetype_name: Some(name), query: ctx.blueprint_query, view_state, view_ctx: None, @@ -42,57 +58,38 @@ fn view_property_ui_impl( let component_results = ctx.blueprint_db().latest_at( ctx.blueprint_query, &blueprint_path, - archetype.component_names.iter().copied(), + reflection.fields.iter().map(|field| field.component_name), ); - let field_info_per_component: HashMap<_, _> = archetype - .field_infos - .map(|field_infos| { - field_infos - .iter() - .cloned() - .map(|field_info| (field_info.component_name, field_info)) - .collect() - }) - .unwrap_or_default(); - - let non_indicator_components = archetype - .component_names - .as_ref() - .iter() - .filter(|component_name| !component_name.is_indicator_component()) - .collect::>(); - // If the property archetype only has a single component, don't show an additional hierarchy level! - if non_indicator_components.len() == 1 { - let component_name = *non_indicator_components[0]; - let field_info = field_info_per_component.get(&component_name); + if reflection.fields.len() == 1 { + let field = &reflection.fields[0]; view_property_component_ui( &query_ctx, ui, - component_name, - archetype.display_name, - field_info, + field.component_name, + reflection.display_name, + name, + field, &blueprint_path, - component_results.get_or_empty(component_name), + component_results.get_or_empty(field.component_name), fallback_provider, ); } else { let sub_prop_ui = |ui: &mut egui::Ui| { - for component_name in non_indicator_components { - let field_info = field_info_per_component.get(component_name); - let display_name = field_info - .map_or_else(|| component_name.short_name(), |info| info.display_name); + for field in &reflection.fields { + let display_name = &field.display_name; view_property_component_ui( &query_ctx, ui, - *component_name, + field.component_name, display_name, - field_info, + name, + field, &blueprint_path, - component_results.get_or_empty(*component_name), + component_results.get_or_empty(field.component_name), fallback_provider, ); } @@ -102,9 +99,9 @@ fn view_property_ui_impl( .interactive(false) .show_hierarchical_with_children( ui, - ui.make_persistent_id(archetype.name.full_name()), + ui.make_persistent_id(name.full_name()), true, - list_item::LabelContent::new(archetype.display_name), + list_item::LabelContent::new(reflection.display_name), sub_prop_ui, ); } @@ -117,7 +114,8 @@ fn view_property_component_ui( ui: &mut egui::Ui, component_name: ComponentName, root_item_display_name: &str, - field_info: Option<&ArchetypeFieldInfo>, + archetype_name: ArchetypeName, + field: &ArchetypeFieldReflection, blueprint_path: &re_log_types::EntityPath, component_results: &re_query::LatestAtComponentResults, fallback_provider: &dyn ComponentFallbackProvider, @@ -166,9 +164,10 @@ fn view_property_component_ui( .show_hierarchical(ui, singleline_list_item_content) }; - if let Some(tooltip) = field_info.map(|info| info.documentation) { - list_item_response = list_item_response.on_hover_text(tooltip); - } + list_item_response = list_item_response.on_hover_ui(|ui| { + let id = egui::Id::new((archetype_name, field.display_name)); + ui.markdown_ui(id, field.docstring_md); + }); view_property_context_menu( ctx.viewer_ctx, diff --git a/crates/re_types/src/blueprint/archetypes/background.rs b/crates/re_types/src/blueprint/archetypes/background.rs index dcd93a938aea..b44b16317209 100644 --- a/crates/re_types/src/blueprint/archetypes/background.rs +++ b/crates/re_types/src/blueprint/archetypes/background.rs @@ -63,22 +63,6 @@ static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 3usize]> = ] }); -static FIELD_INFOS: once_cell::sync::Lazy<[::re_types_core::ArchetypeFieldInfo; 2usize]> = - once_cell::sync::Lazy::new(|| { - [ - ::re_types_core::ArchetypeFieldInfo { - display_name: "Kind", - documentation: "The type of the background.", - component_name: "rerun.blueprint.components.BackgroundKind".into(), - }, - ::re_types_core::ArchetypeFieldInfo { - display_name: "Color", - documentation: "Color used for the `SolidColor` background type.", - component_name: "rerun.components.Color".into(), - }, - ] - }); - impl Background { /// The total number of components in the archetype: 1 required, 1 recommended, 1 optional pub const NUM_COMPONENTS: usize = 3usize; @@ -126,11 +110,6 @@ impl ::re_types_core::Archetype for Background { ALL_COMPONENTS.as_slice().into() } - #[inline] - fn field_infos() -> Option<::std::borrow::Cow<'static, [::re_types_core::ArchetypeFieldInfo]>> { - Some(FIELD_INFOS.as_slice().into()) - } - #[inline] fn from_arrow_components( arrow_data: impl IntoIterator)>, @@ -184,6 +163,8 @@ impl ::re_types_core::AsComponents for Background { } } +impl ::re_types_core::ArchetypeReflectionMarker for Background {} + impl Background { /// Create a new `Background`. #[inline] diff --git a/crates/re_types/src/blueprint/archetypes/plot_legend.rs b/crates/re_types/src/blueprint/archetypes/plot_legend.rs index d17a959dd25c..0e1d0a8d7ea8 100644 --- a/crates/re_types/src/blueprint/archetypes/plot_legend.rs +++ b/crates/re_types/src/blueprint/archetypes/plot_legend.rs @@ -72,23 +72,6 @@ static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 3usize]> = ] }); -static FIELD_INFOS: once_cell::sync::Lazy<[::re_types_core::ArchetypeFieldInfo; 2usize]> = - once_cell::sync::Lazy::new(|| { - [ - ::re_types_core::ArchetypeFieldInfo { - display_name: "Corner", - documentation: - "To what corner the legend is aligned.\n\nDefaults to the right bottom corner.", - component_name: "rerun.blueprint.components.Corner2D".into(), - }, - ::re_types_core::ArchetypeFieldInfo { - display_name: "Visible", - documentation: "Whether the legend is shown at all.\n\nTrue by default.", - component_name: "rerun.blueprint.components.Visible".into(), - }, - ] - }); - impl PlotLegend { /// The total number of components in the archetype: 0 required, 1 recommended, 2 optional pub const NUM_COMPONENTS: usize = 3usize; @@ -136,11 +119,6 @@ impl ::re_types_core::Archetype for PlotLegend { ALL_COMPONENTS.as_slice().into() } - #[inline] - fn field_infos() -> Option<::std::borrow::Cow<'static, [::re_types_core::ArchetypeFieldInfo]>> { - Some(FIELD_INFOS.as_slice().into()) - } - #[inline] fn from_arrow_components( arrow_data: impl IntoIterator)>, @@ -194,6 +172,8 @@ impl ::re_types_core::AsComponents for PlotLegend { } } +impl ::re_types_core::ArchetypeReflectionMarker for PlotLegend {} + impl PlotLegend { /// Create a new `PlotLegend`. #[inline] diff --git a/crates/re_types/src/blueprint/archetypes/scalar_axis.rs b/crates/re_types/src/blueprint/archetypes/scalar_axis.rs index 6aa0c1c50a9e..519978019057 100644 --- a/crates/re_types/src/blueprint/archetypes/scalar_axis.rs +++ b/crates/re_types/src/blueprint/archetypes/scalar_axis.rs @@ -70,22 +70,6 @@ static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 3usize]> = ] }); -static FIELD_INFOS: once_cell::sync::Lazy<[::re_types_core::ArchetypeFieldInfo; 2usize]> = - once_cell::sync::Lazy::new(|| { - [ - ::re_types_core::ArchetypeFieldInfo { - display_name: "Range", - documentation: "The range of the axis.\n\nIf unset, the range well be automatically determined based on the queried data.", - component_name: "rerun.components.Range1D".into(), - }, - ::re_types_core::ArchetypeFieldInfo { - display_name: "Zoom lock", - documentation: "If enabled, the Y axis range will remain locked to the specified range when zooming.", - component_name: "rerun.blueprint.components.LockRangeDuringZoom".into(), - }, - ] - }); - impl ScalarAxis { /// The total number of components in the archetype: 0 required, 1 recommended, 2 optional pub const NUM_COMPONENTS: usize = 3usize; @@ -133,11 +117,6 @@ impl ::re_types_core::Archetype for ScalarAxis { ALL_COMPONENTS.as_slice().into() } - #[inline] - fn field_infos() -> Option<::std::borrow::Cow<'static, [::re_types_core::ArchetypeFieldInfo]>> { - Some(FIELD_INFOS.as_slice().into()) - } - #[inline] fn from_arrow_components( arrow_data: impl IntoIterator)>, @@ -191,6 +170,8 @@ impl ::re_types_core::AsComponents for ScalarAxis { } } +impl ::re_types_core::ArchetypeReflectionMarker for ScalarAxis {} + impl ScalarAxis { /// Create a new `ScalarAxis`. #[inline] diff --git a/crates/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs b/crates/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs index c8c695ddcdd5..38c51a430cdb 100644 --- a/crates/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs +++ b/crates/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs @@ -83,27 +83,6 @@ static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 4usize]> = ] }); -static FIELD_INFOS: once_cell::sync::Lazy<[::re_types_core::ArchetypeFieldInfo; 3usize]> = - once_cell::sync::Lazy::new(|| { - [ - ::re_types_core::ArchetypeFieldInfo { - display_name: "Mag filter", - documentation: "Filter used when zooming in on the tensor.\n\nNote that the filter is applied to the scalar values *before* they are mapped to color.", - component_name: "rerun.components.MagnificationFilter".into(), - }, - ::re_types_core::ArchetypeFieldInfo { - display_name: "Colormap", - documentation: "How scalar values map to colors.", - component_name: "rerun.components.Colormap".into(), - }, - ::re_types_core::ArchetypeFieldInfo { - display_name: "Gamma", - documentation: "Gamma exponent applied to normalized values before mapping to color.\n\nRaises the normalized values to the power of this value before mapping to color.\nActs like an inverse brightness. Defaults to 1.0.", - component_name: "rerun.components.GammaCorrection".into(), - }, - ] - }); - impl TensorScalarMapping { /// The total number of components in the archetype: 0 required, 1 recommended, 3 optional pub const NUM_COMPONENTS: usize = 4usize; @@ -152,11 +131,6 @@ impl ::re_types_core::Archetype for TensorScalarMapping { ALL_COMPONENTS.as_slice().into() } - #[inline] - fn field_infos() -> Option<::std::borrow::Cow<'static, [::re_types_core::ArchetypeFieldInfo]>> { - Some(FIELD_INFOS.as_slice().into()) - } - #[inline] fn from_arrow_components( arrow_data: impl IntoIterator)>, @@ -225,6 +199,8 @@ impl ::re_types_core::AsComponents for TensorScalarMapping { } } +impl ::re_types_core::ArchetypeReflectionMarker for TensorScalarMapping {} + impl TensorScalarMapping { /// Create a new `TensorScalarMapping`. #[inline] diff --git a/crates/re_types/src/blueprint/archetypes/tensor_slice_selection.rs b/crates/re_types/src/blueprint/archetypes/tensor_slice_selection.rs index b5e5947bc1a3..e96b38d6adaa 100644 --- a/crates/re_types/src/blueprint/archetypes/tensor_slice_selection.rs +++ b/crates/re_types/src/blueprint/archetypes/tensor_slice_selection.rs @@ -95,33 +95,6 @@ static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 5usize]> = ] }); -static FIELD_INFOS: once_cell::sync::Lazy<[::re_types_core::ArchetypeFieldInfo; 4usize]> = - once_cell::sync::Lazy::new(|| { - [ - ::re_types_core::ArchetypeFieldInfo { - display_name: "Width", - documentation: "Which dimension to map to width.\n\nIf not specified, the height will be determined automatically based on the name and index of the dimension.", - component_name: "rerun.components.TensorWidthDimension".into(), - }, - ::re_types_core::ArchetypeFieldInfo { - display_name: "Height", - documentation: "Which dimension to map to height.\n\nIf not specified, the height will be determined automatically based on the name and index of the dimension.", - component_name: "rerun.components.TensorHeightDimension".into(), - }, - ::re_types_core::ArchetypeFieldInfo { - display_name: "Indices", - documentation: "Selected indices for all other dimensions.\n\nIf any of the here listed dimensions is equal to `width` or `height`, it will be ignored.", - component_name: "rerun.components.TensorDimensionIndexSelection".into(), - }, - ::re_types_core::ArchetypeFieldInfo { - display_name: "Slider", - documentation: "Any dimension listed here will have a slider for the index.\n\nEdits to the sliders will directly manipulate dimensions on the `indices` list.\nIf any of the here listed dimensions is equal to `width` or `height`, it will be ignored.\nIf not specified, adds slides for any dimension in `indices`.", - component_name: "rerun.blueprint.components.TensorDimensionIndexSlider" - .into(), - }, - ] - }); - impl TensorSliceSelection { /// The total number of components in the archetype: 0 required, 1 recommended, 4 optional pub const NUM_COMPONENTS: usize = 5usize; @@ -170,11 +143,6 @@ impl ::re_types_core::Archetype for TensorSliceSelection { ALL_COMPONENTS.as_slice().into() } - #[inline] - fn field_infos() -> Option<::std::borrow::Cow<'static, [::re_types_core::ArchetypeFieldInfo]>> { - Some(FIELD_INFOS.as_slice().into()) - } - #[inline] fn from_arrow_components( arrow_data: impl IntoIterator)>, @@ -267,6 +235,8 @@ impl ::re_types_core::AsComponents for TensorSliceSelection { } } +impl ::re_types_core::ArchetypeReflectionMarker for TensorSliceSelection {} + impl TensorSliceSelection { /// Create a new `TensorSliceSelection`. #[inline] diff --git a/crates/re_types/src/blueprint/archetypes/tensor_view_fit.rs b/crates/re_types/src/blueprint/archetypes/tensor_view_fit.rs index d72e47693c9e..921dd17794bd 100644 --- a/crates/re_types/src/blueprint/archetypes/tensor_view_fit.rs +++ b/crates/re_types/src/blueprint/archetypes/tensor_view_fit.rs @@ -58,15 +58,6 @@ static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 2usize]> = ] }); -static FIELD_INFOS: once_cell::sync::Lazy<[::re_types_core::ArchetypeFieldInfo; 1usize]> = - once_cell::sync::Lazy::new(|| { - [::re_types_core::ArchetypeFieldInfo { - display_name: "Scaling", - documentation: "How the image is scaled to fit the view.", - component_name: "rerun.blueprint.components.ViewFit".into(), - }] - }); - impl TensorViewFit { /// The total number of components in the archetype: 0 required, 1 recommended, 1 optional pub const NUM_COMPONENTS: usize = 2usize; @@ -114,11 +105,6 @@ impl ::re_types_core::Archetype for TensorViewFit { ALL_COMPONENTS.as_slice().into() } - #[inline] - fn field_infos() -> Option<::std::borrow::Cow<'static, [::re_types_core::ArchetypeFieldInfo]>> { - Some(FIELD_INFOS.as_slice().into()) - } - #[inline] fn from_arrow_components( arrow_data: impl IntoIterator)>, @@ -159,6 +145,8 @@ impl ::re_types_core::AsComponents for TensorViewFit { } } +impl ::re_types_core::ArchetypeReflectionMarker for TensorViewFit {} + impl TensorViewFit { /// Create a new `TensorViewFit`. #[inline] diff --git a/crates/re_types/src/blueprint/archetypes/visual_bounds2d.rs b/crates/re_types/src/blueprint/archetypes/visual_bounds2d.rs index b91f854abf6b..317a566872f0 100644 --- a/crates/re_types/src/blueprint/archetypes/visual_bounds2d.rs +++ b/crates/re_types/src/blueprint/archetypes/visual_bounds2d.rs @@ -66,17 +66,6 @@ static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; 2usize]> = ] }); -static FIELD_INFOS: once_cell::sync::Lazy<[::re_types_core::ArchetypeFieldInfo; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ - ::re_types_core::ArchetypeFieldInfo { - display_name: "Range", - documentation: "Controls the visible range of a 2D view.\n\nUse this to control pan & zoom of the view.", - component_name: "rerun.blueprint.components.VisualBounds2D".into(), - }, - ] - }); - impl VisualBounds2D { /// The total number of components in the archetype: 1 required, 1 recommended, 0 optional pub const NUM_COMPONENTS: usize = 2usize; @@ -124,11 +113,6 @@ impl ::re_types_core::Archetype for VisualBounds2D { ALL_COMPONENTS.as_slice().into() } - #[inline] - fn field_infos() -> Option<::std::borrow::Cow<'static, [::re_types_core::ArchetypeFieldInfo]>> { - Some(FIELD_INFOS.as_slice().into()) - } - #[inline] fn from_arrow_components( arrow_data: impl IntoIterator)>, @@ -170,6 +154,8 @@ impl ::re_types_core::AsComponents for VisualBounds2D { } } +impl ::re_types_core::ArchetypeReflectionMarker for VisualBounds2D {} + impl VisualBounds2D { /// Create a new `VisualBounds2D`. #[inline] diff --git a/crates/re_types_builder/src/codegen/rust/api.rs b/crates/re_types_builder/src/codegen/rust/api.rs index fbed1097e2de..c9525ff8def4 100644 --- a/crates/re_types_builder/src/codegen/rust/api.rs +++ b/crates/re_types_builder/src/codegen/rust/api.rs @@ -1012,43 +1012,13 @@ fn quote_trait_impls_from_obj( }) }; - let (field_info_array, field_info_getter) = if obj - .is_attr_set(ATTR_RUST_GENERATE_FIELD_INFO) + let impl_archetype_reflection_marker = if obj.is_attr_set(ATTR_RUST_GENERATE_FIELD_INFO) { - let field_infos = obj.fields.iter().map(|field| { - let display_name = re_case::to_human_case(&field.name); - let documentation = field - .docs - .lines_with_tag_matching(|tag| tag.is_empty()) - .join("\n"); - let Some(component_name) = field.typ.fqname() else { - panic!("archetype field must be an object/union or an array/vector of such") - }; - - quote! { - ::re_types_core::ArchetypeFieldInfo { - display_name: #display_name, - documentation: #documentation, - component_name: #component_name.into(), - } - } - }).collect_vec(); - let num_field_infos = field_infos.len(); - - let field_info_array = quote! { - static FIELD_INFOS: once_cell::sync::Lazy<[::re_types_core::ArchetypeFieldInfo; #num_field_infos]> = - once_cell::sync::Lazy::new(|| {[#(#field_infos,)*]}); - }; - let field_info_getter = quote! { - #[inline] - fn field_infos() -> Option<::std::borrow::Cow<'static, [::re_types_core::ArchetypeFieldInfo]>> { - Some(FIELD_INFOS.as_slice().into()) - } - }; - - (field_info_array, field_info_getter) + quote! { + impl ::re_types_core::ArchetypeReflectionMarker for #name { } + } } else { - (quote!(), quote!()) + quote!() }; quote! { @@ -1064,8 +1034,6 @@ fn quote_trait_impls_from_obj( static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentName; #num_all]> = once_cell::sync::Lazy::new(|| {[#required #recommended #optional]}); - #field_info_array - impl #name { #num_components_docstring pub const NUM_COMPONENTS: usize = #num_all; @@ -1114,8 +1082,6 @@ fn quote_trait_impls_from_obj( ALL_COMPONENTS.as_slice().into() } - #field_info_getter - #[inline] fn from_arrow_components( arrow_data: impl IntoIterator { diff --git a/crates/re_types_builder/src/codegen/rust/reflection.rs b/crates/re_types_builder/src/codegen/rust/reflection.rs index 0d675ed802ab..d34ec5b0de8d 100644 --- a/crates/re_types_builder/src/codegen/rust/reflection.rs +++ b/crates/re_types_builder/src/codegen/rust/reflection.rs @@ -4,7 +4,9 @@ use camino::Utf8PathBuf; use proc_macro2::TokenStream; use quote::{format_ident, quote}; -use crate::{codegen::autogen_warning, ObjectKind, Objects, Reporter}; +use crate::{ + codegen::autogen_warning, ObjectKind, Objects, Reporter, ATTR_RUST_GENERATE_FIELD_INFO, +}; use super::util::{append_tokens, doc_as_lines}; @@ -21,38 +23,48 @@ pub fn generate_reflection( let mut imports = BTreeSet::new(); let component_reflection = generate_component_reflection(reporter, objects, &mut imports); + let archetype_reflection = generate_archetype_reflection(reporter, objects); let mut code = format!("// {}\n\n", autogen_warning!()); - code.push_str("#![allow(unused_imports)]\n"); + code.push_str("#![allow(clippy::too_many_lines)]\n"); code.push_str("#![allow(clippy::wildcard_imports)]\n\n"); + code.push_str("#![allow(unused_imports)]\n"); for namespace in imports { code.push_str(&format!("use {namespace};\n")); } let quoted_reflection = quote! { use re_types_core::{ - external::arrow2, + ArchetypeName, ComponentName, + Loggable, + LoggableBatch as _, + reflection::{ + ArchetypeFieldReflection, + ArchetypeReflection, + ArchetypeReflectionMap, + ComponentReflection, + ComponentReflectionMap, + Reflection, + }, SerializationError, - reflection::{Reflection, ComponentReflectionMap, ComponentReflection} }; /// Generates reflection about all known components. /// /// Call only once and reuse the results. pub fn generate_reflection() -> Result { - use ::re_types_core::{Loggable, LoggableBatch as _}; - re_tracing::profile_function!(); Ok(Reflection { components: generate_component_reflection()?, - - // TODO(emilk): achetypes + archetypes: generate_archetype_reflection(), }) } #component_reflection + + #archetype_reflection }; let code = append_tokens(reporter, code, "ed_reflection, &path); @@ -104,12 +116,69 @@ fn generate_component_reflection( /// /// Call only once and reuse the results. fn generate_component_reflection() -> Result { - use ::re_types_core::{Loggable, LoggableBatch as _}; + re_tracing::profile_function!(); + let array = [ + #(#quoted_pairs,)* + ]; + Ok(ComponentReflectionMap::from_iter(array)) + } + } +} +/// Generate reflection about components. +fn generate_archetype_reflection(reporter: &Reporter, objects: &Objects) -> TokenStream { + let mut quoted_pairs = Vec::new(); + + for obj in objects + .objects_of_kind(ObjectKind::Archetype) + .filter(|obj| !obj.is_testing()) + .filter(|obj| obj.is_attr_set(ATTR_RUST_GENERATE_FIELD_INFO)) + { + let quoted_field_reflections = obj.fields.iter().map(|field| { + let Some(component_name) = field.typ.fqname() else { + panic!("archetype field must be an object/union or an array/vector of such") + }; + let display_name = re_case::to_human_case(&field.name); + let docstring_md = + doc_as_lines(reporter, &field.virtpath, &field.fqname, &field.docs).join("\n"); + + quote! { + ArchetypeFieldReflection { + component_name: #component_name.into(), + display_name: #display_name, + docstring_md: #docstring_md, + } + } + }); + + let fqname = &obj.fqname; + let quoted_name = quote!( ArchetypeName::new(#fqname) ); + let display_name = re_case::to_human_case(&obj.name); + let docstring_md = doc_as_lines(reporter, &obj.virtpath, &obj.fqname, &obj.docs).join("\n"); + let quoted_archetype_reflection = quote! { + ArchetypeReflection { + display_name: #display_name, + + docstring_md: #docstring_md, + + fields: vec![ + #(#quoted_field_reflections,)* + ], + } + }; + quoted_pairs.push(quote! { (#quoted_name, #quoted_archetype_reflection) }); + } + + quote! { + /// Generates reflection about all known archetypes. + /// + /// Call only once and reuse the results. + fn generate_archetype_reflection() -> ArchetypeReflectionMap { re_tracing::profile_function!(); - Ok(ComponentReflectionMap::from_iter([ + let array = [ #(#quoted_pairs,)* - ])) + ]; + ArchetypeReflectionMap::from_iter(array) } } } diff --git a/crates/re_types_core/src/archetype.rs b/crates/re_types_core/src/archetype.rs index e71afa6022c5..dff626618ab1 100644 --- a/crates/re_types_core/src/archetype.rs +++ b/crates/re_types_core/src/archetype.rs @@ -10,27 +10,6 @@ use crate::{Component, Loggable, LoggableBatch}; // --- -/// Additional information about an archetype's field. -#[derive(Debug, Clone)] -pub struct ArchetypeFieldInfo { - /// The name of the field in human case. - pub display_name: &'static str, - - /// Documentation string for the field (not the component type). - pub documentation: &'static str, - - /// The component name of the field's type. - pub component_name: ComponentName, -} - -/// Utility struct containing all archetype meta information. -pub struct ArchetypeInfo { - pub name: ArchetypeName, - pub display_name: &'static str, - pub component_names: std::borrow::Cow<'static, [ComponentName]>, - pub field_infos: Option>, -} - /// An archetype is a high-level construct that represents a set of [`Component`]s that usually /// play well with each other (i.e. they compose nicely). /// @@ -66,16 +45,6 @@ pub trait Archetype { /// Readable name for displaying in ui. fn display_name() -> &'static str; - /// Returns a struct with various meta information about this archetype. - fn info() -> ArchetypeInfo { - ArchetypeInfo { - name: Self::name(), - display_name: Self::display_name(), - component_names: Self::all_components(), - field_infos: Self::field_infos(), - } - } - // --- // TODO(cmc): Should we also generate and return static IntSets? @@ -127,15 +96,6 @@ pub trait Archetype { .into() } - /// Returns information about the archetype's fields. - ///s - /// This is optional and not implemented by all archetypes. - /// If present, it can be used to display additional information in the viewer. - #[inline] - fn field_infos() -> Option<::std::borrow::Cow<'static, [ArchetypeFieldInfo]>> { - None - } - // --- /// Given an iterator of Arrow arrays and their respective field metadata, deserializes them @@ -176,6 +136,10 @@ pub trait Archetype { } } +/// Indicates that the archetype has the `attr.rust.generate_field_info` +/// attribute, meaning it will have runtime reflection data available for it. +pub trait ArchetypeReflectionMarker {} + // --- re_string_interner::declare_new_type!( diff --git a/crates/re_types_core/src/lib.rs b/crates/re_types_core/src/lib.rs index 2c0c5e0e0f96..09aa34c307bd 100644 --- a/crates/re_types_core/src/lib.rs +++ b/crates/re_types_core/src/lib.rs @@ -87,14 +87,13 @@ mod view; pub use self::{ archetype::{ - Archetype, ArchetypeFieldInfo, ArchetypeInfo, ArchetypeName, GenericIndicatorComponent, + Archetype, ArchetypeName, ArchetypeReflectionMarker, GenericIndicatorComponent, NamedIndicatorComponent, }, arrow_buffer::ArrowBuffer, arrow_string::ArrowString, loggable::{Component, ComponentName, ComponentNameSet, Datatype, DatatypeName, Loggable}, loggable_batch::{ComponentBatch, DatatypeBatch, LoggableBatch, MaybeOwnedComponentBatch}, - reflection::*, result::{ DeserializationError, DeserializationResult, ResultExt, SerializationError, SerializationResult, _Backtrace, diff --git a/crates/re_types_core/src/reflection.rs b/crates/re_types_core/src/reflection.rs index e751feb4dcc1..30bae1d28b0f 100644 --- a/crates/re_types_core/src/reflection.rs +++ b/crates/re_types_core/src/reflection.rs @@ -1,18 +1,19 @@ //! Run-time reflection for reading meta-data about components and archetypes. -use crate::ComponentName; +use crate::{ArchetypeName, ComponentName}; /// Runtime reflection about components and archetypes. -#[derive(Default)] +#[derive(Clone, Debug, Default)] pub struct Reflection { pub components: ComponentReflectionMap, - // TODO(emilk): archetypes (ArchetypeFieldInfo etc). + pub archetypes: ArchetypeReflectionMap, } /// Runtime reflection about components. pub type ComponentReflectionMap = nohash_hasher::IntMap; /// Information about a Rerun [`component`](crate::Component), generated by codegen. +#[derive(Clone, Debug)] pub struct ComponentReflection { /// Markdown docstring for the component. pub docstring_md: &'static str, @@ -24,3 +25,32 @@ pub struct ComponentReflection { /// This is useful as a base fallback value when displaying UI. pub placeholder: Option>, } + +/// Runtime reflection about archetypes. +pub type ArchetypeReflectionMap = nohash_hasher::IntMap; + +/// Utility struct containing all archetype meta information. +#[derive(Clone, Debug)] +pub struct ArchetypeReflection { + /// The name of the field in human case. + pub display_name: &'static str, + + /// Markdown docstring for the archetype. + pub docstring_md: &'static str, + + /// All the component fields of the archetype, in the order they appear in the archetype. + pub fields: Vec, +} + +/// Additional information about an archetype's field. +#[derive(Clone, Debug)] +pub struct ArchetypeFieldReflection { + /// The type of the field (it's always a component). + pub component_name: ComponentName, + + /// The name of the field in human case. + pub display_name: &'static str, + + /// Markdown docstring for the field (not for the component type). + pub docstring_md: &'static str, +} diff --git a/crates/re_viewer/src/app.rs b/crates/re_viewer/src/app.rs index 5fa435a12dc7..33a6e7c3a47c 100644 --- a/crates/re_viewer/src/app.rs +++ b/crates/re_viewer/src/app.rs @@ -175,7 +175,7 @@ pub struct App { pub(crate) panel_state_overrides_active: bool, pub(crate) panel_state_overrides: PanelStateOverrides, - reflection: re_types_core::Reflection, + reflection: re_types_core::reflection::Reflection, } impl App { diff --git a/crates/re_viewer/src/app_state.rs b/crates/re_viewer/src/app_state.rs index 77ad93e8062d..c38e400eb3a8 100644 --- a/crates/re_viewer/src/app_state.rs +++ b/crates/re_viewer/src/app_state.rs @@ -126,7 +126,7 @@ impl AppState { render_ctx: &re_renderer::RenderContext, recording: &EntityDb, store_context: &StoreContext<'_>, - reflection: &re_types_core::Reflection, + reflection: &re_types_core::reflection::Reflection, component_ui_registry: &ComponentUiRegistry, space_view_class_registry: &SpaceViewClassRegistry, rx: &ReceiveSet, diff --git a/crates/re_viewer/src/reflection/mod.rs b/crates/re_viewer/src/reflection/mod.rs index 11b99fcdf98b..c889a1af897f 100644 --- a/crates/re_viewer/src/reflection/mod.rs +++ b/crates/re_viewer/src/reflection/mod.rs @@ -1,16 +1,18 @@ // DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/rust/reflection.rs -#![allow(unused_imports)] +#![allow(clippy::too_many_lines)] #![allow(clippy::wildcard_imports)] - +#![allow(unused_imports)] use re_types::blueprint::components::*; use re_types::components::*; use re_types_blueprint::blueprint::components::*; use re_types_core::components::*; use re_types_core::{ - external::arrow2, - reflection::{ComponentReflection, ComponentReflectionMap, Reflection}, - ComponentName, SerializationError, + reflection::{ + ArchetypeFieldReflection, ArchetypeReflection, ArchetypeReflectionMap, ComponentReflection, + ComponentReflectionMap, Reflection, + }, + ArchetypeName, ComponentName, Loggable, LoggableBatch as _, SerializationError, }; /// Generates reflection about all known components. @@ -18,10 +20,10 @@ use re_types_core::{ /// Call only once and reuse the results. pub fn generate_reflection() -> Result { - use ::re_types_core::{Loggable, LoggableBatch as _}; re_tracing::profile_function!(); Ok(Reflection { components: generate_component_reflection()?, + archetypes: generate_archetype_reflection(), }) } @@ -30,523 +32,654 @@ pub fn generate_reflection() -> Result { /// Call only once and reuse the results. fn generate_component_reflection() -> Result { - use ::re_types_core::{Loggable, LoggableBatch as _}; re_tracing::profile_function!(); - Ok( - ComponentReflectionMap::from_iter([ - ( - ::name(), - ComponentReflection { - docstring_md: "The active tab in a tabbed container.", - placeholder: Some(ActiveTab::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Whether the viewport layout is determined automatically.", - placeholder: Some(AutoLayout::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Whether or not space views should be created automatically.", - placeholder: Some(AutoSpaceViews::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "The type of the background in a view.", - placeholder: Some(BackgroundKind::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "The layout share of a column in the container.", - placeholder: Some(ColumnShare::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "The kind of a blueprint container (tabs, grid, …).", - placeholder: Some(ContainerKind::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "One of four 2D corners, typically used to align objects.", - placeholder: Some(Corner2D::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "How many columns a grid container should have.", - placeholder: Some(GridColumns::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "All the contents in the container.", - placeholder: Some(IncludedContent::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "The unique id of a space view, used to refer to views in containers.", - placeholder: Some(IncludedSpaceView::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Whether the entity can be interacted with.\n\nNon interactive components are still visible, but mouse interactions in the view are disabled.", - placeholder: Some(Interactive::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Indicate whether the range should be locked when zooming in on the data.\n\nDefault is `false`, i.e. zoom will change the visualized range.", - placeholder: Some(LockRangeDuringZoom::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Tri-state for panel controls.", - placeholder: Some(PanelState::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "An individual `QueryExpression` used to filter a set of `EntityPath`s.\n\nEach expression is either an inclusion or an exclusion expression.\nInclusions start with an optional `+` and exclusions must start with a `-`.\n\nMultiple expressions are combined together as part of `SpaceViewContents`.\n\nThe `/**` suffix matches the whole subtree, i.e. self and any child, recursively\n(`/world/**` matches both `/world` and `/world/car/driver`).\nOther uses of `*` are not (yet) supported.", - placeholder: Some(QueryExpression::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "The container that sits at the root of a viewport.", - placeholder: Some(RootContainer::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "The layout share of a row in the container.", - placeholder: Some(RowShare::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "The class of a `SpaceView`.", - placeholder: Some(SpaceViewClass::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Whether a space view is maximized.", - placeholder: Some(SpaceViewMaximized::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "The origin of a `SpaceView`.", - placeholder: Some(SpaceViewOrigin::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Show a slider for the index of some dimension of a slider.", - placeholder: Some(TensorDimensionIndexSlider::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Determines whether an image or texture should be scaled to fit the viewport.", - placeholder: Some(ViewFit::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Hash of a viewer recommendation.\n\nThe formation of this hash is considered an internal implementation detail of the viewer.", - placeholder: Some(ViewerRecommendationHash::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Whether the container, view, entity or instance is currently visible.", - placeholder: Some(Visible::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "The range of values on a given timeline that will be included in a view's query.\n\nRefer to `VisibleTimeRanges` archetype for more information.", - placeholder: Some(VisibleTimeRange::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Visual bounds in 2D space used for `Spatial2DView`.", - placeholder: Some(VisualBounds2D::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Configures a policy for aggregation of values.\n\nThis is used for lines in plots when the X axis distance of individual points goes below a single pixel,\ni.e. a single pixel covers more than one tick worth of data. It can greatly improve performance\n(and readability) in such situations as it prevents overdraw.", - placeholder: Some(AggregationPolicy::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "The `AnnotationContext` provides additional information on how to display entities.\n\nEntities can use `ClassId`s and `KeypointId`s to provide annotations, and\nthe labels and colors will be looked up in the appropriate\n`AnnotationContext`. We use the *first* annotation context we find in the\npath-hierarchy when searching up through the ancestors of a given entity\npath.", - placeholder: Some(AnnotationContext::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "The length of an axis in local units of the space.", - placeholder: Some(AxisLength::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A binary blob of data.", - placeholder: Some(Blob::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A 16-bit ID representing a type of semantic class.\n\nUsed to look up a [`crate::datatypes::ClassDescription`] within the [`crate::components::AnnotationContext`].", - placeholder: Some(ClassId::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Configures how a clear operation should behave - recursive or not.", - placeholder: Some(ClearIsRecursive::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "An RGBA color with unmultiplied/separate alpha, in sRGB gamma space with linear alpha.\n\nThe color is stored as a 32-bit integer, where the most significant\nbyte is `R` and the least significant byte is `A`.", - placeholder: Some(Color::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Colormap for mapping scalar values within a given range to a color.\n\nThis provides a number of popular pre-defined colormaps.\nIn the future, the Rerun Viewer will allow users to define their own colormaps,\nbut currently the Viewer is limited to the types defined here.", - placeholder: Some(Colormap::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A component indicating how long a meter is, expressed in native units.", - placeholder: Some(DepthMeter::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Spatially disconnect this entity from its parent.\n\nSpecifies that the entity path at which this is logged is spatially disconnected from its parent,\nmaking it impossible to transform the entity path into its parent's space and vice versa.\nIt *only* applies to space views that work with spatial transformations, i.e. 2D & 3D space views.\nThis is useful for specifying that a subgraph is independent of the rest of the scene.", - placeholder: Some(DisconnectedSpace::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Draw order used for the display order of 2D elements.\n\nHigher values are drawn on top of lower values.\nAn entity can have only a single draw order component.\nWithin an entity draw order is governed by the order of the components.\n\nDraw order for entities with the same draw order is generally undefined.", - placeholder: Some(DrawOrder::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "How much a primitive fills out the available space.\n\nUsed for instance to scale the points of the point cloud created from `DepthImage` projection.\nValid range is from 0 to max float although typically values above 1.0 are not useful\nDefaults to 1.0.", - placeholder: Some(FillRatio::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A gamma correction value to be used with a scalar value or color.\n\nUsed to adjust the gamma of a color or scalar value between 0 and 1 before rendering.\n`new_value = old_value ^ gamma`\n\nValid range is from 0 (excluding) to max float.\nDefaults to 1.0 unless otherwise specified.", - placeholder: Some(GammaCorrection::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Half-sizes (extents) of a 2D box along its local axis, starting at its local origin/center.\n\nThe box extends both in negative and positive direction along each axis.\nNegative sizes indicate that the box is flipped along the respective axis, but this has no effect on how it is displayed.", - placeholder: Some(HalfSizes2D::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Half-sizes (extents) of a 3D box along its local axis, starting at its local origin/center.\n\nThe box extends both in negative and positive direction along each axis.\nNegative sizes indicate that the box is flipped along the respective axis, but this has no effect on how it is displayed.", - placeholder: Some(HalfSizes3D::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "The distance from the camera origin to the image plane when the projection is shown in a 3D viewer.\n\nThis is only used for visualization purposes, and does not affect the projection itself.", - placeholder: Some(ImagePlaneDistance::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A 16-bit ID representing a type of semantic keypoint within a class.\n\n`KeypointId`s are only meaningful within the context of a [`crate::datatypes::ClassDescription`].\n\nUsed to look up an [`crate::datatypes::AnnotationInfo`] for a Keypoint within the [`crate::components::AnnotationContext`].", - placeholder: Some(KeypointId::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A line strip in 2D space.\n\nA line strip is a list of points connected by line segments. It can be used to draw\napproximations of smooth curves.\n\nThe points will be connected in order, like so:\n```text\n 2------3 5\n / \\ /\n0----1 \\ /\n 4\n```", - placeholder: Some(LineStrip2D::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A line strip in 3D space.\n\nA line strip is a list of points connected by line segments. It can be used to draw\napproximations of smooth curves.\n\nThe points will be connected in order, like so:\n```text\n 2------3 5\n / \\ /\n0----1 \\ /\n 4\n```", - placeholder: Some(LineStrip3D::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Filter used when magnifying an image/texture such that a single pixel/texel is displayed as multiple pixels on screen.", - placeholder: Some(MagnificationFilter::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Shape of a marker.", - placeholder: Some(MarkerShape::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Size of a marker in UI points.", - placeholder: Some(MarkerSize::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Material properties of a mesh.", - placeholder: Some(Material::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A standardized media type (RFC2046, formerly known as MIME types), encoded as a utf8 string.\n\nThe complete reference of officially registered media types is maintained by the IANA and can be\nconsulted at .", - placeholder: Some(MediaType::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A display name, typically for an entity or a item like a plot series.", - placeholder: Some(Name::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "An out-of-tree affine transform between two 3D spaces, represented in a given direction.\n\n\"Out-of-tree\" means that the transform only affects its own entity: children don't inherit from it.", - placeholder: Some(OutOfTreeTransform3D::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Camera projection, from image coordinates to view coordinates.\n\nChild from parent.\nImage coordinates from camera view coordinates.\n\nExample:\n```text\n1496.1 0.0 980.5\n 0.0 1496.1 744.5\n 0.0 0.0 1.0\n```", - placeholder: Some(PinholeProjection::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A position in 2D space.", - placeholder: Some(Position2D::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A position in 3D space.", - placeholder: Some(Position3D::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A Radius component.", - placeholder: Some(Radius::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A 1D range, specifying a lower and upper bound.", - placeholder: Some(Range1D::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Pixel resolution width & height, e.g. of a camera sensor.\n\nTypically in integer units, but for some use cases floating point may be used.", - placeholder: Some(Resolution::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A 3D rotation, represented either by a quaternion or a rotation around axis.", - placeholder: Some(Rotation3D::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A double-precision scalar.\n\nUsed for time series plots.", - placeholder: Some(Scalar::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "The width of a stroke specified in UI points.", - placeholder: Some(StrokeWidth::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A multi-dimensional `Tensor` of data.\n\nThe number of dimensions and their respective lengths is specified by the `shape` field.\nThe dimensions are ordered from outermost to innermost. For example, in the common case of\na 2D RGB Image, the shape would be `[height, width, channel]`.\n\nThese dimensions are combined with an index to look up values from the `buffer` field,\nwhich stores a contiguous array of typed values.\n\nNote that the buffer may be encoded in a compressed format such as `jpeg` or\nin a format with downsampled chroma, such as NV12 or YUY2.\nFor file formats, the shape is used as a hint, for chroma downsampled format\nthe shape has to be the shape of the decoded image.", - placeholder: Some(TensorData::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Specifies a concrete index on a tensor dimension.", - placeholder: Some( - TensorDimensionIndexSelection::default().to_arrow()?, - ), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Specifies which dimension to use for height.", - placeholder: Some(TensorHeightDimension::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "Specifies which dimension to use for width.", - placeholder: Some(TensorWidthDimension::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A 2D texture UV coordinate.\n\nTexture coordinates specify a position on a 2D texture.\nA range from 0-1 covers the entire texture in the respective dimension.\nUnless configured otherwise, the texture repeats outside of this range.\nRerun uses top-left as the origin for UV coordinates.\n\n 0 U 1\n0 + --------- →\n | .\nV | .\n | .\n1 ↓ . . . . . .\n\nThis is the same convention as in Vulkan/Metal/DX12/WebGPU, but (!) unlike OpenGL,\nwhich places the origin at the bottom-left.", - placeholder: Some(Texcoord2D::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A string of text, e.g. for labels and text documents.", - placeholder: Some(Text::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "The severity level of a text log message.\n\nRecommended to be one of:\n* `\"CRITICAL\"`\n* `\"ERROR\"`\n* `\"WARN\"`\n* `\"INFO\"`\n* `\"DEBUG\"`\n* `\"TRACE\"`", - placeholder: Some(TextLogLevel::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "An affine transform between two 3D spaces, represented in a given direction.", - placeholder: Some(Transform3D::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "The three indices of a triangle mesh.", - placeholder: Some(TriangleIndices::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A vector in 2D space.", - placeholder: Some(Vector2D::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "A vector in 3D space.", - placeholder: Some(Vector3D::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "How we interpret the coordinate system of an entity/space.\n\nFor instance: What is \"up\"? What does the Z axis mean? Is this right-handed or left-handed?\n\nThe three coordinates are always ordered as [x, y, z].\n\nFor example [Right, Down, Forward] means that the X axis points to the right, the Y axis points\ndown, and the Z axis points forward.\n\nThe following constants are used to represent the different directions:\n * Up = 1\n * Down = 2\n * Right = 3\n * Left = 4\n * Forward = 5\n * Back = 6", - placeholder: Some(ViewCoordinates::default().to_arrow()?), - }, - ), - ( - ::name(), - ComponentReflection { - docstring_md: "The name of a visualizer.", - placeholder: Some(VisualizerOverrides::default().to_arrow()?), - }, - ), - ]), - ) + let array = [ + ( + ::name(), + ComponentReflection { + docstring_md: "The active tab in a tabbed container.", + placeholder: Some(ActiveTab::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Whether the viewport layout is determined automatically.", + placeholder: Some(AutoLayout::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Whether or not space views should be created automatically.", + placeholder: Some(AutoSpaceViews::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "The type of the background in a view.", + placeholder: Some(BackgroundKind::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "The layout share of a column in the container.", + placeholder: Some(ColumnShare::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "The kind of a blueprint container (tabs, grid, …).", + placeholder: Some(ContainerKind::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "One of four 2D corners, typically used to align objects.", + placeholder: Some(Corner2D::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "How many columns a grid container should have.", + placeholder: Some(GridColumns::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "All the contents in the container.", + placeholder: Some(IncludedContent::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "The unique id of a space view, used to refer to views in containers.", + placeholder: Some(IncludedSpaceView::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Whether the entity can be interacted with.\n\nNon interactive components are still visible, but mouse interactions in the view are disabled.", + placeholder: Some(Interactive::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Indicate whether the range should be locked when zooming in on the data.\n\nDefault is `false`, i.e. zoom will change the visualized range.", + placeholder: Some(LockRangeDuringZoom::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Tri-state for panel controls.", + placeholder: Some(PanelState::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "An individual `QueryExpression` used to filter a set of `EntityPath`s.\n\nEach expression is either an inclusion or an exclusion expression.\nInclusions start with an optional `+` and exclusions must start with a `-`.\n\nMultiple expressions are combined together as part of `SpaceViewContents`.\n\nThe `/**` suffix matches the whole subtree, i.e. self and any child, recursively\n(`/world/**` matches both `/world` and `/world/car/driver`).\nOther uses of `*` are not (yet) supported.", + placeholder: Some(QueryExpression::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "The container that sits at the root of a viewport.", + placeholder: Some(RootContainer::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "The layout share of a row in the container.", + placeholder: Some(RowShare::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "The class of a `SpaceView`.", + placeholder: Some(SpaceViewClass::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Whether a space view is maximized.", + placeholder: Some(SpaceViewMaximized::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "The origin of a `SpaceView`.", + placeholder: Some(SpaceViewOrigin::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Show a slider for the index of some dimension of a slider.", + placeholder: Some(TensorDimensionIndexSlider::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Determines whether an image or texture should be scaled to fit the viewport.", + placeholder: Some(ViewFit::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Hash of a viewer recommendation.\n\nThe formation of this hash is considered an internal implementation detail of the viewer.", + placeholder: Some(ViewerRecommendationHash::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Whether the container, view, entity or instance is currently visible.", + placeholder: Some(Visible::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "The range of values on a given timeline that will be included in a view's query.\n\nRefer to `VisibleTimeRanges` archetype for more information.", + placeholder: Some(VisibleTimeRange::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Visual bounds in 2D space used for `Spatial2DView`.", + placeholder: Some(VisualBounds2D::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Configures a policy for aggregation of values.\n\nThis is used for lines in plots when the X axis distance of individual points goes below a single pixel,\ni.e. a single pixel covers more than one tick worth of data. It can greatly improve performance\n(and readability) in such situations as it prevents overdraw.", + placeholder: Some(AggregationPolicy::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "The `AnnotationContext` provides additional information on how to display entities.\n\nEntities can use `ClassId`s and `KeypointId`s to provide annotations, and\nthe labels and colors will be looked up in the appropriate\n`AnnotationContext`. We use the *first* annotation context we find in the\npath-hierarchy when searching up through the ancestors of a given entity\npath.", + placeholder: Some(AnnotationContext::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "The length of an axis in local units of the space.", + placeholder: Some(AxisLength::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A binary blob of data.", + placeholder: Some(Blob::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A 16-bit ID representing a type of semantic class.\n\nUsed to look up a [`crate::datatypes::ClassDescription`] within the [`crate::components::AnnotationContext`].", + placeholder: Some(ClassId::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Configures how a clear operation should behave - recursive or not.", + placeholder: Some(ClearIsRecursive::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "An RGBA color with unmultiplied/separate alpha, in sRGB gamma space with linear alpha.\n\nThe color is stored as a 32-bit integer, where the most significant\nbyte is `R` and the least significant byte is `A`.", + placeholder: Some(Color::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Colormap for mapping scalar values within a given range to a color.\n\nThis provides a number of popular pre-defined colormaps.\nIn the future, the Rerun Viewer will allow users to define their own colormaps,\nbut currently the Viewer is limited to the types defined here.", + placeholder: Some(Colormap::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A component indicating how long a meter is, expressed in native units.", + placeholder: Some(DepthMeter::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Spatially disconnect this entity from its parent.\n\nSpecifies that the entity path at which this is logged is spatially disconnected from its parent,\nmaking it impossible to transform the entity path into its parent's space and vice versa.\nIt *only* applies to space views that work with spatial transformations, i.e. 2D & 3D space views.\nThis is useful for specifying that a subgraph is independent of the rest of the scene.", + placeholder: Some(DisconnectedSpace::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Draw order used for the display order of 2D elements.\n\nHigher values are drawn on top of lower values.\nAn entity can have only a single draw order component.\nWithin an entity draw order is governed by the order of the components.\n\nDraw order for entities with the same draw order is generally undefined.", + placeholder: Some(DrawOrder::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "How much a primitive fills out the available space.\n\nUsed for instance to scale the points of the point cloud created from `DepthImage` projection.\nValid range is from 0 to max float although typically values above 1.0 are not useful\nDefaults to 1.0.", + placeholder: Some(FillRatio::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A gamma correction value to be used with a scalar value or color.\n\nUsed to adjust the gamma of a color or scalar value between 0 and 1 before rendering.\n`new_value = old_value ^ gamma`\n\nValid range is from 0 (excluding) to max float.\nDefaults to 1.0 unless otherwise specified.", + placeholder: Some(GammaCorrection::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Half-sizes (extents) of a 2D box along its local axis, starting at its local origin/center.\n\nThe box extends both in negative and positive direction along each axis.\nNegative sizes indicate that the box is flipped along the respective axis, but this has no effect on how it is displayed.", + placeholder: Some(HalfSizes2D::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Half-sizes (extents) of a 3D box along its local axis, starting at its local origin/center.\n\nThe box extends both in negative and positive direction along each axis.\nNegative sizes indicate that the box is flipped along the respective axis, but this has no effect on how it is displayed.", + placeholder: Some(HalfSizes3D::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "The distance from the camera origin to the image plane when the projection is shown in a 3D viewer.\n\nThis is only used for visualization purposes, and does not affect the projection itself.", + placeholder: Some(ImagePlaneDistance::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A 16-bit ID representing a type of semantic keypoint within a class.\n\n`KeypointId`s are only meaningful within the context of a [`crate::datatypes::ClassDescription`].\n\nUsed to look up an [`crate::datatypes::AnnotationInfo`] for a Keypoint within the [`crate::components::AnnotationContext`].", + placeholder: Some(KeypointId::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A line strip in 2D space.\n\nA line strip is a list of points connected by line segments. It can be used to draw\napproximations of smooth curves.\n\nThe points will be connected in order, like so:\n```text\n 2------3 5\n / \\ /\n0----1 \\ /\n 4\n```", + placeholder: Some(LineStrip2D::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A line strip in 3D space.\n\nA line strip is a list of points connected by line segments. It can be used to draw\napproximations of smooth curves.\n\nThe points will be connected in order, like so:\n```text\n 2------3 5\n / \\ /\n0----1 \\ /\n 4\n```", + placeholder: Some(LineStrip3D::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Filter used when magnifying an image/texture such that a single pixel/texel is displayed as multiple pixels on screen.", + placeholder: Some(MagnificationFilter::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Shape of a marker.", + placeholder: Some(MarkerShape::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Size of a marker in UI points.", + placeholder: Some(MarkerSize::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Material properties of a mesh.", + placeholder: Some(Material::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A standardized media type (RFC2046, formerly known as MIME types), encoded as a utf8 string.\n\nThe complete reference of officially registered media types is maintained by the IANA and can be\nconsulted at .", + placeholder: Some(MediaType::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A display name, typically for an entity or a item like a plot series.", + placeholder: Some(Name::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "An out-of-tree affine transform between two 3D spaces, represented in a given direction.\n\n\"Out-of-tree\" means that the transform only affects its own entity: children don't inherit from it.", + placeholder: Some(OutOfTreeTransform3D::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Camera projection, from image coordinates to view coordinates.\n\nChild from parent.\nImage coordinates from camera view coordinates.\n\nExample:\n```text\n1496.1 0.0 980.5\n 0.0 1496.1 744.5\n 0.0 0.0 1.0\n```", + placeholder: Some(PinholeProjection::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A position in 2D space.", + placeholder: Some(Position2D::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A position in 3D space.", + placeholder: Some(Position3D::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A Radius component.", + placeholder: Some(Radius::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A 1D range, specifying a lower and upper bound.", + placeholder: Some(Range1D::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Pixel resolution width & height, e.g. of a camera sensor.\n\nTypically in integer units, but for some use cases floating point may be used.", + placeholder: Some(Resolution::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A 3D rotation, represented either by a quaternion or a rotation around axis.", + placeholder: Some(Rotation3D::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A double-precision scalar.\n\nUsed for time series plots.", + placeholder: Some(Scalar::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "The width of a stroke specified in UI points.", + placeholder: Some(StrokeWidth::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A multi-dimensional `Tensor` of data.\n\nThe number of dimensions and their respective lengths is specified by the `shape` field.\nThe dimensions are ordered from outermost to innermost. For example, in the common case of\na 2D RGB Image, the shape would be `[height, width, channel]`.\n\nThese dimensions are combined with an index to look up values from the `buffer` field,\nwhich stores a contiguous array of typed values.\n\nNote that the buffer may be encoded in a compressed format such as `jpeg` or\nin a format with downsampled chroma, such as NV12 or YUY2.\nFor file formats, the shape is used as a hint, for chroma downsampled format\nthe shape has to be the shape of the decoded image.", + placeholder: Some(TensorData::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Specifies a concrete index on a tensor dimension.", + placeholder: Some(TensorDimensionIndexSelection::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Specifies which dimension to use for height.", + placeholder: Some(TensorHeightDimension::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "Specifies which dimension to use for width.", + placeholder: Some(TensorWidthDimension::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A 2D texture UV coordinate.\n\nTexture coordinates specify a position on a 2D texture.\nA range from 0-1 covers the entire texture in the respective dimension.\nUnless configured otherwise, the texture repeats outside of this range.\nRerun uses top-left as the origin for UV coordinates.\n\n 0 U 1\n0 + --------- →\n | .\nV | .\n | .\n1 ↓ . . . . . .\n\nThis is the same convention as in Vulkan/Metal/DX12/WebGPU, but (!) unlike OpenGL,\nwhich places the origin at the bottom-left.", + placeholder: Some(Texcoord2D::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A string of text, e.g. for labels and text documents.", + placeholder: Some(Text::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "The severity level of a text log message.\n\nRecommended to be one of:\n* `\"CRITICAL\"`\n* `\"ERROR\"`\n* `\"WARN\"`\n* `\"INFO\"`\n* `\"DEBUG\"`\n* `\"TRACE\"`", + placeholder: Some(TextLogLevel::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "An affine transform between two 3D spaces, represented in a given direction.", + placeholder: Some(Transform3D::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "The three indices of a triangle mesh.", + placeholder: Some(TriangleIndices::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A vector in 2D space.", + placeholder: Some(Vector2D::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "A vector in 3D space.", + placeholder: Some(Vector3D::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "How we interpret the coordinate system of an entity/space.\n\nFor instance: What is \"up\"? What does the Z axis mean? Is this right-handed or left-handed?\n\nThe three coordinates are always ordered as [x, y, z].\n\nFor example [Right, Down, Forward] means that the X axis points to the right, the Y axis points\ndown, and the Z axis points forward.\n\nThe following constants are used to represent the different directions:\n * Up = 1\n * Down = 2\n * Right = 3\n * Left = 4\n * Forward = 5\n * Back = 6", + placeholder: Some(ViewCoordinates::default().to_arrow()?), + }, + ), + ( + ::name(), + ComponentReflection { + docstring_md: "The name of a visualizer.", + placeholder: Some(VisualizerOverrides::default().to_arrow()?), + }, + ), + ]; + Ok(ComponentReflectionMap::from_iter(array)) +} + +/// Generates reflection about all known archetypes. +/// +/// Call only once and reuse the results. + +fn generate_archetype_reflection() -> ArchetypeReflectionMap { + re_tracing::profile_function!(); + let array = [ + ( + ArchetypeName::new("rerun.blueprint.archetypes.Background"), + ArchetypeReflection { + display_name: "Background", + docstring_md: "Configuration for the background of a view.", + fields: vec![ + ArchetypeFieldReflection { component_name : + "rerun.blueprint.components.BackgroundKind".into(), display_name : + "Kind", docstring_md : "The type of the background.", }, + ArchetypeFieldReflection { component_name : "rerun.components.Color" + .into(), display_name : "Color", docstring_md : + "Color used for the `SolidColor` background type.", }, + ], + }, + ), + ( + ArchetypeName::new("rerun.blueprint.archetypes.PlotLegend"), + ArchetypeReflection { + display_name: "Plot legend", + docstring_md: "Configuration for the legend of a plot.", + fields: vec![ + ArchetypeFieldReflection { component_name : + "rerun.blueprint.components.Corner2D".into(), display_name : + "Corner", docstring_md : + "To what corner the legend is aligned.\n\nDefaults to the right bottom corner.", + }, ArchetypeFieldReflection { component_name : + "rerun.blueprint.components.Visible".into(), display_name : + "Visible", docstring_md : + "Whether the legend is shown at all.\n\nTrue by default.", }, + ], + }, + ), + ( + ArchetypeName::new("rerun.blueprint.archetypes.ScalarAxis"), + ArchetypeReflection { + display_name: "Scalar axis", + docstring_md: "Configuration for the scalar axis of a plot.", + fields: vec![ + ArchetypeFieldReflection { component_name : + "rerun.components.Range1D".into(), display_name : "Range", + docstring_md : + "The range of the axis.\n\nIf unset, the range well be automatically determined based on the queried data.", + }, ArchetypeFieldReflection { component_name : + "rerun.blueprint.components.LockRangeDuringZoom".into(), display_name + : "Zoom lock", docstring_md : + "If enabled, the Y axis range will remain locked to the specified range when zooming.", + }, + ], + }, + ), + ( + ArchetypeName::new("rerun.blueprint.archetypes.TensorScalarMapping"), + ArchetypeReflection { + display_name: "Tensor scalar mapping", + docstring_md: "Configures how tensor scalars are mapped to color.", + fields: vec![ + ArchetypeFieldReflection { component_name : + "rerun.components.MagnificationFilter".into(), display_name : + "Mag filter", docstring_md : + "Filter used when zooming in on the tensor.\n\nNote that the filter is applied to the scalar values *before* they are mapped to color.", + }, ArchetypeFieldReflection { component_name : + "rerun.components.Colormap".into(), display_name : "Colormap", + docstring_md : "How scalar values map to colors.", }, + ArchetypeFieldReflection { component_name : + "rerun.components.GammaCorrection".into(), display_name : "Gamma", + docstring_md : + "Gamma exponent applied to normalized values before mapping to color.\n\nRaises the normalized values to the power of this value before mapping to color.\nActs like an inverse brightness. Defaults to 1.0.", + }, + ], + }, + ), + ( + ArchetypeName::new("rerun.blueprint.archetypes.TensorSliceSelection"), + ArchetypeReflection { + display_name: "Tensor slice selection", + docstring_md: "Specifies a 2D slice of a tensor.", + fields: vec![ + ArchetypeFieldReflection { component_name : + "rerun.components.TensorWidthDimension".into(), display_name : + "Width", docstring_md : + "Which dimension to map to width.\n\nIf not specified, the height will be determined automatically based on the name and index of the dimension.", + }, ArchetypeFieldReflection { component_name : + "rerun.components.TensorHeightDimension".into(), display_name : + "Height", docstring_md : + "Which dimension to map to height.\n\nIf not specified, the height will be determined automatically based on the name and index of the dimension.", + }, ArchetypeFieldReflection { component_name : + "rerun.components.TensorDimensionIndexSelection".into(), display_name + : "Indices", docstring_md : + "Selected indices for all other dimensions.\n\nIf any of the here listed dimensions is equal to `width` or `height`, it will be ignored.", + }, ArchetypeFieldReflection { component_name : + "rerun.blueprint.components.TensorDimensionIndexSlider".into(), + display_name : "Slider", docstring_md : + "Any dimension listed here will have a slider for the index.\n\nEdits to the sliders will directly manipulate dimensions on the `indices` list.\nIf any of the here listed dimensions is equal to `width` or `height`, it will be ignored.\nIf not specified, adds slides for any dimension in `indices`.", + }, + ], + }, + ), + ( + ArchetypeName::new("rerun.blueprint.archetypes.TensorViewFit"), + ArchetypeReflection { + display_name: "Tensor view fit", + docstring_md: "Configures how a selected tensor slice is shown on screen.", + fields: vec![ + ArchetypeFieldReflection { component_name : + "rerun.blueprint.components.ViewFit".into(), display_name : + "Scaling", docstring_md : "How the image is scaled to fit the view.", + }, + ], + }, + ), + ( + ArchetypeName::new("rerun.blueprint.archetypes.VisualBounds2D"), + ArchetypeReflection { + display_name: "Visual bounds 2D", + docstring_md: "Controls the visual bounds of a 2D view.\n\nEverything within these bounds are guaranteed to be visible.\nSomethings outside of these bounds may also be visible due to letterboxing.\n\nIf no visual bounds are set, it will be determined automatically,\nbased on the bounding-box of the data or other camera information present in the view.", + fields: vec![ + ArchetypeFieldReflection { component_name : + "rerun.blueprint.components.VisualBounds2D".into(), display_name : + "Range", docstring_md : + "Controls the visible range of a 2D view.\n\nUse this to control pan & zoom of the view.", + }, + ], + }, + ), + ]; + ArchetypeReflectionMap::from_iter(array) } diff --git a/crates/re_viewer_context/src/viewer_context.rs b/crates/re_viewer_context/src/viewer_context.rs index e2416a9edaea..064037f0328f 100644 --- a/crates/re_viewer_context/src/viewer_context.rs +++ b/crates/re_viewer_context/src/viewer_context.rs @@ -27,7 +27,7 @@ pub struct ViewerContext<'a> { /// /// ⚠️ In almost all cases you should not use this directly, but instead use the currently best fitting /// [`crate::ComponentFallbackProvider`] and call [`crate::ComponentFallbackProvider::fallback_for`] instead. - pub reflection: &'a re_types_core::Reflection, + pub reflection: &'a re_types_core::reflection::Reflection, /// How to display components. pub component_ui_registry: &'a ComponentUiRegistry,