From 9c1ed5105e1b809f4a0e8e29579d75eb2ed43b40 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 10 Jan 2025 20:09:30 +0100 Subject: [PATCH 01/57] Fix some clippy 1.84.0 lints (#8655) Just taking the new clippy for a spin to see what I can learn! --- crates/build/re_build_tools/src/hashing.rs | 2 +- .../build/re_types_builder/src/codegen/cpp/mod.rs | 2 +- .../build/re_types_builder/src/codegen/rust/api.rs | 4 ++-- .../src/codegen/rust/deserializer.rs | 4 ++-- .../re_types_builder/src/codegen/rust/reflection.rs | 4 ++-- .../re_types_builder/src/codegen/rust/serializer.rs | 2 +- crates/build/re_types_builder/src/docs.rs | 2 +- crates/store/re_chunk/src/arrow2_util.rs | 4 ++-- crates/store/re_chunk/src/arrow_util.rs | 2 +- crates/store/re_chunk/src/chunk.rs | 2 +- crates/store/re_chunk/src/shuffle.rs | 4 ++-- crates/store/re_chunk_store/src/dataframe.rs | 2 +- crates/store/re_chunk_store/src/query.rs | 8 +++----- crates/store/re_chunk_store/src/store.rs | 4 +--- crates/store/re_chunk_store/src/writes.rs | 2 +- crates/store/re_data_loader/src/loader_external.rs | 2 +- crates/store/re_entity_db/src/entity_db.rs | 13 +++++-------- crates/store/re_sdk_comms/src/tcp_client.rs | 2 +- crates/store/re_types_core/src/loggable_batch.rs | 6 +++--- crates/top/rerun/src/commands/entrypoint.rs | 4 +--- crates/utils/re_byte_size/src/std_sizes.rs | 2 +- .../viewer/re_blueprint_tree/src/blueprint_tree.rs | 4 ++-- crates/viewer/re_component_ui/src/radius.rs | 2 +- crates/viewer/re_data_ui/src/app_id.rs | 2 +- crates/viewer/re_renderer/build.rs | 2 +- crates/viewer/re_renderer_examples/multiview.rs | 2 +- crates/viewer/re_selection_panel/src/defaults_ui.rs | 2 +- .../re_selection_panel/src/visible_time_range_ui.rs | 4 ++-- crates/viewer/re_time_panel/src/lib.rs | 5 ++--- .../viewer/re_time_panel/src/time_selection_ui.rs | 2 +- crates/viewer/re_view/src/results_ext.rs | 2 +- crates/viewer/re_view_bar_chart/src/view_class.rs | 2 +- .../re_view_dataframe/src/view_query/blueprint.rs | 2 +- crates/viewer/re_view_map/src/map_view.rs | 5 +---- .../re_view_spatial/src/scene_bounding_boxes.rs | 2 +- .../src/transform_component_tracker.rs | 2 +- crates/viewer/re_view_spatial/src/ui_3d.rs | 4 ++-- .../re_view_spatial/src/visualizers/depth_images.rs | 2 +- .../src/visualizers/encoded_image.rs | 2 +- .../viewer/re_view_tensor/src/dimension_mapping.rs | 4 ++-- .../re_view_tensor/src/tensor_dimension_mapper.rs | 2 +- crates/viewer/re_view_tensor/src/view_class.rs | 2 +- .../src/line_visualizer_system.rs | 2 +- crates/viewer/re_view_time_series/src/util.rs | 2 +- crates/viewer/re_view_time_series/src/view_class.rs | 2 +- crates/viewer/re_viewer/src/ui/rerun_menu.rs | 2 +- .../viewer/re_viewer_context/src/query_context.rs | 2 +- .../viewer/re_viewer_context/src/view/view_class.rs | 2 +- crates/viewer/re_viewport/src/viewport_ui.rs | 4 ++-- .../re_viewport_blueprint/src/view_properties.rs | 8 ++++---- .../re_viewport_blueprint/src/viewport_blueprint.rs | 4 ++-- rerun_py/src/python_bridge.rs | 4 ++-- 52 files changed, 76 insertions(+), 89 deletions(-) diff --git a/crates/build/re_build_tools/src/hashing.rs b/crates/build/re_build_tools/src/hashing.rs index f4d03203fc3c..60807cd063d6 100644 --- a/crates/build/re_build_tools/src/hashing.rs +++ b/crates/build/re_build_tools/src/hashing.rs @@ -30,7 +30,7 @@ pub fn iter_dir<'a>( extensions.iter().any(|ext| { entry .extension() - .map_or(false, |ext2| *ext == ext2.to_string_lossy()) + .is_some_and(|ext2| *ext == ext2.to_string_lossy()) }) }) }) diff --git a/crates/build/re_types_builder/src/codegen/cpp/mod.rs b/crates/build/re_types_builder/src/codegen/cpp/mod.rs index f8a3a8a82d28..d363c49b6d57 100644 --- a/crates/build/re_types_builder/src/codegen/cpp/mod.rs +++ b/crates/build/re_types_builder/src/codegen/cpp/mod.rs @@ -575,7 +575,7 @@ impl QuotedObject { .typ .fqname() .and_then(|fqname| objects.get(fqname)) - .map_or(false, |obj| obj.deprecation_notice().is_some()) + .is_some_and(|obj| obj.deprecation_notice().is_some()) }); let (deprecation_ignore_start, deprecation_ignore_end) = quote_deprecation_ignore_start_and_end( diff --git a/crates/build/re_types_builder/src/codegen/rust/api.rs b/crates/build/re_types_builder/src/codegen/rust/api.rs index 1265b746daf8..3807c76364f8 100644 --- a/crates/build/re_types_builder/src/codegen/rust/api.rs +++ b/crates/build/re_types_builder/src/codegen/rust/api.rs @@ -884,10 +884,10 @@ fn quote_trait_impls_for_datatype_or_component( let from_arrow_body = if let Some(forwarded_type) = forwarded_type.as_ref() { let is_pod = obj .try_get_attr::(ATTR_RUST_DERIVE) - .map_or(false, |d| d.contains("bytemuck::Pod")) + .is_some_and(|d| d.contains("bytemuck::Pod")) || obj .try_get_attr::(ATTR_RUST_DERIVE_ONLY) - .map_or(false, |d| d.contains("bytemuck::Pod")); + .is_some_and(|d| d.contains("bytemuck::Pod")); if is_pod { quote! { #forwarded_type::from_arrow(arrow_data).map(bytemuck::cast_vec) diff --git a/crates/build/re_types_builder/src/codegen/rust/deserializer.rs b/crates/build/re_types_builder/src/codegen/rust/deserializer.rs index 58be66308a6d..aa5c6e61ff40 100644 --- a/crates/build/re_types_builder/src/codegen/rust/deserializer.rs +++ b/crates/build/re_types_builder/src/codegen/rust/deserializer.rs @@ -507,7 +507,7 @@ fn quote_arrow_field_deserializer( // If the inner object is an enum, then dispatch to its deserializer. if let DataType::Extension(fqname, _, _) = datatype { - if objects.get(fqname).map_or(false, |obj| obj.is_enum()) { + if objects.get(fqname).is_some_and(|obj| obj.is_enum()) { let fqname_use = quote_fqname_as_type_path(fqname); return quote!(#fqname_use::from_arrow_opt(#data_src).with_context(#obj_field_fqname)?.into_iter()); } @@ -912,7 +912,7 @@ fn quote_iterator_transparency( } else { None }; - let inner_is_arrow_transparent = inner_obj.map_or(false, |obj| obj.datatype.is_none()); + let inner_is_arrow_transparent = inner_obj.is_some_and(|obj| obj.datatype.is_none()); if inner_is_arrow_transparent { let inner_obj = inner_obj.as_ref().unwrap(); diff --git a/crates/build/re_types_builder/src/codegen/rust/reflection.rs b/crates/build/re_types_builder/src/codegen/rust/reflection.rs index 8c86c4e37641..0afa9a880c8e 100644 --- a/crates/build/re_types_builder/src/codegen/rust/reflection.rs +++ b/crates/build/re_types_builder/src/codegen/rust/reflection.rs @@ -128,11 +128,11 @@ fn generate_component_reflection( || obj .try_get_attr::(ATTR_RUST_DERIVE_ONLY) .or_else(|| obj.try_get_attr::(ATTR_RUST_DERIVE)) - .map_or(false, |derives| derives.contains("Default")); + .is_some_and(|derives| derives.contains("Default")); let has_custom_default_impl = extension_contents_for_fqname .get(&obj.fqname) - .map_or(false, |contents| { + .is_some_and(|contents| { contents.contains(&format!("impl Default for {}", &obj.name)) || contents.contains(&format!("impl Default for super::{}", &obj.name)) }); diff --git a/crates/build/re_types_builder/src/codegen/rust/serializer.rs b/crates/build/re_types_builder/src/codegen/rust/serializer.rs index 6156c4895bc4..d5208b9bf543 100644 --- a/crates/build/re_types_builder/src/codegen/rust/serializer.rs +++ b/crates/build/re_types_builder/src/codegen/rust/serializer.rs @@ -496,7 +496,7 @@ fn quote_arrow_field_serializer( } } - let inner_is_arrow_transparent = inner_obj.map_or(false, |obj| obj.datatype.is_none()); + let inner_is_arrow_transparent = inner_obj.is_some_and(|obj| obj.datatype.is_none()); match datatype.to_logical_type() { DataType::Boolean diff --git a/crates/build/re_types_builder/src/docs.rs b/crates/build/re_types_builder/src/docs.rs index 4b8f6bae8d6e..79ee7869d521 100644 --- a/crates/build/re_types_builder/src/docs.rs +++ b/crates/build/re_types_builder/src/docs.rs @@ -255,7 +255,7 @@ mod doclink_translation { if tokens .peek() - .map_or(false, |next_token| next_token.starts_with('(')) + .is_some_and(|next_token| next_token.starts_with('(')) { // We are at the `)[` boundary of a markdown link, e.g. "[Rerun](https://rerun.io)", // so this is not a rerun doclink after all. diff --git a/crates/store/re_chunk/src/arrow2_util.rs b/crates/store/re_chunk/src/arrow2_util.rs index c8e64b143c03..c6e3696cc412 100644 --- a/crates/store/re_chunk/src/arrow2_util.rs +++ b/crates/store/re_chunk/src/arrow2_util.rs @@ -25,7 +25,7 @@ pub fn is_list_array_semantically_empty(list_array: &ArrowListArray) -> boo let is_all_nulls = || { list_array .validity() - .map_or(false, |bitmap| bitmap.unset_bits() == list_array.len()) + .is_some_and(|bitmap| bitmap.unset_bits() == list_array.len()) }; let is_all_empties = || list_array.offsets().lengths().all(|len| len == 0); @@ -192,7 +192,7 @@ pub fn sparse_list_array_to_dense_list_array( let is_empty = list_array .validity() - .map_or(false, |validity| validity.is_empty()); + .is_some_and(|validity| validity.is_empty()); if is_empty { return list_array.clone(); } diff --git a/crates/store/re_chunk/src/arrow_util.rs b/crates/store/re_chunk/src/arrow_util.rs index 15ed476e7a51..9ff23565e963 100644 --- a/crates/store/re_chunk/src/arrow_util.rs +++ b/crates/store/re_chunk/src/arrow_util.rs @@ -86,7 +86,7 @@ pub fn sparse_list_array_to_dense_list_array(list_array: &ListArray) -> ListArra return list_array.clone(); } - let is_empty = list_array.nulls().map_or(false, |nulls| nulls.is_empty()); + let is_empty = list_array.nulls().is_some_and(|nulls| nulls.is_empty()); if is_empty { return list_array.clone(); } diff --git a/crates/store/re_chunk/src/chunk.rs b/crates/store/re_chunk/src/chunk.rs index 7380f9ae2810..cbbaacc7b7d9 100644 --- a/crates/store/re_chunk/src/chunk.rs +++ b/crates/store/re_chunk/src/chunk.rs @@ -1581,7 +1581,7 @@ impl Chunk { let validity_is_empty = list_array .validity() - .map_or(false, |validity| validity.is_empty()); + .is_some_and(|validity| validity.is_empty()); if !self.is_empty() && validity_is_empty { return Err(ChunkError::Malformed { reason: format!( diff --git a/crates/store/re_chunk/src/shuffle.rs b/crates/store/re_chunk/src/shuffle.rs index ba9639898856..f90479c7c541 100644 --- a/crates/store/re_chunk/src/shuffle.rs +++ b/crates/store/re_chunk/src/shuffle.rs @@ -55,7 +55,7 @@ impl Chunk { || self .timelines .get(timeline) - .map_or(false, |time_column| time_column.is_sorted()) + .is_some_and(|time_column| time_column.is_sorted()) } /// For debugging purposes. @@ -66,7 +66,7 @@ impl Chunk { || self .timelines .get(timeline) - .map_or(false, |time_column| time_column.is_sorted_uncached()) + .is_some_and(|time_column| time_column.is_sorted_uncached()) } /// Sort the chunk, if needed. diff --git a/crates/store/re_chunk_store/src/dataframe.rs b/crates/store/re_chunk_store/src/dataframe.rs index 01c9f243d2a6..906778de5350 100644 --- a/crates/store/re_chunk_store/src/dataframe.rs +++ b/crates/store/re_chunk_store/src/dataframe.rs @@ -900,7 +900,7 @@ impl ChunkStore { view_contents.as_ref().map_or(true, |view_contents| { view_contents .get(&column.entity_path) - .map_or(false, |components| { + .is_some_and(|components| { components.as_ref().map_or(true, |components| { components.contains(&column.component_name) }) diff --git a/crates/store/re_chunk_store/src/query.rs b/crates/store/re_chunk_store/src/query.rs index 228e4c601b51..b8dae5e44618 100644 --- a/crates/store/re_chunk_store/src/query.rs +++ b/crates/store/re_chunk_store/src/query.rs @@ -745,12 +745,12 @@ impl ChunkStore { chunk .timelines() .get(&query.timeline()) - .map_or(false, |time_column| { + .is_some_and(|time_column| { time_column .time_range_per_component(chunk.components()) .get(&component_name) .and_then(|per_desc| per_desc.values().next()) - .map_or(false, |time_range| time_range.intersects(query.range())) + .is_some_and(|time_range| time_range.intersects(query.range())) }) }) .collect_vec(); @@ -798,9 +798,7 @@ impl ChunkStore { chunk .timelines() .get(&query.timeline()) - .map_or(false, |time_column| { - time_column.time_range().intersects(query.range()) - }) + .is_some_and(|time_column| time_column.time_range().intersects(query.range())) }) .collect_vec(); diff --git a/crates/store/re_chunk_store/src/store.rs b/crates/store/re_chunk_store/src/store.rs index 2cf1358685b3..7bf10cb1e8ed 100644 --- a/crates/store/re_chunk_store/src/store.rs +++ b/crates/store/re_chunk_store/src/store.rs @@ -671,9 +671,7 @@ impl ChunkStore { let is_static = self .static_chunk_ids_per_entity .get(entity_path) - .map_or(false, |per_component| { - per_component.get(component_name).is_some() - }); + .is_some_and(|per_component| per_component.get(component_name).is_some()); let is_indicator = component_name.is_indicator_component(); diff --git a/crates/store/re_chunk_store/src/writes.rs b/crates/store/re_chunk_store/src/writes.rs index 204ad39abc8d..45cbadc43bb5 100644 --- a/crates/store/re_chunk_store/src/writes.rs +++ b/crates/store/re_chunk_store/src/writes.rs @@ -88,7 +88,7 @@ impl ChunkStore { for (component_desc, list_array) in chunk.components().iter_flattened() { let is_empty = list_array .validity() - .map_or(false, |validity| validity.is_empty()); + .is_some_and(|validity| validity.is_empty()); if is_empty { continue; } diff --git a/crates/store/re_data_loader/src/loader_external.rs b/crates/store/re_data_loader/src/loader_external.rs index 51e4ac10f1d9..9ae27fc0178b 100644 --- a/crates/store/re_data_loader/src/loader_external.rs +++ b/crates/store/re_data_loader/src/loader_external.rs @@ -59,7 +59,7 @@ pub static EXTERNAL_LOADER_PATHS: Lazy> = Lazy::new(|| { return None; }; let filepath = entry.path(); - let is_rerun_loader = filepath.file_name().map_or(false, |filename| { + let is_rerun_loader = filepath.file_name().is_some_and(|filename| { filename .to_string_lossy() .starts_with(EXTERNAL_DATA_LOADER_PREFIX) diff --git a/crates/store/re_entity_db/src/entity_db.rs b/crates/store/re_entity_db/src/entity_db.rs index 618332b18d40..cf4801b0c8d4 100644 --- a/crates/store/re_entity_db/src/entity_db.rs +++ b/crates/store/re_entity_db/src/entity_db.rs @@ -259,7 +259,7 @@ impl EntityDb { pub fn has_any_data_on_timeline(&self, timeline: &Timeline) -> bool { self.time_histogram_per_timeline .get(timeline) - .map_or(false, |hist| !hist.is_empty()) + .is_some_and(|hist| !hist.is_empty()) } /// Returns the time range of data on the given timeline, ignoring any static times. @@ -586,13 +586,10 @@ impl EntityDb { }; // TODO(cmc): chunk.slice_time_selection(time_selection) - chunk - .timelines() - .get(&timeline) - .map_or(false, |time_column| { - time_range.contains(time_column.time_range().min()) - || time_range.contains(time_column.time_range().max()) - }) + chunk.timelines().get(&timeline).is_some_and(|time_column| { + time_range.contains(time_column.time_range().min()) + || time_range.contains(time_column.time_range().max()) + }) }) .cloned() // refcount .collect(); diff --git a/crates/store/re_sdk_comms/src/tcp_client.rs b/crates/store/re_sdk_comms/src/tcp_client.rs index c44b5d947376..cd8e51ffe254 100644 --- a/crates/store/re_sdk_comms/src/tcp_client.rs +++ b/crates/store/re_sdk_comms/src/tcp_client.rs @@ -186,7 +186,7 @@ impl TcpClient { num_attempts, } => { // If a timeout wasn't provided, never timeout - self.flush_timeout.map_or(false, |timeout| { + self.flush_timeout.is_some_and(|timeout| { Instant::now().duration_since(start_time) > timeout && num_attempts > 0 }) } diff --git a/crates/store/re_types_core/src/loggable_batch.rs b/crates/store/re_types_core/src/loggable_batch.rs index e5a928b0e762..72f23628f052 100644 --- a/crates/store/re_types_core/src/loggable_batch.rs +++ b/crates/store/re_types_core/src/loggable_batch.rs @@ -129,7 +129,7 @@ impl LoggableBatch for ComponentBatchCowWithDescriptor<'_> { } } -impl<'a> ComponentBatch for ComponentBatchCowWithDescriptor<'a> { +impl ComponentBatch for ComponentBatchCowWithDescriptor<'_> { #[inline] fn descriptor(&self) -> Cow<'_, ComponentDescriptor> { self.descriptor_override @@ -179,14 +179,14 @@ impl<'a> std::ops::Deref for ComponentBatchCow<'a> { } } -impl<'a> LoggableBatch for ComponentBatchCow<'a> { +impl LoggableBatch for ComponentBatchCow<'_> { #[inline] fn to_arrow2(&self) -> SerializationResult> { (**self).to_arrow2() } } -impl<'a> ComponentBatch for ComponentBatchCow<'a> { +impl ComponentBatch for ComponentBatchCow<'_> { #[inline] fn descriptor(&self) -> Cow<'_, ComponentDescriptor> { (**self).descriptor() diff --git a/crates/top/rerun/src/commands/entrypoint.rs b/crates/top/rerun/src/commands/entrypoint.rs index 994a4dfe0001..7c240a42cb0a 100644 --- a/crates/top/rerun/src/commands/entrypoint.rs +++ b/crates/top/rerun/src/commands/entrypoint.rs @@ -607,9 +607,7 @@ where Err(err) if err .downcast_ref::() - .map_or(false, |io_err| { - io_err.kind() == std::io::ErrorKind::AddrInUse - }) => + .is_some_and(|io_err| io_err.kind() == std::io::ErrorKind::AddrInUse) => { re_log::warn!("{err}"); Ok(1) diff --git a/crates/utils/re_byte_size/src/std_sizes.rs b/crates/utils/re_byte_size/src/std_sizes.rs index 063a2bbfbb6b..7564f3d090c3 100644 --- a/crates/utils/re_byte_size/src/std_sizes.rs +++ b/crates/utils/re_byte_size/src/std_sizes.rs @@ -11,7 +11,7 @@ impl SizeBytes for String { /// Does not take capacity into account. #[inline] fn heap_size_bytes(&self) -> u64 { - self.as_bytes().len() as u64 + self.len() as u64 } } diff --git a/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs b/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs index 3af575f1da63..855f058e2bfb 100644 --- a/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs +++ b/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs @@ -468,7 +468,7 @@ impl BlueprintTree { let is_item_hovered = ctx.selection_state().highlight_for_ui_element(&item) == HoverHighlight::Hovered; - let visible = data_result_node.map_or(false, |n| n.data_result.is_visible(ctx)); + 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(); let item_label = if entity_path.is_root() { @@ -530,7 +530,7 @@ impl BlueprintTree { } // 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.map_or(false, |n| !n.children.is_empty()); + 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 = entity_path.starts_with(&view.space_origin) diff --git a/crates/viewer/re_component_ui/src/radius.rs b/crates/viewer/re_component_ui/src/radius.rs index 17a13dcb70e1..4ddcf946945d 100644 --- a/crates/viewer/re_component_ui/src/radius.rs +++ b/crates/viewer/re_component_ui/src/radius.rs @@ -33,7 +33,7 @@ pub fn edit_radius_ui( if combobox_response .inner .as_ref() - .map_or(false, |r| r.changed()) + .is_some_and(|r| r.changed()) { // When we change the type of units,the value is likely going to be _very wrong_. // Unfortunately, we don't have knowledge of a fallback here, so we use hardcoded "reasonable" values. diff --git a/crates/viewer/re_data_ui/src/app_id.rs b/crates/viewer/re_data_ui/src/app_id.rs index d014681a3bfc..512289c0b63b 100644 --- a/crates/viewer/re_data_ui/src/app_id.rs +++ b/crates/viewer/re_data_ui/src/app_id.rs @@ -70,7 +70,7 @@ impl crate::DataUi for ApplicationId { let button = egui::Button::image_and_text(&re_ui::icons::RESET, "Reset to default blueprint"); - let is_same_as_default = default_blueprint.map_or(false, |default_blueprint| { + let is_same_as_default = default_blueprint.is_some_and(|default_blueprint| { default_blueprint.latest_row_id() == active_blueprint.latest_row_id() }); diff --git a/crates/viewer/re_renderer/build.rs b/crates/viewer/re_renderer/build.rs index 885844c9e5a5..68f89c03366a 100644 --- a/crates/viewer/re_renderer/build.rs +++ b/crates/viewer/re_renderer/build.rs @@ -153,7 +153,7 @@ fn main() { let is_wgsl = entry .file_name() .to_str() - .map_or(false, |s| s.ends_with(".wgsl")); + .is_some_and(|s| s.ends_with(".wgsl")); is_dir || is_wgsl } diff --git a/crates/viewer/re_renderer_examples/multiview.rs b/crates/viewer/re_renderer_examples/multiview.rs index 56ce412ca84a..90917a79a859 100644 --- a/crates/viewer/re_renderer_examples/multiview.rs +++ b/crates/viewer/re_renderer_examples/multiview.rs @@ -224,7 +224,7 @@ impl Multiview { if self .take_screenshot_next_frame_for_view - .map_or(false, |i| i == index) + .is_some_and(|i| i == index) { view_builder.schedule_screenshot(re_ctx, READBACK_IDENTIFIER, index)?; re_log::info!("Scheduled screenshot for view {}", index); diff --git a/crates/viewer/re_selection_panel/src/defaults_ui.rs b/crates/viewer/re_selection_panel/src/defaults_ui.rs index 1800b68ca702..a0b4013177ac 100644 --- a/crates/viewer/re_selection_panel/src/defaults_ui.rs +++ b/crates/viewer/re_selection_panel/src/defaults_ui.rs @@ -202,7 +202,7 @@ fn active_defaults( .cache() .latest_at(query, &view.defaults_path, [*c]) .component_batch_raw(c) - .map_or(false, |data| !data.is_empty()) + .is_some_and(|data| !data.is_empty()) }) .collect::>() } diff --git a/crates/viewer/re_selection_panel/src/visible_time_range_ui.rs b/crates/viewer/re_selection_panel/src/visible_time_range_ui.rs index fa57fac24651..7caae1c0e531 100644 --- a/crates/viewer/re_selection_panel/src/visible_time_range_ui.rs +++ b/crates/viewer/re_selection_panel/src/visible_time_range_ui.rs @@ -233,7 +233,7 @@ Notes: || collapsing_response.header_response.hovered() || collapsing_response .body_response - .map_or(false, |r| r.hovered()); + .is_some_and(|r| r.hovered()); if should_display_visible_time_range { if let Some(current_time) = time_ctrl.time_int() { @@ -587,5 +587,5 @@ fn visible_history_boundary_ui( TimeRangeBoundary::Infinite => None, }; - response.map_or(false, |r| r.dragged() || r.has_focus()) + response.is_some_and(|r| r.dragged() || r.has_focus()) } diff --git a/crates/viewer/re_time_panel/src/lib.rs b/crates/viewer/re_time_panel/src/lib.rs index d623cda476af..00f715e00147 100644 --- a/crates/viewer/re_time_panel/src/lib.rs +++ b/crates/viewer/re_time_panel/src/lib.rs @@ -316,7 +316,7 @@ impl TimePanel { let time_range = entity_db.time_range_for(time_ctrl.timeline()); let has_more_than_one_time_point = - time_range.map_or(false, |time_range| time_range.min() != time_range.max()); + time_range.is_some_and(|time_range| time_range.min() != time_range.max()); if ui.max_rect().width() < 600.0 && has_more_than_one_time_point { // Responsive ui for narrow screens, e.g. mobile. Split the controls into two rows. @@ -1398,8 +1398,7 @@ fn interact_with_streams_rect( // Check for zoom/pan inputs (via e.g. horizontal scrolling) on the entire // time area rectangle, including the timeline rect. - let full_rect_hovered = - pointer_pos.map_or(false, |pointer_pos| full_rect.contains(pointer_pos)); + let full_rect_hovered = pointer_pos.is_some_and(|pointer_pos| full_rect.contains(pointer_pos)); if full_rect_hovered { ui.input(|input| { delta_x += input.smooth_scroll_delta.x; diff --git a/crates/viewer/re_time_panel/src/time_selection_ui.rs b/crates/viewer/re_time_panel/src/time_selection_ui.rs index 4b732edf54c1..b7b3972fdb34 100644 --- a/crates/viewer/re_time_panel/src/time_selection_ui.rs +++ b/crates/viewer/re_time_panel/src/time_selection_ui.rs @@ -33,7 +33,7 @@ pub fn loop_selection_ui( let pointer_pos = ui.input(|i| i.pointer.hover_pos()); let is_pointer_in_timeline = - pointer_pos.map_or(false, |pointer_pos| timeline_rect.contains(pointer_pos)); + pointer_pos.is_some_and(|pointer_pos| timeline_rect.contains(pointer_pos)); let left_edge_id = ui.id().with("selection_left_edge"); let right_edge_id = ui.id().with("selection_right_edge"); diff --git a/crates/viewer/re_view/src/results_ext.rs b/crates/viewer/re_view/src/results_ext.rs index 8dbe97606db0..3788826abef7 100644 --- a/crates/viewer/re_view/src/results_ext.rs +++ b/crates/viewer/re_view/src/results_ext.rs @@ -283,7 +283,7 @@ impl RangeResultsExt for RangeResults { } } -impl<'a> RangeResultsExt for HybridRangeResults<'a> { +impl RangeResultsExt for HybridRangeResults<'_> { #[inline] fn get_required_chunks(&self, component_name: &ComponentName) -> Option> { if let Some(unit) = self.overrides.get(component_name) { diff --git a/crates/viewer/re_view_bar_chart/src/view_class.rs b/crates/viewer/re_view_bar_chart/src/view_class.rs index eb56be3fd3e7..52608ffc7604 100644 --- a/crates/viewer/re_view_bar_chart/src/view_class.rs +++ b/crates/viewer/re_view_bar_chart/src/view_class.rs @@ -86,7 +86,7 @@ Display a 1D tensor as a bar chart. // Keeping this implementation simple: We know there's only a single visualizer here. if visualizable_entities_per_visualizer .get(&BarChartVisualizerSystem::identifier()) - .map_or(false, |entities| entities.contains(entity_path)) + .is_some_and(|entities| entities.contains(entity_path)) { std::iter::once(BarChartVisualizerSystem::identifier()).collect() } else { diff --git a/crates/viewer/re_view_dataframe/src/view_query/blueprint.rs b/crates/viewer/re_view_dataframe/src/view_query/blueprint.rs index 18429831d8d5..abb1f508fd43 100644 --- a/crates/viewer/re_view_dataframe/src/view_query/blueprint.rs +++ b/crates/viewer/re_view_dataframe/src/view_query/blueprint.rs @@ -109,7 +109,7 @@ impl Query { Ok(self .query_property .component_or_empty::()? - .map_or(false, |comp| *comp.0)) + .is_some_and(|comp| *comp.0)) } pub(crate) fn save_latest_at_enabled(&self, ctx: &ViewerContext<'_>, enabled: bool) { diff --git a/crates/viewer/re_view_map/src/map_view.rs b/crates/viewer/re_view_map/src/map_view.rs index 5baa1dbcc101..336cc9033437 100644 --- a/crates/viewer/re_view_map/src/map_view.rs +++ b/crates/viewer/re_view_map/src/map_view.rs @@ -266,10 +266,7 @@ Displays geospatial primitives on a map. // Map UI // - let (tiles, map_memory) = match state.ensure_and_get_mut_refs(ctx, ui.ctx()) { - Ok(refs) => refs, - Err(err) => return Err(err), - }; + let (tiles, map_memory) = state.ensure_and_get_mut_refs(ctx, ui.ctx())?; let attribution = tiles.attribution(); let some_tiles_manager: Option<&mut dyn Tiles> = Some(tiles); diff --git a/crates/viewer/re_view_spatial/src/scene_bounding_boxes.rs b/crates/viewer/re_view_spatial/src/scene_bounding_boxes.rs index 44484a46e4e5..ec42749bae43 100644 --- a/crates/viewer/re_view_spatial/src/scene_bounding_boxes.rs +++ b/crates/viewer/re_view_spatial/src/scene_bounding_boxes.rs @@ -48,7 +48,7 @@ impl SceneBoundingBoxes { // bounding box, creating a feedback loop if we were to add it here. let data_is_only_2d = data .preferred_view_kind - .map_or(false, |kind| kind == SpatialViewKind::TwoD); + .is_some_and(|kind| kind == SpatialViewKind::TwoD); if space_kind == SpatialViewKind::ThreeD && data_is_only_2d { continue; } diff --git a/crates/viewer/re_view_spatial/src/transform_component_tracker.rs b/crates/viewer/re_view_spatial/src/transform_component_tracker.rs index 7c951cafe693..7f6b564f10f6 100644 --- a/crates/viewer/re_view_spatial/src/transform_component_tracker.rs +++ b/crates/viewer/re_view_spatial/src/transform_component_tracker.rs @@ -99,7 +99,7 @@ impl PerStoreChunkSubscriber for TransformComponentTrackerStoreSubscriber { .chunk .components() .get(&component_name) - .map_or(false, |per_desc| { + .is_some_and(|per_desc| { per_desc .values() .any(|list_array| list_array.offsets().lengths().any(|len| len > 0)) diff --git a/crates/viewer/re_view_spatial/src/ui_3d.rs b/crates/viewer/re_view_spatial/src/ui_3d.rs index 314c2faccbbd..ce9baf90c197 100644 --- a/crates/viewer/re_view_spatial/src/ui_3d.rs +++ b/crates/viewer/re_view_spatial/src/ui_3d.rs @@ -758,7 +758,7 @@ fn show_orbit_eye_center( let should_show_center_of_orbit_camera = state_3d .last_eye_interaction - .map_or(false, |d| d.elapsed().as_secs_f32() < 0.35); + .is_some_and(|d| d.elapsed().as_secs_f32() < 0.35); if !state_3d.eye_interact_fade_in && should_show_center_of_orbit_camera { // Any interaction immediately causes fade in to start if it's not already on. @@ -886,7 +886,7 @@ fn show_projections_from_2d_space( .. } => { let current_tracked_entity = state.state_3d.tracked_entity.as_ref(); - if current_tracked_entity.map_or(true, |tracked| tracked != tracked_entity) { + if current_tracked_entity != Some(tracked_entity) { if let Some(tracked_camera) = space_cameras .iter() .find(|cam| &cam.ent_path == tracked_entity) diff --git a/crates/viewer/re_view_spatial/src/visualizers/depth_images.rs b/crates/viewer/re_view_spatial/src/visualizers/depth_images.rs index 6aff48716e8f..652eafbdb38f 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/depth_images.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/depth_images.rs @@ -407,7 +407,7 @@ impl TypedComponentFallbackProvider for DepthImageVisualizer { let is_integer_tensor = ctx .recording() .latest_at_component::(ctx.target_entity_path, ctx.query) - .map_or(false, |(_index, tensor)| tensor.dtype().is_integer()); + .is_some_and(|(_index, tensor)| tensor.dtype().is_integer()); if is_integer_tensor { 1000.0 } else { 1.0 }.into() } diff --git a/crates/viewer/re_view_spatial/src/visualizers/encoded_image.rs b/crates/viewer/re_view_spatial/src/visualizers/encoded_image.rs index 4269a277c296..bad12c67990b 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/encoded_image.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/encoded_image.rs @@ -48,7 +48,7 @@ impl VisualizerAdditionalApplicabilityFilter for ImageMediaTypeFilter { diff_component_filter(event, |media_type: &re_types::components::MediaType| { media_type.is_image() }) || diff_component_filter(event, |image: &re_types::components::Blob| { - MediaType::guess_from_data(&image.0).map_or(false, |media| media.is_image()) + MediaType::guess_from_data(&image.0).is_some_and(|media| media.is_image()) }) } } diff --git a/crates/viewer/re_view_tensor/src/dimension_mapping.rs b/crates/viewer/re_view_tensor/src/dimension_mapping.rs index 43ccab9a812b..6fd1f1cd13aa 100644 --- a/crates/viewer/re_view_tensor/src/dimension_mapping.rs +++ b/crates/viewer/re_view_tensor/src/dimension_mapping.rs @@ -75,7 +75,7 @@ fn make_width_height_valid( invert: shape[default_width] .name .as_ref() - .map_or(false, |name| name.to_lowercase().eq("left")), + .is_some_and(|name| name.to_lowercase().eq("left")), } .into(), ); @@ -87,7 +87,7 @@ fn make_width_height_valid( invert: shape[default_height] .name .as_ref() - .map_or(false, |name| name.to_lowercase().eq("up")), + .is_some_and(|name| name.to_lowercase().eq("up")), } .into(), ); diff --git a/crates/viewer/re_view_tensor/src/tensor_dimension_mapper.rs b/crates/viewer/re_view_tensor/src/tensor_dimension_mapper.rs index 07e6bed75cb1..6a35e6bbe165 100644 --- a/crates/viewer/re_view_tensor/src/tensor_dimension_mapper.rs +++ b/crates/viewer/re_view_tensor/src/tensor_dimension_mapper.rs @@ -226,7 +226,7 @@ pub fn dimension_mapping_ui( ); let mut has_slider = - slice_selection.slider.as_ref().map_or(false, |slider| { + slice_selection.slider.as_ref().is_some_and(|slider| { slider .iter() .any(|slider| slider.dimension == selector.dimension) diff --git a/crates/viewer/re_view_tensor/src/view_class.rs b/crates/viewer/re_view_tensor/src/view_class.rs index ee8fdfc733d4..5568eb2b239a 100644 --- a/crates/viewer/re_view_tensor/src/view_class.rs +++ b/crates/viewer/re_view_tensor/src/view_class.rs @@ -106,7 +106,7 @@ Note: select the view to configure which dimensions are shown." // Keeping this implementation simple: We know there's only a single visualizer here. if visualizable_entities_per_visualizer .get(&TensorSystem::identifier()) - .map_or(false, |entities| entities.contains(entity_path)) + .is_some_and(|entities| entities.contains(entity_path)) { std::iter::once(TensorSystem::identifier()).collect() } else { diff --git a/crates/viewer/re_view_time_series/src/line_visualizer_system.rs b/crates/viewer/re_view_time_series/src/line_visualizer_system.rs index 6ea021d08867..d8b88011e8ef 100644 --- a/crates/viewer/re_view_time_series/src/line_visualizer_system.rs +++ b/crates/viewer/re_view_time_series/src/line_visualizer_system.rs @@ -482,7 +482,7 @@ fn collect_recursive_clears( chunk .iter_component::() .map(|is_recursive| { - is_recursive.as_slice().first().map_or(false, |v| *v.0) + is_recursive.as_slice().first().is_some_and(|v| *v.0) }) ) .filter_map(|(index, is_recursive)| { diff --git a/crates/viewer/re_view_time_series/src/util.rs b/crates/viewer/re_view_time_series/src/util.rs index eca8c7848294..6ecb7a4af188 100644 --- a/crates/viewer/re_view_time_series/src/util.rs +++ b/crates/viewer/re_view_time_series/src/util.rs @@ -53,7 +53,7 @@ pub fn determine_time_range( let mut time_range = ResolvedTimeRange::from_relative_time_range(&visible_time_range, time_cursor); - let is_auto_bounds = plot_mem.map_or(false, |mem| mem.auto_bounds.x || mem.auto_bounds.y); + let is_auto_bounds = plot_mem.is_some_and(|mem| mem.auto_bounds.x || mem.auto_bounds.y); let plot_bounds = plot_mem.map(|mem| { let bounds = mem.bounds().range_x(); let x_min = bounds.start().floor() as i64; diff --git a/crates/viewer/re_view_time_series/src/view_class.rs b/crates/viewer/re_view_time_series/src/view_class.rs index f53cd3ed58d2..ebcad6927277 100644 --- a/crates/viewer/re_view_time_series/src/view_class.rs +++ b/crates/viewer/re_view_time_series/src/view_class.rs @@ -257,7 +257,7 @@ Display time series data in a plot. .filter_map(|visualizer| { if indicated_entities_per_visualizer .get(*visualizer) - .map_or(false, |matching_list| matching_list.contains(entity_path)) + .is_some_and(|matching_list| matching_list.contains(entity_path)) { Some(**visualizer) } else { diff --git a/crates/viewer/re_viewer/src/ui/rerun_menu.rs b/crates/viewer/re_viewer/src/ui/rerun_menu.rs index a4a2ff703347..bb79fa5edb3c 100644 --- a/crates/viewer/re_viewer/src/ui/rerun_menu.rs +++ b/crates/viewer/re_viewer/src/ui/rerun_menu.rs @@ -194,7 +194,7 @@ impl App { }); }); } else { - let entity_db_is_nonempty = store_ctx.map_or(false, |ctx| !ctx.recording.is_empty()); + let entity_db_is_nonempty = store_ctx.is_some_and(|ctx| !ctx.recording.is_empty()); ui.add_enabled_ui(entity_db_is_nonempty, |ui| { if ui .add(save_recording_button) diff --git a/crates/viewer/re_viewer_context/src/query_context.rs b/crates/viewer/re_viewer_context/src/query_context.rs index b2ce007dd84a..e1ad601eb026 100644 --- a/crates/viewer/re_viewer_context/src/query_context.rs +++ b/crates/viewer/re_viewer_context/src/query_context.rs @@ -92,7 +92,7 @@ impl DataQueryResult { pub fn contains_entity(&self, path: &EntityPath) -> bool { self.tree .lookup_result_by_path(path) - .map_or(false, |result| !result.tree_prefix_only) + .is_some_and(|result| !result.tree_prefix_only) } } diff --git a/crates/viewer/re_viewer_context/src/view/view_class.rs b/crates/viewer/re_viewer_context/src/view/view_class.rs index 4b449636dadd..6ecc035ae640 100644 --- a/crates/viewer/re_viewer_context/src/view/view_class.rs +++ b/crates/viewer/re_viewer_context/src/view/view_class.rs @@ -160,7 +160,7 @@ pub trait ViewClass: Send + Sync { .filter_map(|visualizer| { if indicated_entities_per_visualizer .get(visualizer) - .map_or(false, |matching_list| matching_list.contains(entity_path)) + .is_some_and(|matching_list| matching_list.contains(entity_path)) { Some(*visualizer) } else { diff --git a/crates/viewer/re_viewport/src/viewport_ui.rs b/crates/viewer/re_viewport/src/viewport_ui.rs index 030fa184447c..4c9035e311dc 100644 --- a/crates/viewer/re_viewport/src/viewport_ui.rs +++ b/crates/viewer/re_viewport/src/viewport_ui.rs @@ -1021,11 +1021,11 @@ impl TabWidget { let hovered = tab_desc .item .as_ref() - .map_or(false, |item| tab_viewer.ctx.hovered().contains_item(item)); + .is_some_and(|item| tab_viewer.ctx.hovered().contains_item(item)); let selected = tab_desc .item .as_ref() - .map_or(false, |item| tab_viewer.ctx.selection().contains_item(item)); + .is_some_and(|item| tab_viewer.ctx.selection().contains_item(item)); // tab icon let icon_size = DesignTokens::small_icon_size(); diff --git a/crates/viewer/re_viewport_blueprint/src/view_properties.rs b/crates/viewer/re_viewport_blueprint/src/view_properties.rs index e6c2630e809d..7ff14aa1b92a 100644 --- a/crates/viewer/re_viewport_blueprint/src/view_properties.rs +++ b/crates/viewer/re_viewport_blueprint/src/view_properties.rs @@ -208,10 +208,10 @@ impl ViewProperty { /// Returns whether any property is non-empty. pub fn any_non_empty(&self) -> bool { - self.query_results.components.keys().any(|name| { - self.component_raw(*name) - .map_or(false, |raw| !raw.is_empty()) - }) + self.query_results + .components + .keys() + .any(|name| self.component_raw(*name).is_some_and(|raw| !raw.is_empty())) } /// Create a query context for this view property. diff --git a/crates/viewer/re_viewport_blueprint/src/viewport_blueprint.rs b/crates/viewer/re_viewport_blueprint/src/viewport_blueprint.rs index 630eee0dde5c..2142a7c4acbd 100644 --- a/crates/viewer/re_viewport_blueprint/src/viewport_blueprint.rs +++ b/crates/viewer/re_viewport_blueprint/src/viewport_blueprint.rs @@ -144,7 +144,7 @@ impl ViewportBlueprint { // Only enable auto-views if this is the app-default blueprint let is_app_default_blueprint = blueprint_db .store_info() - .map_or(false, |ri| ri.is_app_default_blueprint()); + .is_some_and(|ri| ri.is_app_default_blueprint()); let auto_layout = AtomicBool::new(auto_layout.map_or(is_app_default_blueprint, |auto| *auto.0)); let auto_views = @@ -267,7 +267,7 @@ impl ViewportBlueprint { Item::View(view_id) => self.view(view_id).is_some(), Item::DataResult(view_id, instance_path) => { - self.view(view_id).map_or(false, |view| { + self.view(view_id).is_some_and(|view| { let entity_path = &instance_path.entity_path; // TODO(#5742): including any path that is—or descend from—the space origin is diff --git a/rerun_py/src/python_bridge.rs b/rerun_py/src/python_bridge.rs index bae0810496c6..ba37d6ece289 100644 --- a/rerun_py/src/python_bridge.rs +++ b/rerun_py/src/python_bridge.rs @@ -206,7 +206,7 @@ fn new_recording( ) -> PyResult { // The sentinel file we use to identify the official examples directory. const SENTINEL_FILENAME: &str = ".rerun_examples"; - let is_official_example = application_path.map_or(false, |mut path| { + let is_official_example = application_path.is_some_and(|mut path| { // more than 4 layers would be really pushing it for _ in 0..4 { path.pop(); // first iteration is always a file path in our examples @@ -545,7 +545,7 @@ fn set_thread_local_blueprint_recording( #[pyfunction] #[pyo3(signature = (recording=None))] fn is_enabled(recording: Option<&PyRecordingStream>) -> bool { - get_data_recording(recording).map_or(false, |rec| rec.is_enabled()) + get_data_recording(recording).is_some_and(|rec| rec.is_enabled()) } /// Helper for forwarding the blueprint memory-sink representation to a given sink From cdf0181a6dd76c1100e82015f0496039b03aed3d Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 10 Jan 2025 20:31:33 +0100 Subject: [PATCH 02/57] Port `TimeColumn` to arrow-rs (#8638) ### Related * #3741 --- Cargo.lock | 6 +- crates/store/re_chunk/src/batcher.rs | 90 +++----------- crates/store/re_chunk/src/builder.rs | 4 +- crates/store/re_chunk/src/chunk.rs | 113 ++++++++++++------ crates/store/re_chunk/src/lib.rs | 4 +- crates/store/re_chunk/src/merge.rs | 17 +-- crates/store/re_chunk/src/shuffle.rs | 9 +- crates/store/re_chunk/src/slice.rs | 45 +++---- crates/store/re_chunk/src/transport.rs | 54 +++------ crates/store/re_chunk_store/src/dataframe.rs | 4 +- .../store/re_chunk_store/tests/memory_test.rs | 4 +- ...ory_test__scalars_on_one_timeline_new.snap | 6 +- crates/store/re_data_loader/Cargo.toml | 1 + .../re_data_loader/src/loader_archetype.rs | 8 +- crates/store/re_dataframe/Cargo.toml | 1 + crates/store/re_dataframe/src/query.rs | 18 ++- .../store/re_log_types/src/time_point/mod.rs | 28 ++++- .../re_log_types/src/time_point/timeline.rs | 9 +- crates/top/re_sdk/Cargo.toml | 1 - crates/top/re_sdk/src/recording_stream.rs | 18 +-- crates/top/rerun_c/Cargo.toml | 1 + crates/top/rerun_c/src/lib.rs | 16 ++- crates/utils/re_byte_size/src/arrow_sizes.rs | 20 +++- .../src/display_record_batch.rs | 57 +++------ rerun_py/src/arrow.rs | 19 ++- 25 files changed, 268 insertions(+), 285 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e946a50a1935..61be28db6ef1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5569,7 +5569,7 @@ dependencies = [ [[package]] name = "re_arrow2" version = "0.18.1" -source = "git+https://github.com/rerun-io/re_arrow2.git?branch=main#82095762a42eed76e4043c82833e391893d5821c" +source = "git+https://github.com/rerun-io/re_arrow2.git?branch=main#573b5bafd071d09698353d8f0de8d31f3fa59017" dependencies = [ "ahash", "arrow-array", @@ -5802,6 +5802,7 @@ version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "anyhow", + "arrow", "crossbeam", "image", "notify", @@ -5879,6 +5880,7 @@ name = "re_dataframe" version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", + "arrow", "itertools 0.13.0", "nohash-hasher", "rayon", @@ -6330,7 +6332,6 @@ dependencies = [ "once_cell", "parking_lot", "rand", - "re_arrow2", "re_build_info", "re_build_tools", "re_byte_size", @@ -7341,6 +7342,7 @@ name = "rerun_c" version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", + "arrow", "infer", "once_cell", "parking_lot", diff --git a/crates/store/re_chunk/src/batcher.rs b/crates/store/re_chunk/src/batcher.rs index 9143124a9ad4..e5c4a431fe49 100644 --- a/crates/store/re_chunk/src/batcher.rs +++ b/crates/store/re_chunk/src/batcher.rs @@ -5,7 +5,7 @@ use std::{ }; use arrow::array::{Array as ArrowArray, ArrayRef}; -use arrow2::array::PrimitiveArray as Arrow2PrimitiveArray; +use arrow::buffer::ScalarBuffer as ArrowScalarBuffer; use crossbeam::channel::{Receiver, Sender}; use nohash_hasher::IntMap; @@ -724,7 +724,7 @@ impl PendingRow { let timelines = timepoint .into_iter() .map(|(timeline, time)| { - let times = Arrow2PrimitiveArray::::from_vec(vec![time.as_i64()]); + let times = ArrowScalarBuffer::from(vec![time.as_i64()]); let time_column = TimeColumn::new(Some(true), timeline, times); (timeline, time_column) }) @@ -973,7 +973,7 @@ impl PendingTimeColumn { TimeColumn { timeline, - times: Arrow2PrimitiveArray::::from_vec(times).to(timeline.datatype()), + times: ArrowScalarBuffer::from(times), is_sorted, time_range, } @@ -1050,11 +1050,7 @@ mod tests { let expected_row_ids = vec![row1.row_id, row2.row_id, row3.row_id]; let expected_timelines = [( timeline1, - TimeColumn::new( - Some(true), - timeline1, - Arrow2PrimitiveArray::from_vec(vec![42, 43, 44]), - ), + TimeColumn::new(Some(true), timeline1, vec![42, 43, 44].into()), )]; let expected_components = [( MyPoint::descriptor(), @@ -1206,11 +1202,7 @@ mod tests { let expected_row_ids = vec![row1.row_id, row3.row_id]; let expected_timelines = [( timeline1, - TimeColumn::new( - Some(true), - timeline1, - Arrow2PrimitiveArray::from_vec(vec![42, 44]), - ), + TimeColumn::new(Some(true), timeline1, vec![42, 44].into()), )]; let expected_components = [( MyPoint::descriptor(), @@ -1234,11 +1226,7 @@ mod tests { let expected_row_ids = vec![row2.row_id]; let expected_timelines = [( timeline1, - TimeColumn::new( - Some(true), - timeline1, - Arrow2PrimitiveArray::from_vec(vec![43]), - ), + TimeColumn::new(Some(true), timeline1, vec![43].into()), )]; let expected_components = [( MyPoint::descriptor(), @@ -1321,11 +1309,7 @@ mod tests { let expected_row_ids = vec![row1.row_id]; let expected_timelines = [( timeline1, - TimeColumn::new( - Some(true), - timeline1, - Arrow2PrimitiveArray::from_vec(vec![42]), - ), + TimeColumn::new(Some(true), timeline1, vec![42].into()), )]; let expected_components = [( MyPoint::descriptor(), @@ -1350,19 +1334,11 @@ mod tests { let expected_timelines = [ ( timeline1, - TimeColumn::new( - Some(true), - timeline1, - Arrow2PrimitiveArray::from_vec(vec![43, 44]), - ), + TimeColumn::new(Some(true), timeline1, vec![43, 44].into()), ), ( timeline2, - TimeColumn::new( - Some(true), - timeline2, - Arrow2PrimitiveArray::from_vec(vec![1000, 1001]), - ), + TimeColumn::new(Some(true), timeline2, vec![1000, 1001].into()), ), ]; let expected_components = [( @@ -1442,11 +1418,7 @@ mod tests { let expected_row_ids = vec![row1.row_id, row3.row_id]; let expected_timelines = [( timeline1, - TimeColumn::new( - Some(true), - timeline1, - Arrow2PrimitiveArray::from_vec(vec![42, 44]), - ), + TimeColumn::new(Some(true), timeline1, vec![42, 44].into()), )]; let expected_components = [( MyPoint::descriptor(), @@ -1470,11 +1442,7 @@ mod tests { let expected_row_ids = vec![row2.row_id]; let expected_timelines = [( timeline1, - TimeColumn::new( - Some(true), - timeline1, - Arrow2PrimitiveArray::from_vec(vec![43]), - ), + TimeColumn::new(Some(true), timeline1, vec![43].into()), )]; let expected_components = [( MyPoint::descriptor(), @@ -1572,19 +1540,11 @@ mod tests { let expected_timelines = [ ( timeline1, - TimeColumn::new( - Some(false), - timeline1, - Arrow2PrimitiveArray::from_vec(vec![45, 42, 43, 44]), - ), + TimeColumn::new(Some(false), timeline1, vec![45, 42, 43, 44].into()), ), ( timeline2, - TimeColumn::new( - Some(false), - timeline2, - Arrow2PrimitiveArray::from_vec(vec![1003, 1000, 1001, 1002]), - ), + TimeColumn::new(Some(false), timeline2, vec![1003, 1000, 1001, 1002].into()), ), ]; let expected_components = [( @@ -1686,19 +1646,11 @@ mod tests { let expected_timelines = [ ( timeline1, - TimeColumn::new( - Some(false), - timeline1, - Arrow2PrimitiveArray::from_vec(vec![45, 42, 43]), - ), + TimeColumn::new(Some(false), timeline1, vec![45, 42, 43].into()), ), ( timeline2, - TimeColumn::new( - Some(false), - timeline2, - Arrow2PrimitiveArray::from_vec(vec![1003, 1000, 1001]), - ), + TimeColumn::new(Some(false), timeline2, vec![1003, 1000, 1001].into()), ), ]; let expected_components = [( @@ -1725,19 +1677,11 @@ mod tests { let expected_timelines = [ ( timeline1, - TimeColumn::new( - Some(true), - timeline1, - Arrow2PrimitiveArray::from_vec(vec![44]), - ), + TimeColumn::new(Some(true), timeline1, vec![44].into()), ), ( timeline2, - TimeColumn::new( - Some(true), - timeline2, - Arrow2PrimitiveArray::from_vec(vec![1002]), - ), + TimeColumn::new(Some(true), timeline2, vec![1002].into()), ), ]; let expected_components = [( diff --git a/crates/store/re_chunk/src/builder.rs b/crates/store/re_chunk/src/builder.rs index 243ba8d311e5..279aa625a223 100644 --- a/crates/store/re_chunk/src/builder.rs +++ b/crates/store/re_chunk/src/builder.rs @@ -352,8 +352,6 @@ impl TimeColumnBuilder { #[inline] pub fn build(self) -> TimeColumn { let Self { timeline, times } = self; - - let times = arrow2::array::PrimitiveArray::::from_vec(times).to(timeline.datatype()); - TimeColumn::new(None, timeline, times) + TimeColumn::new(None, timeline, times.into()) } } diff --git a/crates/store/re_chunk/src/chunk.rs b/crates/store/re_chunk/src/chunk.rs index cbbaacc7b7d9..eb0bc8045b0e 100644 --- a/crates/store/re_chunk/src/chunk.rs +++ b/crates/store/re_chunk/src/chunk.rs @@ -1,7 +1,10 @@ use std::sync::atomic::{AtomicU64, Ordering}; use ahash::HashMap; -use arrow::array::ListArray as ArrowListArray; +use arrow::{ + array::{Array as ArrowArray, ArrayRef as ArrowArrayRef, ListArray as ArrowListArray}, + buffer::ScalarBuffer as ArrowScalarBuffer, +}; use arrow2::{ array::{ Array as Arrow2Array, ListArray as Arrow2ListArray, PrimitiveArray as Arrow2PrimitiveArray, @@ -781,7 +784,11 @@ pub struct TimeColumn { /// * This is guaranteed to always be dense, because chunks are split anytime a timeline is /// added or removed. /// * This cannot ever contain `TimeInt::STATIC`, since static data doesn't even have timelines. - pub(crate) times: Arrow2PrimitiveArray, + /// + /// When this buffer is converted to an arrow array, it's datatype will depend + /// on the timeline type, so it will either become a + /// [`arrow::array::Int64Array`] or a [`arrow::array::TimestampNanosecondArray`]. + pub(crate) times: ArrowScalarBuffer, /// Is [`Self::times`] sorted? /// @@ -795,6 +802,16 @@ pub struct TimeColumn { pub(crate) time_range: ResolvedTimeRange, } +/// Errors when deserializing/parsing/reading a column of time data. +#[derive(Debug, thiserror::Error)] +pub enum TimeColumnError { + #[error("Time columns had nulls, but should be dense")] + ContainsNulls, + + #[error("Unsupported data type : {0}")] + UnsupportedDataType(arrow::datatypes::DataType), +} + impl Chunk { /// Creates a new [`Chunk`]. /// @@ -968,15 +985,10 @@ impl TimeColumn { /// When left unspecified (`None`), it will be computed in O(n) time. /// /// For a row-oriented constructor, see [`Self::builder`]. - pub fn new( - is_sorted: Option, - timeline: Timeline, - times: Arrow2PrimitiveArray, - ) -> Self { + pub fn new(is_sorted: Option, timeline: Timeline, times: ArrowScalarBuffer) -> Self { re_tracing::profile_function_if!(1000 < times.len(), format!("{} times", times.len())); - let times = times.to(timeline.datatype()); - let time_slice = times.values().as_slice(); + let time_slice = times.as_ref(); let is_sorted = is_sorted.unwrap_or_else(|| time_slice.windows(2).all(|times| times[0] <= times[1])); @@ -1021,7 +1033,7 @@ impl TimeColumn { name: impl Into, times: impl IntoIterator>, ) -> Self { - let time_vec = times.into_iter().map(|t| { + let time_vec: Vec<_> = times.into_iter().map(|t| { let t = t.into(); TimeInt::try_from(t) .unwrap_or_else(|_| { @@ -1038,7 +1050,7 @@ impl TimeColumn { Self::new( None, Timeline::new_sequence(name.into()), - Arrow2PrimitiveArray::::from_vec(time_vec), + ArrowScalarBuffer::from(time_vec), ) } @@ -1060,12 +1072,12 @@ impl TimeColumn { TimeInt::MIN }) .as_i64() - }).collect(); + }).collect_vec(); Self::new( None, Timeline::new_temporal(name.into()), - Arrow2PrimitiveArray::::from_vec(time_vec), + ArrowScalarBuffer::from(time_vec), ) } @@ -1090,14 +1102,49 @@ impl TimeColumn { }) .as_i64() }) - .collect(); + .collect_vec(); Self::new( None, Timeline::new_temporal(name.into()), - Arrow2PrimitiveArray::::from_vec(time_vec), + ArrowScalarBuffer::from(time_vec), ) } + + /// Parse the given [`ArrowArray`] as a time column. + /// + /// Results in an error if the array is of the wrong datatype, or if it contains nulls. + pub fn read_array(array: &dyn ArrowArray) -> Result, TimeColumnError> { + #![allow(clippy::manual_map)] + + if array.null_count() > 0 { + return Err(TimeColumnError::ContainsNulls); + } + + // Sequence timelines are i64, but time columns are nanoseconds (also as i64). + if let Some(times) = array.as_any().downcast_ref::() { + Ok(times.values().clone()) + } else if let Some(times) = array + .as_any() + .downcast_ref::() + { + Ok(times.values().clone()) + } else if let Some(times) = array + .as_any() + .downcast_ref::() + { + Ok(times.values().clone()) + } else if let Some(times) = array + .as_any() + .downcast_ref::() + { + Ok(times.values().clone()) + } else { + Err(TimeColumnError::UnsupportedDataType( + array.data_type().clone(), + )) + } + } } // --- @@ -1188,7 +1235,7 @@ impl Chunk { #[inline] pub fn row_ids(&self) -> impl Iterator + '_ { let (times, counters) = self.row_ids_raw(); - izip!(times.values().as_slice(), counters.values().as_slice()) + izip!(times.values().as_ref(), counters.values().as_slice()) .map(|(&time, &counter)| RowId::from_u128((time as u128) << 64 | (counter as u128))) } @@ -1230,7 +1277,7 @@ impl Chunk { } let (times, counters) = self.row_ids_raw(); - let (times, counters) = (times.values().as_slice(), counters.values().as_slice()); + let (times, counters) = (times.values().as_ref(), counters.values().as_slice()); #[allow(clippy::unwrap_used)] // checked above let (index_min, index_max) = if self.is_sorted() { @@ -1333,23 +1380,24 @@ impl TimeColumn { } #[inline] - pub fn times_array(&self) -> &Arrow2PrimitiveArray { + pub fn times_buffer(&self) -> &ArrowScalarBuffer { &self.times } + /// Returns an array with the appropriate datatype. + #[inline] + pub fn times_array(&self) -> ArrowArrayRef { + self.timeline.typ().make_arrow_array(self.times.clone()) + } + #[inline] pub fn times_raw(&self) -> &[i64] { - self.times.values().as_slice() + self.times.as_ref() } #[inline] pub fn times(&self) -> impl DoubleEndedIterator + '_ { - self.times - .values() - .as_slice() - .iter() - .copied() - .map(TimeInt::new_temporal) + self.times_raw().iter().copied().map(TimeInt::new_temporal) } #[inline] @@ -1603,24 +1651,13 @@ impl TimeColumn { /// Costly checks are only run in debug builds. pub fn sanity_check(&self) -> ChunkResult<()> { let Self { - timeline, + timeline: _, times, is_sorted, time_range, } = self; - if *times.data_type() != timeline.datatype() { - return Err(ChunkError::Malformed { - reason: format!( - "Time data for timeline {} has the wrong datatype: expected {:?} but got {:?} instead", - timeline.name(), - timeline.datatype(), - *times.data_type(), - ), - }); - } - - let times = times.values().as_slice(); + let times = times.as_ref(); #[allow(clippy::collapsible_if)] // readability if cfg!(debug_assertions) { diff --git a/crates/store/re_chunk/src/lib.rs b/crates/store/re_chunk/src/lib.rs index 9ba7b632b86d..b4edc54d1ce6 100644 --- a/crates/store/re_chunk/src/lib.rs +++ b/crates/store/re_chunk/src/lib.rs @@ -26,7 +26,9 @@ mod batcher; mod arrow; pub use self::builder::{ChunkBuilder, TimeColumnBuilder}; -pub use self::chunk::{Chunk, ChunkComponents, ChunkError, ChunkResult, TimeColumn}; +pub use self::chunk::{ + Chunk, ChunkComponents, ChunkError, ChunkResult, TimeColumn, TimeColumnError, +}; pub use self::helpers::{ChunkShared, UnitChunkShared}; pub use self::id::{ChunkId, RowId}; pub use self::iter::{ diff --git a/crates/store/re_chunk/src/merge.rs b/crates/store/re_chunk/src/merge.rs index a804ede244fb..9b4433b1e975 100644 --- a/crates/store/re_chunk/src/merge.rs +++ b/crates/store/re_chunk/src/merge.rs @@ -1,6 +1,6 @@ +use arrow::buffer::ScalarBuffer as ArrowScalarBuffer; use arrow2::array::{ - Array as Arrow2Array, ListArray as Arrow2ListArray, PrimitiveArray as Arrow2PrimitiveArray, - StructArray as Arrow2StructArray, + Array as Arrow2Array, ListArray as Arrow2ListArray, StructArray as Arrow2StructArray, }; use itertools::{izip, Itertools}; use nohash_hasher::IntMap; @@ -281,17 +281,20 @@ impl TimeColumn { if self.timeline != rhs.timeline { return None; } + re_tracing::profile_function!(); let is_sorted = self.is_sorted && rhs.is_sorted && self.time_range.max() <= rhs.time_range.min(); let time_range = self.time_range.union(rhs.time_range); - let times = arrow2_util::concat_arrays(&[&self.times, &rhs.times]).ok()?; - let times = times - .as_any() - .downcast_ref::>()? - .clone(); + let times = self + .times_raw() + .iter() + .chain(rhs.times_raw()) + .copied() + .collect_vec(); + let times = ArrowScalarBuffer::from(times); Some(Self { timeline: self.timeline, diff --git a/crates/store/re_chunk/src/shuffle.rs b/crates/store/re_chunk/src/shuffle.rs index f90479c7c541..86d48b35bdb2 100644 --- a/crates/store/re_chunk/src/shuffle.rs +++ b/crates/store/re_chunk/src/shuffle.rs @@ -1,3 +1,4 @@ +use arrow::buffer::ScalarBuffer as ArrowScalarBuffer; use arrow2::{ array::{ Array as Arrow2Array, ListArray as Arrow2ListArray, PrimitiveArray as Arrow2PrimitiveArray, @@ -238,19 +239,19 @@ impl Chunk { for info in timelines.values_mut() { let TimeColumn { - timeline, + timeline: _, times, is_sorted, time_range: _, } = info; - let mut sorted = times.values().to_vec(); + let mut sorted = times.to_vec(); for (to, from) in swaps.iter().copied().enumerate() { - sorted[to] = times.values()[from]; + sorted[to] = times[from]; } *is_sorted = sorted.windows(2).all(|times| times[0] <= times[1]); - *times = Arrow2PrimitiveArray::::from_vec(sorted).to(timeline.datatype()); + *times = ArrowScalarBuffer::from(sorted); } } diff --git a/crates/store/re_chunk/src/slice.rs b/crates/store/re_chunk/src/slice.rs index b361254c76a9..3b2f842cef92 100644 --- a/crates/store/re_chunk/src/slice.rs +++ b/crates/store/re_chunk/src/slice.rs @@ -1,6 +1,6 @@ use arrow2::array::{ Array as Arrow2Array, BooleanArray as Arrow2BooleanArray, ListArray as Arrow2ListArray, - PrimitiveArray as Arrow2PrimitiveArray, StructArray as Arrow2StructArray, + StructArray as Arrow2StructArray, }; use itertools::Itertools; @@ -9,7 +9,7 @@ use nohash_hasher::IntSet; use re_log_types::Timeline; use re_types_core::{ComponentDescriptor, ComponentName}; -use crate::{arrow2_util, Chunk, RowId, TimeColumn}; +use crate::{arrow2_util, arrow_util, Chunk, RowId, TimeColumn}; // --- @@ -538,7 +538,7 @@ impl Chunk { i.saturating_sub(1) as i32 }) .collect_vec(); - Arrow2PrimitiveArray::::from_vec(indices) + arrow2::array::Int32Array::from_vec(indices) }; let chunk = Self { @@ -671,7 +671,7 @@ impl Chunk { /// WARNING: the returned chunk has the same old [`crate::ChunkId`]! Change it with [`Self::with_id`]. #[must_use] #[inline] - pub fn taken(&self, indices: &Arrow2PrimitiveArray) -> Self { + pub fn taken(&self, indices: &arrow2::array::Int32Array) -> Self { let Self { id, entity_path, @@ -792,11 +792,7 @@ impl TimeColumn { // The original chunk is unsorted, but the new sliced one actually ends up being sorted. let is_sorted_opt = is_sorted.then_some(is_sorted); - Self::new( - is_sorted_opt, - *timeline, - Arrow2PrimitiveArray::sliced(times.clone(), index, len), - ) + Self::new(is_sorted_opt, *timeline, times.clone().slice(index, len)) } /// Empties the [`TimeColumn`] vertically. @@ -806,16 +802,12 @@ impl TimeColumn { pub fn emptied(&self) -> Self { let Self { timeline, - times, + times: _, is_sorted: _, time_range: _, } = self; - Self::new( - Some(true), - *timeline, - Arrow2PrimitiveArray::new_empty(times.data_type().clone()), - ) + Self::new(Some(true), *timeline, vec![].into()) } /// Runs a [filter] compute kernel on the time data with the specified `mask`. @@ -852,15 +844,20 @@ impl TimeColumn { Self::new( is_sorted_opt, *timeline, - arrow2_util::filter_array(times, filter), + arrow_util::filter_array( + &arrow::array::Int64Array::new(times.clone(), None), + &filter.clone().into(), + ) + .into_parts() + .1, ) } /// Runs a [take] compute kernel on the time data with the specified `indices`. /// - /// [take]: arrow2::compute::take::take + /// [take]: arrow::compute::take #[inline] - pub(crate) fn taken(&self, indices: &Arrow2PrimitiveArray) -> Self { + pub(crate) fn taken(&self, indices: &arrow2::array::Int32Array) -> Self { let Self { timeline, times, @@ -868,11 +865,14 @@ impl TimeColumn { time_range: _, } = self; - Self::new( - Some(*is_sorted), - *timeline, - arrow2_util::take_array(times, indices), + let new_times = arrow_util::take_array( + &arrow::array::Int64Array::new(times.clone(), None), + &arrow::array::Int32Array::from(indices.clone()), ) + .into_parts() + .1; + + Self::new(Some(*is_sorted), *timeline, new_times) } } @@ -880,6 +880,7 @@ impl TimeColumn { #[cfg(test)] mod tests { + use arrow2::array::PrimitiveArray as Arrow2PrimitiveArray; use itertools::Itertools; use re_log_types::{ example_components::{MyColor, MyLabel, MyPoint}, diff --git a/crates/store/re_chunk/src/transport.rs b/crates/store/re_chunk/src/transport.rs index 0a2700d78c3c..e603ad9fd856 100644 --- a/crates/store/re_chunk/src/transport.rs +++ b/crates/store/re_chunk/src/transport.rs @@ -1,8 +1,6 @@ +use arrow::array::ArrayRef as ArrowArrayRef; use arrow2::{ - array::{ - Array as Arrow2Array, ListArray, PrimitiveArray as Arrow2PrimitiveArray, - StructArray as Arrow2StructArray, - }, + array::{Array as Arrow2Array, ListArray, StructArray as Arrow2StructArray}, chunk::Chunk as Arrow2Chunk, datatypes::{ DataType as Arrow2Datatype, Field as ArrowField, Metadata as Arrow2Metadata, @@ -450,15 +448,16 @@ impl Chunk { .map(|(timeline, info)| { let TimeColumn { timeline: _, - times, + times: _, is_sorted, time_range: _, } = info; + let nullable = false; // timelines within a single chunk are always dense let field = ArrowField::new( timeline.name().to_string(), - times.data_type().clone(), - false, // timelines within a single chunk are always dense + timeline.datatype().into(), + nullable, ) .with_metadata({ let mut metadata = TransportChunk::field_metadata_time_column(); @@ -468,7 +467,7 @@ impl Chunk { metadata }); - let times = times.clone().boxed() /* cheap */; + let times = info.times_array(); (field, times) }) @@ -478,7 +477,7 @@ impl Chunk { for (field, times) in timelines { schema.fields.push(field); - columns.push(times); + columns.push(times.into()); } } @@ -590,36 +589,17 @@ impl Chunk { } }; - let times = column - .as_any() - .downcast_ref::>() - .ok_or_else(|| ChunkError::Malformed { - reason: format!( - "time column '{}' is not deserializable ({:?})", - field.name, - column.data_type() - ), - })?; - - if times.validity().is_some() { - return Err(ChunkError::Malformed { - reason: format!( - "time column '{}' must be dense ({:?})", - field.name, - column.data_type() - ), - }); - } + let times = TimeColumn::read_array(&ArrowArrayRef::from(column.clone())).map_err( + |err| ChunkError::Malformed { + reason: format!("Bad time column '{}': {err}", field.name), + }, + )?; let is_sorted = field .metadata .contains_key(TransportChunk::FIELD_METADATA_MARKER_IS_SORTED_BY_TIME); - let time_column = TimeColumn::new( - is_sorted.then_some(true), - timeline, - times.clone(), /* cheap */ - ); + let time_column = TimeColumn::new(is_sorted.then_some(true), timeline, times); if timelines.insert(timeline, time_column).is_some() { return Err(ChunkError::Malformed { reason: format!( @@ -735,11 +715,7 @@ mod tests { let timeline1 = Timeline::new_temporal("log_time"); let timelines1 = std::iter::once(( timeline1, - TimeColumn::new( - Some(true), - timeline1, - Arrow2PrimitiveArray::::from_vec(vec![42, 43, 44, 45]), - ), + TimeColumn::new(Some(true), timeline1, vec![42, 43, 44, 45].into()), )) .collect(); diff --git a/crates/store/re_chunk_store/src/dataframe.rs b/crates/store/re_chunk_store/src/dataframe.rs index 906778de5350..0297f77225ed 100644 --- a/crates/store/re_chunk_store/src/dataframe.rs +++ b/crates/store/re_chunk_store/src/dataframe.rs @@ -708,7 +708,7 @@ impl ChunkStore { let timelines = self.all_timelines_sorted().into_iter().map(|timeline| { ColumnDescriptor::Time(TimeColumnDescriptor { timeline, - datatype: timeline.datatype(), + datatype: timeline.datatype().into(), }) }); @@ -782,7 +782,7 @@ impl ChunkStore { TimeColumnDescriptor { timeline, - datatype: timeline.datatype(), + datatype: timeline.datatype().into(), } } diff --git a/crates/store/re_chunk_store/tests/memory_test.rs b/crates/store/re_chunk_store/tests/memory_test.rs index 9af9d5c04ca6..96abe0c5f2b7 100644 --- a/crates/store/re_chunk_store/tests/memory_test.rs +++ b/crates/store/re_chunk_store/tests/memory_test.rs @@ -135,8 +135,8 @@ fn scalar_memory_overhead() { [ format!("{NUM_SCALARS} scalars"), format!( - "{} in total", - re_format::format_bytes(total_mem_use_global as _) + "{} MiB in total", + (total_mem_use_global as f64 / 1024.0 / 1024.0).round() // Round to nearest megabyte - we get fluctuations on the kB depending on platform ), format!( "{} per row", diff --git a/crates/store/re_chunk_store/tests/snapshots/memory_test__scalars_on_one_timeline_new.snap b/crates/store/re_chunk_store/tests/snapshots/memory_test__scalars_on_one_timeline_new.snap index 6d6b6432b176..6d2e21bbc212 100644 --- a/crates/store/re_chunk_store/tests/snapshots/memory_test__scalars_on_one_timeline_new.snap +++ b/crates/store/re_chunk_store/tests/snapshots/memory_test__scalars_on_one_timeline_new.snap @@ -1,9 +1,11 @@ --- source: crates/store/re_chunk_store/tests/memory_test.rs -expression: "[format!(\"{NUM_SCALARS} scalars\"),\n format!(\"{} in total\",\n re_format::format_bytes(total_mem_use_global as _)),\n format!(\"{} per row\",\n re_format::format_bytes(total_mem_use_global as f64 / NUM_SCALARS\n as f64))]" +assertion_line: 133 +expression: "[format!(\"{NUM_SCALARS} scalars\"),\nformat!(\"{} MiB in total\",\n(total_mem_use_global as f64 / 1024.0 / 1024.0).round()),\nformat!(\"{} per row\",\nre_format::format_bytes(total_mem_use_global as f64 / NUM_SCALARS as f64)),]" +snapshot_kind: text --- [ "1048576 scalars", - "37.1 MiB in total", + "37 MiB in total", "37 B per row", ] diff --git a/crates/store/re_data_loader/Cargo.toml b/crates/store/re_data_loader/Cargo.toml index 80ba230cc383..6374634ae26c 100644 --- a/crates/store/re_data_loader/Cargo.toml +++ b/crates/store/re_data_loader/Cargo.toml @@ -35,6 +35,7 @@ re_types = { workspace = true, features = ["image", "video"] } ahash.workspace = true anyhow.workspace = true +arrow.workspace = true arrow2.workspace = true crossbeam.workspace = true image.workspace = true diff --git a/crates/store/re_data_loader/src/loader_archetype.rs b/crates/store/re_data_loader/src/loader_archetype.rs index 7ed62c2d1f28..3e830c8ab776 100644 --- a/crates/store/re_data_loader/src/loader_archetype.rs +++ b/crates/store/re_data_loader/src/loader_archetype.rs @@ -5,7 +5,6 @@ use re_types::components::VideoTimestamp; use re_types::Archetype; use re_types::{components::MediaType, ComponentBatch}; -use arrow2::array::PrimitiveArray as Arrow2PrimitiveArray; use arrow2::Either; use crate::{DataLoader, DataLoaderError, LoadedData}; @@ -193,13 +192,14 @@ fn load_video( Ok(frame_timestamps_ns) => { // Time column. let is_sorted = Some(true); - let time_column_times = Arrow2PrimitiveArray::from_slice(&frame_timestamps_ns); + let frame_timestamps_ns: arrow::buffer::ScalarBuffer = frame_timestamps_ns.into(); let time_column = - re_chunk::TimeColumn::new(is_sorted, video_timeline, time_column_times); + re_chunk::TimeColumn::new(is_sorted, video_timeline, frame_timestamps_ns.clone()); // VideoTimestamp component column. let video_timestamps = frame_timestamps_ns - .into_iter() + .iter() + .copied() .map(VideoTimestamp::from_nanoseconds) .collect::>(); let video_timestamp_batch = &video_timestamps as &dyn ComponentBatch; diff --git a/crates/store/re_dataframe/Cargo.toml b/crates/store/re_dataframe/Cargo.toml index eaaca1a0a58d..185614733cc8 100644 --- a/crates/store/re_dataframe/Cargo.toml +++ b/crates/store/re_dataframe/Cargo.toml @@ -37,6 +37,7 @@ re_types_core.workspace = true # External dependencies: anyhow.workspace = true +arrow.workspace = true arrow2.workspace = true itertools.workspace = true nohash-hasher.workspace = true diff --git a/crates/store/re_dataframe/src/query.rs b/crates/store/re_dataframe/src/query.rs index b3ba686d7705..e998efc7aad0 100644 --- a/crates/store/re_dataframe/src/query.rs +++ b/crates/store/re_dataframe/src/query.rs @@ -6,6 +6,7 @@ use std::{ }, }; +use arrow::buffer::ScalarBuffer as ArrowScalarBuffer; use arrow2::{ array::{ Array as Arrow2Array, BooleanArray as Arrow2BooleanArray, @@ -1133,7 +1134,8 @@ impl QueryHandle { // * return the minimum value instead of the max // * return the exact value for each component (that would be a _lot_ of columns!) // * etc - let mut max_value_per_index = IntMap::default(); + let mut max_value_per_index: IntMap)> = + IntMap::default(); { view_streaming_state .iter() @@ -1158,7 +1160,7 @@ impl QueryHandle { .map(|time| { ( *time_column.timeline(), - (time, time_column.times_array().sliced(cursor, 1)), + (time, time_column.times_buffer().slice(cursor, 1)), ) }) }) @@ -1182,9 +1184,7 @@ impl QueryHandle { state.filtered_index, ( *cur_index_value, - Arrow2PrimitiveArray::::from_vec(vec![cur_index_value.as_i64()]) - .to(state.filtered_index.datatype()) - .to_boxed(), + ArrowScalarBuffer::from(vec![cur_index_value.as_i64()]), ), ); } @@ -1250,7 +1250,13 @@ impl QueryHandle { ColumnDescriptor::Time(descr) => { max_value_per_index.get(&descr.timeline).map_or_else( || arrow2::array::new_null_array(column.datatype(), 1), - |(_time, time_sliced)| time_sliced.clone(), + |(_time, time_sliced)| { + descr + .timeline + .typ() + .make_arrow_array(time_sliced.clone()) + .into() + }, ) } diff --git a/crates/store/re_log_types/src/time_point/mod.rs b/crates/store/re_log_types/src/time_point/mod.rs index 696da3d8cc42..2626fb0b4a88 100644 --- a/crates/store/re_log_types/src/time_point/mod.rs +++ b/crates/store/re_log_types/src/time_point/mod.rs @@ -1,4 +1,7 @@ -use std::collections::{btree_map, BTreeMap}; +use std::{ + collections::{btree_map, BTreeMap}, + sync::Arc, +}; mod non_min_i64; mod time_int; @@ -182,6 +185,29 @@ impl TimeType { pub fn format_range_utc(&self, time_range: ResolvedTimeRange) -> String { self.format_range(time_range, TimeZone::Utc) } + + /// Returns the appropriate arrow datatype to represent this timeline. + #[inline] + pub fn datatype(self) -> arrow::datatypes::DataType { + match self { + Self::Time => { + arrow::datatypes::DataType::Timestamp(arrow::datatypes::TimeUnit::Nanosecond, None) + } + Self::Sequence => arrow::datatypes::DataType::Int64, + } + } + + /// Returns an array with the appropriate datatype. + pub fn make_arrow_array( + self, + times: impl Into>, + ) -> arrow::array::ArrayRef { + let times = times.into(); + match self { + Self::Time => Arc::new(arrow::array::TimestampNanosecondArray::new(times, None)), + Self::Sequence => Arc::new(arrow::array::Int64Array::new(times, None)), + } + } } // ---------------------------------------------------------------------------- diff --git a/crates/store/re_log_types/src/time_point/timeline.rs b/crates/store/re_log_types/src/time_point/timeline.rs index d86463f57cb4..5f3f509966e9 100644 --- a/crates/store/re_log_types/src/time_point/timeline.rs +++ b/crates/store/re_log_types/src/time_point/timeline.rs @@ -1,5 +1,3 @@ -use arrow2::datatypes::{DataType, TimeUnit}; - use crate::{time::TimeZone, ResolvedTimeRange, TimeType}; re_string_interner::declare_new_type!( @@ -100,11 +98,8 @@ impl Timeline { /// Returns the appropriate arrow datatype to represent this timeline. #[inline] - pub fn datatype(&self) -> DataType { - match self.typ { - TimeType::Time => DataType::Timestamp(TimeUnit::Nanosecond, None), - TimeType::Sequence => DataType::Int64, - } + pub fn datatype(&self) -> arrow::datatypes::DataType { + self.typ.datatype() } } diff --git a/crates/top/re_sdk/Cargo.toml b/crates/top/re_sdk/Cargo.toml index 35f9b2f7cc7a..b825292f6f85 100644 --- a/crates/top/re_sdk/Cargo.toml +++ b/crates/top/re_sdk/Cargo.toml @@ -60,7 +60,6 @@ re_sdk_comms = { workspace = true, features = ["client"] } re_types_core.workspace = true ahash.workspace = true -arrow2.workspace = true crossbeam.workspace = true document-features.workspace = true itertools.workspace = true diff --git a/crates/top/re_sdk/src/recording_stream.rs b/crates/top/re_sdk/src/recording_stream.rs index bfe2fb0fc3de..8771691ac47c 100644 --- a/crates/top/re_sdk/src/recording_stream.rs +++ b/crates/top/re_sdk/src/recording_stream.rs @@ -9,12 +9,10 @@ use itertools::Either; use nohash_hasher::IntMap; use parking_lot::Mutex; -use arrow2::array::PrimitiveArray as Arrow2PrimitiveArray; use re_chunk::{ - Chunk, ChunkBatcher, ChunkBatcherConfig, ChunkBatcherError, ChunkComponents, PendingRow, RowId, + Chunk, ChunkBatcher, ChunkBatcherConfig, ChunkBatcherError, ChunkComponents, ChunkError, + ChunkId, PendingRow, RowId, TimeColumn, }; - -use re_chunk::{ChunkError, ChunkId, TimeColumn}; use re_log_types::{ ApplicationId, ArrowChunkReleaseCallback, BlueprintActivationCommand, EntityPath, LogMsg, StoreId, StoreInfo, StoreKind, StoreSource, Time, TimeInt, TimePoint, TimeType, Timeline, @@ -1547,10 +1545,9 @@ impl RecordingStream { let time_timeline = Timeline::log_time(); let time = TimeInt::new_temporal(Time::now().nanos_since_epoch()); - let repeated_time = Arrow2PrimitiveArray::::from_values( - std::iter::repeat(time.as_i64()).take(chunk.num_rows()), - ) - .to(time_timeline.datatype()); + let repeated_time = std::iter::repeat(time.as_i64()) + .take(chunk.num_rows()) + .collect(); let time_column = TimeColumn::new(Some(true), time_timeline, repeated_time); @@ -1571,10 +1568,7 @@ impl RecordingStream { .tick .fetch_add(1, std::sync::atomic::Ordering::Relaxed); - let repeated_tick = Arrow2PrimitiveArray::::from_values( - std::iter::repeat(tick).take(chunk.num_rows()), - ) - .to(tick_timeline.datatype()); + let repeated_tick = std::iter::repeat(tick).take(chunk.num_rows()).collect(); let tick_chunk = TimeColumn::new(Some(true), tick_timeline, repeated_tick); diff --git a/crates/top/rerun_c/Cargo.toml b/crates/top/rerun_c/Cargo.toml index 40dfae4fd7cf..978d6cde38c5 100644 --- a/crates/top/rerun_c/Cargo.toml +++ b/crates/top/rerun_c/Cargo.toml @@ -40,6 +40,7 @@ re_sdk = { workspace = true, features = ["data_loaders"] } re_video.workspace = true ahash.workspace = true +arrow.workspace = true arrow2.workspace = true infer.workspace = true once_cell.workspace = true diff --git a/crates/top/rerun_c/src/lib.rs b/crates/top/rerun_c/src/lib.rs index e90100d2a0b6..2da8b11d97f4 100644 --- a/crates/top/rerun_c/src/lib.rs +++ b/crates/top/rerun_c/src/lib.rs @@ -17,6 +17,7 @@ use std::ffi::{c_char, c_uchar, CString}; use component_type_registry::COMPONENT_TYPES; use once_cell::sync::Lazy; +use arrow::array::ArrayRef as ArrowArrayRef; use arrow_utils::arrow_array_from_c_ffi; use re_sdk::{ external::nohash_hasher::IntMap, @@ -962,15 +963,12 @@ fn rr_recording_stream_send_columns_impl( let timeline: Timeline = time_column.timeline.clone().try_into()?; let datatype = arrow2::datatypes::DataType::Int64; let time_values_untyped = unsafe { arrow_array_from_c_ffi(&time_column.times, datatype) }?; - let time_values = time_values_untyped - .as_any() - .downcast_ref::>() - .ok_or_else(|| { - CError::new( - CErrorCode::ArrowFfiArrayImportError, - "Arrow C FFI import did not produce a Int64 time array - please file an issue at https://github.com/rerun-io/rerun/issues if you see this! This shouldn't be possible since conversion from C was successful with this datatype." - ) - })?; + let time_values = TimeColumn::read_array(&ArrowArrayRef::from(time_values_untyped)).map_err(|err| { + CError::new( + CErrorCode::ArrowFfiArrayImportError, + &format!("Arrow C FFI import did not produce a Int64 time array - please file an issue at https://github.com/rerun-io/rerun/issues if you see this! This shouldn't be possible since conversion from C was successful with this datatype. Details: {err}") + ) + })?; Ok(( timeline, diff --git a/crates/utils/re_byte_size/src/arrow_sizes.rs b/crates/utils/re_byte_size/src/arrow_sizes.rs index 7b9ca72d0fd0..7f8cba0f76dc 100644 --- a/crates/utils/re_byte_size/src/arrow_sizes.rs +++ b/crates/utils/re_byte_size/src/arrow_sizes.rs @@ -1,4 +1,8 @@ -use arrow::array::{Array, ArrayRef}; +use arrow::{ + array::{Array, ArrayRef, ArrowPrimitiveType, PrimitiveArray}, + buffer::ScalarBuffer, + datatypes::ArrowNativeType, +}; use super::SizeBytes; @@ -15,3 +19,17 @@ impl SizeBytes for ArrayRef { self.get_array_memory_size() as u64 } } + +impl SizeBytes for PrimitiveArray { + #[inline] + fn heap_size_bytes(&self) -> u64 { + Array::get_array_memory_size(self) as u64 + } +} + +impl SizeBytes for ScalarBuffer { + #[inline] + fn heap_size_bytes(&self) -> u64 { + self.inner().capacity() as _ + } +} diff --git a/crates/viewer/re_view_dataframe/src/display_record_batch.rs b/crates/viewer/re_view_dataframe/src/display_record_batch.rs index 671326e0a412..a1eddc1c3dd5 100644 --- a/crates/viewer/re_view_dataframe/src/display_record_batch.rs +++ b/crates/viewer/re_view_dataframe/src/display_record_batch.rs @@ -1,17 +1,18 @@ //! Intermediate data structures to make `re_datastore`'s row data more amenable to displaying in a //! table. +use arrow::buffer::ScalarBuffer as ArrowScalarBuffer; use arrow::{ array::{ Array as ArrowArray, ArrayRef as ArrowArrayRef, - Int32DictionaryArray as ArrowInt32DictionaryArray, Int64Array as ArrowInt64Array, - ListArray as ArrowListArray, TimestampNanosecondArray as ArrowTimestampNanosecondArray, + Int32DictionaryArray as ArrowInt32DictionaryArray, ListArray as ArrowListArray, }, datatypes::DataType as ArrowDataType, }; use thiserror::Error; use re_chunk_store::{ColumnDescriptor, ComponentColumnDescriptor, LatestAtQuery}; +use re_dataframe::external::re_chunk::{TimeColumn, TimeColumnError}; use re_log_types::{EntityPath, TimeInt, Timeline}; use re_types_core::ComponentName; use re_ui::UiExt; @@ -19,8 +20,11 @@ use re_viewer_context::{UiLayout, ViewerContext}; #[derive(Error, Debug)] pub(crate) enum DisplayRecordBatchError { - #[error("Unexpected column data type for timeline '{0}': {1:?}")] - UnexpectedTimeColumnDataType(String, ArrowDataType), + #[error("Bad column for timeline '{timeline}': {error}")] + BadTimeColumn { + timeline: String, + error: TimeColumnError, + }, #[error("Unexpected column data type for component '{0}': {1:?}")] UnexpectedComponentColumnDataType(String, ArrowDataType), @@ -165,7 +169,7 @@ impl ComponentData { pub(crate) enum DisplayColumn { Timeline { timeline: Timeline, - time_data: ArrowInt64Array, + time_data: ArrowScalarBuffer, }, Component { entity_path: EntityPath, @@ -179,39 +183,15 @@ impl DisplayColumn { column_descriptor: &ColumnDescriptor, column_data: &ArrowArrayRef, ) -> Result { - fn int64_from_nanoseconds( - duration_array: &ArrowTimestampNanosecondArray, - ) -> Option { - let data = duration_array.to_data(); - let buffer = data.buffers().first()?.clone(); - arrow::array::ArrayData::builder(arrow::datatypes::DataType::Int64) - .len(duration_array.len()) - .add_buffer(buffer) - .build() - .ok() - .map(ArrowInt64Array::from) - } - match column_descriptor { ColumnDescriptor::Time(desc) => { let timeline = desc.timeline; - // Sequence timelines are i64, but time columns are nanoseconds (also as i64) - let time_data_result = column_data - .as_any() - .downcast_ref::() - .cloned() - .or_else(|| { - column_data - .as_any() - .downcast_ref::() - .and_then(int64_from_nanoseconds) - }); - let time_data = time_data_result.ok_or_else(|| { - DisplayRecordBatchError::UnexpectedTimeColumnDataType( - timeline.name().as_str().to_owned(), - column_data.data_type().to_owned(), - ) + let time_data = TimeColumn::read_array(column_data).map_err(|err| { + DisplayRecordBatchError::BadTimeColumn { + timeline: timeline.name().as_str().to_owned(), + error: err, + } })?; Ok(Self::Timeline { @@ -266,9 +246,8 @@ impl DisplayColumn { return; } - if time_data.is_valid(row_index) { - let timestamp = TimeInt::try_from(time_data.value(row_index)); - match timestamp { + if let Some(value) = time_data.get(row_index) { + match TimeInt::try_from(*value) { Ok(timestamp) => { ui.label(timeline.typ().format(timestamp, ctx.app_options.time_zone)); } @@ -304,8 +283,8 @@ impl DisplayColumn { pub(crate) fn try_decode_time(&self, row_index: usize) -> Option { match self { Self::Timeline { time_data, .. } => { - let timestamp = time_data.value(row_index); - TimeInt::try_from(timestamp).ok() + let timestamp = time_data.get(row_index)?; + TimeInt::try_from(*timestamp).ok() } Self::Component { .. } => None, } diff --git a/rerun_py/src/arrow.rs b/rerun_py/src/arrow.rs index 04c6ea735e03..e150be7fc33b 100644 --- a/rerun_py/src/arrow.rs +++ b/rerun_py/src/arrow.rs @@ -3,11 +3,11 @@ use std::borrow::Cow; use arrow::{ - array::{make_array, ArrayData}, + array::{make_array, ArrayData, ArrayRef as ArrowArrayRef}, pyarrow::PyArrowType, }; use arrow2::{ - array::{Array, ListArray, PrimitiveArray}, + array::{Array, ListArray}, datatypes::Field, offset::Offsets, }; @@ -121,7 +121,13 @@ pub fn build_chunk_from_components( let timelines: Result, ChunkError> = arrays .into_iter() .zip(fields) - .map(|(value, field)| { + .map(|(array, field)| { + let timeline_data = + TimeColumn::read_array(&ArrowArrayRef::from(array)).map_err(|err| { + ChunkError::Malformed { + reason: format!("Invalid timeline {}: {err}", field.name), + } + })?; let timeline = match field.data_type() { arrow2::datatypes::DataType::Int64 => { Ok(Timeline::new_sequence(field.name.clone())) @@ -133,13 +139,6 @@ pub fn build_chunk_from_components( reason: format!("Invalid data_type for timeline: {}", field.name), }), }?; - let timeline_data = value - .as_any() - .downcast_ref::>() - .ok_or_else(|| ChunkError::Malformed { - reason: format!("Invalid primitive array for timeline: {}", field.name), - })? - .clone(); Ok((timeline, timeline_data)) }) .collect(); From 38cc75b7f715c9cbcc62e9628bb2535734e1e490 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Sat, 11 Jan 2025 13:05:58 +0100 Subject: [PATCH 03/57] Filter entities in the UI (part 0): Make `CustomContent` more useful (#8645) --- .../src/item_heading_no_breadcrumbs.rs | 15 +- .../src/item_heading_with_breadcrumbs.rs | 49 ++--- .../src/view_entity_picker.rs | 10 +- .../examples/re_ui_example/right_panel.rs | 20 +- .../re_ui/src/list_item/custom_content.rs | 179 ++++++++++++++++++ .../{other_contents.rs => debug_content.rs} | 32 ---- crates/viewer/re_ui/src/list_item/mod.rs | 6 +- .../re_ui/src/list_item/property_content.rs | 4 +- crates/viewer/re_ui/tests/list_item_tests.rs | 26 ++- .../re_ui/tests/snapshots/list_items.png | 4 +- 10 files changed, 249 insertions(+), 96 deletions(-) create mode 100644 crates/viewer/re_ui/src/list_item/custom_content.rs rename crates/viewer/re_ui/src/list_item/{other_contents.rs => debug_content.rs} (51%) diff --git a/crates/viewer/re_selection_panel/src/item_heading_no_breadcrumbs.rs b/crates/viewer/re_selection_panel/src/item_heading_no_breadcrumbs.rs index c78d2176e8d4..366b3be55bc8 100644 --- a/crates/viewer/re_selection_panel/src/item_heading_no_breadcrumbs.rs +++ b/crates/viewer/re_selection_panel/src/item_heading_no_breadcrumbs.rs @@ -24,17 +24,10 @@ pub fn item_title_list_item( .interactive(true) .show_flat( ui, - list_item::CustomContent::new(|ui, context| { - ui.allocate_new_ui( - egui::UiBuilder::new() - .max_rect(context.rect) - .layout(egui::Layout::left_to_right(egui::Align::Center)), - |ui| { - ui.spacing_mut().item_spacing.x = 4.0; - ui.style_mut().interaction.selectable_labels = false; - item_heading_no_breadcrumbs(ctx, viewport, ui, item); - }, - ); + list_item::CustomContent::new(|ui, _| { + ui.spacing_mut().item_spacing.x = 4.0; + ui.style_mut().interaction.selectable_labels = false; + item_heading_no_breadcrumbs(ctx, viewport, ui, item); }), ); cursor_interact_with_selectable(ctx, response, item.clone()); diff --git a/crates/viewer/re_selection_panel/src/item_heading_with_breadcrumbs.rs b/crates/viewer/re_selection_panel/src/item_heading_with_breadcrumbs.rs index a006a2eac302..fc8315e41155 100644 --- a/crates/viewer/re_selection_panel/src/item_heading_with_breadcrumbs.rs +++ b/crates/viewer/re_selection_panel/src/item_heading_with_breadcrumbs.rs @@ -37,37 +37,30 @@ pub fn item_heading_with_breadcrumbs( .selected(true) .show_flat( ui, - list_item::CustomContent::new(|ui, context| { - ui.allocate_new_ui( - egui::UiBuilder::new() - .max_rect(context.rect) - .layout(egui::Layout::left_to_right(egui::Align::Center)), - |ui| { - ui.spacing_mut().item_spacing.x = 4.0; + list_item::CustomContent::new(|ui, _| { + ui.spacing_mut().item_spacing.x = 4.0; - { - // No background rectangles, even for hovered items - let visuals = ui.visuals_mut(); - visuals.widgets.active.bg_fill = egui::Color32::TRANSPARENT; - visuals.widgets.active.weak_bg_fill = egui::Color32::TRANSPARENT; - visuals.widgets.hovered.bg_fill = egui::Color32::TRANSPARENT; - visuals.widgets.hovered.weak_bg_fill = egui::Color32::TRANSPARENT; - } + { + // No background rectangles, even for hovered items + let visuals = ui.visuals_mut(); + visuals.widgets.active.bg_fill = egui::Color32::TRANSPARENT; + visuals.widgets.active.weak_bg_fill = egui::Color32::TRANSPARENT; + visuals.widgets.hovered.bg_fill = egui::Color32::TRANSPARENT; + visuals.widgets.hovered.weak_bg_fill = egui::Color32::TRANSPARENT; + } - // First the C>R>U>M>B>S> - { - let previous_style = ui.style().clone(); - // Dimmer colors for breadcrumbs - let visuals = ui.visuals_mut(); - visuals.widgets.inactive.fg_stroke.color = egui::hex_color!("#6A8CD0"); // TODO(#3133): use design tokens - item_bread_crumbs_ui(ctx, viewport, ui, item); - ui.set_style(previous_style); - } + // First the C>R>U>M>B>S> + { + let previous_style = ui.style().clone(); + // Dimmer colors for breadcrumbs + let visuals = ui.visuals_mut(); + visuals.widgets.inactive.fg_stroke.color = egui::hex_color!("#6A8CD0"); // TODO(#3133): use design tokens + item_bread_crumbs_ui(ctx, viewport, ui, item); + ui.set_style(previous_style); + } - // Then the full name of the main item: - last_part_of_item_heading(ctx, viewport, ui, item); - }, - ); + // Then the full name of the main item: + last_part_of_item_heading(ctx, viewport, ui, item); }), ); } diff --git a/crates/viewer/re_selection_panel/src/view_entity_picker.rs b/crates/viewer/re_selection_panel/src/view_entity_picker.rs index 74ed964631bc..65cebadc678d 100644 --- a/crates/viewer/re_selection_panel/src/view_entity_picker.rs +++ b/crates/viewer/re_selection_panel/src/view_entity_picker.rs @@ -90,15 +90,10 @@ fn add_entities_tree_ui( entity_path_filter: &ResolvedEntityPathFilter, entities_add_info: &IntMap, ) { - let item_content = list_item::CustomContent::new(|ui, content_ctx| { - let mut child_ui = ui.new_child( - egui::UiBuilder::new() - .max_rect(content_ctx.rect) - .layout(egui::Layout::left_to_right(egui::Align::Center)), - ); + let item_content = list_item::CustomContent::new(|ui, _| { add_entities_line_ui( ctx, - &mut child_ui, + ui, name, tree, view, @@ -191,6 +186,7 @@ fn add_entities_line_ui( } }); + //TODO(ab): use `CustomContent` support for action button to implement this. ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { if entity_path_filter.contains_rule_for_exactly(entity_path) { // Reset-button diff --git a/crates/viewer/re_ui/examples/re_ui_example/right_panel.rs b/crates/viewer/re_ui/examples/re_ui_example/right_panel.rs index 680015615141..5787dcf8aae4 100644 --- a/crates/viewer/re_ui/examples/re_ui_example/right_panel.rs +++ b/crates/viewer/re_ui/examples/re_ui_example/right_panel.rs @@ -324,14 +324,28 @@ impl RightPanel { ui.list_item().show_hierarchical( ui, - list_item::CustomContent::new(|ui, context| { + list_item::CustomContent::new(|ui, _| { ui.ctx().debug_painter().debug_rect( - context.rect, + ui.max_rect(), egui::Color32::LIGHT_RED, "CustomContent delegates to a closure", ); }), - ) + ); + + ui.list_item().show_hierarchical( + ui, + list_item::CustomContent::new(|ui, _| { + ui.ctx().debug_painter().debug_rect( + ui.max_rect(), + egui::Color32::LIGHT_RED, + "CustomContent with an action button", + ); + }) + .action_button(&re_ui::icons::ADD, || { + re_log::warn!("Add button clicked"); + }), + ); }, ); } diff --git a/crates/viewer/re_ui/src/list_item/custom_content.rs b/crates/viewer/re_ui/src/list_item/custom_content.rs new file mode 100644 index 000000000000..31a85cc9a8ab --- /dev/null +++ b/crates/viewer/re_ui/src/list_item/custom_content.rs @@ -0,0 +1,179 @@ +use egui::{NumExt as _, Ui}; + +use crate::list_item::{ContentContext, DesiredWidth, ListItemContent}; +use crate::DesignTokens; + +/// Control how the [`CustomContent`] advertises its width. +#[derive(Debug, Clone, Copy)] +enum CustomContentDesiredWidth { + /// Use the provided [`DesiredWidth`]. + DesiredWidth(DesiredWidth), + + /// Use [`DesiredWidth::AtLeast`] with a width computed from the provided content, plus any + /// extras such as a button. + ContentWidth(f32), +} + +impl Default for CustomContentDesiredWidth { + fn default() -> Self { + Self::DesiredWidth(Default::default()) + } +} + +/// [`ListItemContent`] that mostly delegates to a closure. +#[expect(clippy::type_complexity)] +pub struct CustomContent<'a> { + ui: Box) + 'a>, + desired_width: CustomContentDesiredWidth, + + //TODO(ab): in the future, that should be a `Vec`, with some auto expanding mini-toolbar + button: Option>, +} + +impl<'a> CustomContent<'a> { + /// Create a content with a custom UI closure. + /// + /// The closure will be called from within a [`egui::Ui`] with its maximum width set as per the + /// list item geometry. Note that this may differ from [`ContentContext::rect`] if a button is + /// set. + pub fn new(ui: impl FnOnce(&mut egui::Ui, &ContentContext<'_>) + 'a) -> Self { + Self { + ui: Box::new(ui), + desired_width: Default::default(), + button: None, + } + } + + /// Set the desired width for the entire content. + #[inline] + pub fn with_desired_width(mut self, desired_width: DesiredWidth) -> Self { + self.desired_width = CustomContentDesiredWidth::DesiredWidth(desired_width); + self + } + + /// Set the desired width based on the provided content width. If a button is set, its width + /// will be taken into account and added to the content width. + #[inline] + pub fn with_content_width(mut self, desired_content_width: f32) -> Self { + self.desired_width = CustomContentDesiredWidth::ContentWidth(desired_content_width); + self + } + + /// Add a right-aligned [`super::ItemButton`]. + /// + /// Note: for aesthetics, space is always reserved for the action button. + // TODO(#6191): accept multiple calls for this function for multiple actions. + #[inline] + pub fn button(mut self, button: impl super::ItemButton + 'a) -> Self { + // TODO(#6191): support multiple action buttons + assert!( + self.button.is_none(), + "Only one action button is supported right now" + ); + + self.button = Some(Box::new(button)); + self + } + + /// Helper to add an [`super::ItemActionButton`] to the right of the item. + /// + /// See [`Self::button`] for more information. + #[inline] + pub fn action_button( + self, + icon: &'static crate::icons::Icon, + on_click: impl FnOnce() + 'a, + ) -> Self { + self.action_button_with_enabled(icon, true, on_click) + } + + /// Helper to add an enabled/disabled [`super::ItemActionButton`] to the right of the item. + /// + /// See [`Self::button`] for more information. + #[inline] + pub fn action_button_with_enabled( + self, + icon: &'static crate::icons::Icon, + enabled: bool, + on_click: impl FnOnce() + 'a, + ) -> Self { + self.button(super::ItemActionButton::new(icon, on_click).enabled(enabled)) + } + + /// Helper to add a [`super::ItemMenuButton`] to the right of the item. + /// + /// See [`Self::button`] for more information. + #[inline] + pub fn menu_button( + self, + icon: &'static crate::icons::Icon, + add_contents: impl FnOnce(&mut egui::Ui) + 'a, + ) -> Self { + self.button(super::ItemMenuButton::new(icon, add_contents)) + } +} + +impl ListItemContent for CustomContent<'_> { + fn ui(self: Box, ui: &mut egui::Ui, context: &ContentContext<'_>) { + let Self { + ui: content_ui, + desired_width: _, + button, + } = *self; + + let button_dimension = + DesignTokens::small_icon_size().x + 2.0 * ui.spacing().button_padding.x; + + let content_width = if button.is_some() { + (context.rect.width() - button_dimension - DesignTokens::text_to_icon_padding()) + .at_least(0.0) + } else { + context.rect.width() + }; + + let content_rect = egui::Rect::from_min_size( + context.rect.min, + egui::vec2(content_width, context.rect.height()), + ); + + ui.allocate_new_ui( + egui::UiBuilder::new() + .max_rect(content_rect) + .layout(egui::Layout::left_to_right(egui::Align::Center)), + |ui| { + content_ui(ui, context); + }, + ); + + if let Some(button) = button { + let action_button_rect = egui::Rect::from_center_size( + context.rect.right_center() - egui::vec2(button_dimension / 2.0, 0.0), + egui::Vec2::splat(button_dimension), + ); + + // the right to left layout is used to mimic LabelContent's buttons behavior and get a + // better alignment + let mut child_ui = ui.new_child( + egui::UiBuilder::new() + .max_rect(action_button_rect) + .layout(egui::Layout::right_to_left(egui::Align::Center)), + ); + + button.ui(&mut child_ui); + } + } + + fn desired_width(&self, ui: &Ui) -> DesiredWidth { + match self.desired_width { + CustomContentDesiredWidth::DesiredWidth(desired_width) => desired_width, + CustomContentDesiredWidth::ContentWidth(mut content_width) => { + if self.button.is_some() { + content_width += DesignTokens::small_icon_size().x + + 2.0 * ui.spacing().button_padding.x + + DesignTokens::text_to_icon_padding(); + } + DesiredWidth::AtLeast(content_width) + } + } + } +} diff --git a/crates/viewer/re_ui/src/list_item/other_contents.rs b/crates/viewer/re_ui/src/list_item/debug_content.rs similarity index 51% rename from crates/viewer/re_ui/src/list_item/other_contents.rs rename to crates/viewer/re_ui/src/list_item/debug_content.rs index 30d5141a2f57..1916b26b3905 100644 --- a/crates/viewer/re_ui/src/list_item/other_contents.rs +++ b/crates/viewer/re_ui/src/list_item/debug_content.rs @@ -2,38 +2,6 @@ use egui::Ui; use crate::list_item::{ContentContext, DesiredWidth, ListItemContent}; -/// [`ListItemContent`] that delegates to a closure. -#[allow(clippy::type_complexity)] -pub struct CustomContent<'a> { - ui: Box) + 'a>, - desired_width: DesiredWidth, -} - -impl<'a> CustomContent<'a> { - pub fn new(ui: impl FnOnce(&mut egui::Ui, &ContentContext<'_>) + 'a) -> Self { - Self { - ui: Box::new(ui), - desired_width: Default::default(), - } - } - - #[inline] - pub fn with_desired_width(mut self, desired_width: DesiredWidth) -> Self { - self.desired_width = desired_width; - self - } -} - -impl ListItemContent for CustomContent<'_> { - fn ui(self: Box, ui: &mut egui::Ui, context: &ContentContext<'_>) { - (self.ui)(ui, context); - } - - fn desired_width(&self, _ui: &Ui) -> DesiredWidth { - self.desired_width - } -} - /// [`ListItemContent`] that displays the content rect. #[derive(Debug, Clone, Default)] pub struct DebugContent { diff --git a/crates/viewer/re_ui/src/list_item/mod.rs b/crates/viewer/re_ui/src/list_item/mod.rs index 80178875716f..fd09e3c74742 100644 --- a/crates/viewer/re_ui/src/list_item/mod.rs +++ b/crates/viewer/re_ui/src/list_item/mod.rs @@ -3,19 +3,21 @@ //! TODO(ab): provide some top-level documentation here. mod button_content; +mod custom_content; +mod debug_content; mod item_button; mod label_content; #[allow(clippy::module_inception)] mod list_item; -mod other_contents; mod property_content; mod scope; pub use button_content::*; +pub use custom_content::*; +pub use debug_content::*; pub use item_button::*; pub use label_content::*; pub use list_item::*; -pub use other_contents::*; pub use property_content::*; pub use scope::*; diff --git a/crates/viewer/re_ui/src/list_item/property_content.rs b/crates/viewer/re_ui/src/list_item/property_content.rs index ebe1ea4c5a03..c081ff1cd9d4 100644 --- a/crates/viewer/re_ui/src/list_item/property_content.rs +++ b/crates/viewer/re_ui/src/list_item/property_content.rs @@ -42,7 +42,7 @@ impl<'a> PropertyContent<'a> { /// Set the minimum desired width for the entire content. /// - /// Since there is no possibly way to meaningfully collapse two to three columns worth of + /// Since there is no possible way to meaningfully collapse two to three columns worth of /// content, this is set to 200.0 by default. #[inline] pub fn min_desired_width(mut self, min_desired_width: f32) -> Self { @@ -78,7 +78,7 @@ impl<'a> PropertyContent<'a> { // TODO(#6191): support multiple action buttons assert!( self.button.is_none(), - "Only one action button supported right now" + "Only one action button is supported right now" ); self.button = Some(Box::new(button)); diff --git a/crates/viewer/re_ui/tests/list_item_tests.rs b/crates/viewer/re_ui/tests/list_item_tests.rs index 86db31082935..95a00c96cfcc 100644 --- a/crates/viewer/re_ui/tests/list_item_tests.rs +++ b/crates/viewer/re_ui/tests/list_item_tests.rs @@ -143,9 +143,7 @@ pub fn test_list_items_should_match_snapshot() { ui, list_item::PropertyContent::new("Color") .with_icon(&re_ui::icons::VIEW_TEXT) - .action_button(&re_ui::icons::ADD, || { - re_log::warn!("Add button clicked"); - }) + .action_button(&re_ui::icons::ADD, || {}) .value_color(&color), ); @@ -153,9 +151,7 @@ pub fn test_list_items_should_match_snapshot() { ui, list_item::PropertyContent::new("Color (editable)") .with_icon(&re_ui::icons::VIEW_TEXT) - .action_button(&re_ui::icons::ADD, || { - re_log::warn!("Add button clicked"); - }) + .action_button(&re_ui::icons::ADD, || {}) .value_color_mut(&mut color), ); }); @@ -176,14 +172,26 @@ pub fn test_list_items_should_match_snapshot() { ui.list_item().show_hierarchical( ui, - list_item::CustomContent::new(|ui, context| { + list_item::CustomContent::new(|ui, _| { ui.ctx().debug_painter().debug_rect( - context.rect, + ui.max_rect(), egui::Color32::LIGHT_RED, "CustomContent delegates to a closure", ); }), - ) + ); + + ui.list_item().show_hierarchical( + ui, + list_item::CustomContent::new(|ui, _| { + ui.ctx().debug_painter().debug_rect( + ui.max_rect(), + egui::Color32::LIGHT_RED, + "CustomContent with an action button", + ); + }) + .action_button(&re_ui::icons::ADD, || {}), + ); }, ); }; diff --git a/crates/viewer/re_ui/tests/snapshots/list_items.png b/crates/viewer/re_ui/tests/snapshots/list_items.png index 92329ffe8c55..a77e07f76e98 100644 --- a/crates/viewer/re_ui/tests/snapshots/list_items.png +++ b/crates/viewer/re_ui/tests/snapshots/list_items.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f8c3f52449a6240d67c66c9a04793742dc3b02380c7482ada8cc0f8be315968d -size 84773 +oid sha256:086ea1d934e76962279b3d5b57fa0afdb626587ff4b302597d70ca7e2626df38 +size 89533 From 0e264849e81bd420a030dd1f626d526e63fc899d Mon Sep 17 00:00:00 2001 From: Zeljko Mihaljcic <7150613+zehiko@users.noreply.github.com> Date: Mon, 13 Jan 2025 09:17:36 +0100 Subject: [PATCH 04/57] Add support for ReDap catalog projection and filtering to python SDK (#8629) --- examples/python/remote/metadata.py | 8 +++-- rerun_py/rerun_bindings/rerun_bindings.pyi | 16 ++++++++-- rerun_py/src/remote.rs | 37 +++++++++++++++++----- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/examples/python/remote/metadata.py b/examples/python/remote/metadata.py index 68d322bdd66c..188d46e81e91 100644 --- a/examples/python/remote/metadata.py +++ b/examples/python/remote/metadata.py @@ -23,14 +23,16 @@ register_cmd.add_argument("storage_url", help="Storage URL to register") + print_cmd.add_argument("--columns", nargs="*", help="Define which columns to print") + print_cmd.add_argument("--recording-ids", nargs="*", help="Select specific recordings to print") + args = parser.parse_args() # Register the new rrd conn = rr.remote.connect("http://0.0.0.0:51234") - catalog = pl.from_arrow(conn.query_catalog().read_all()) - if args.subcommand == "print": + catalog = pl.from_arrow(conn.query_catalog(args.columns, args.recording_ids).read_all()) print(catalog) elif args.subcommand == "register": @@ -39,6 +41,8 @@ print(f"Registered new recording with ID: {id}") elif args.subcommand == "update": + catalog = pl.from_arrow(conn.query_catalog().read_all()) + id = ( catalog.filter(catalog["rerun_recording_id"].str.starts_with(args.id)) .select(pl.first("rerun_recording_id")) diff --git a/rerun_py/rerun_bindings/rerun_bindings.pyi b/rerun_py/rerun_bindings/rerun_bindings.pyi index 2420615ec2d9..05a419764dfd 100644 --- a/rerun_py/rerun_bindings/rerun_bindings.pyi +++ b/rerun_py/rerun_bindings/rerun_bindings.pyi @@ -577,8 +577,20 @@ class StorageNodeClient: Required-feature: `remote` """ - def query_catalog(self) -> pa.RecordBatchReader: - """Get the metadata for all recordings in the storage node.""" + def query_catalog( + self, columns: Optional[list[str]] = None, recording_ids: Optional[list[str]] = None + ) -> pa.RecordBatchReader: + """ + Get the metadata recordings in the storage node. + + Parameters + ---------- + columns : Optional[list[str]], optional + The columns to include in the output, by default None. + recording_ids : Optional[list[str]] + Filter specific recordings by Recording Id + + """ ... def register(self, storage_url: str, metadata: Optional[TableLike] = None) -> str: diff --git a/rerun_py/src/remote.rs b/rerun_py/src/remote.rs index 49f6cd9872de..87073ae9bafc 100644 --- a/rerun_py/src/remote.rs +++ b/rerun_py/src/remote.rs @@ -24,9 +24,9 @@ use re_log_types::{EntityPathFilter, StoreInfo, StoreSource}; use re_protos::{ common::v0::RecordingId, remote_store::v0::{ - storage_node_client::StorageNodeClient, CatalogFilter, FetchRecordingRequest, - QueryCatalogRequest, QueryRequest, RecordingType, RegisterRecordingRequest, - UpdateCatalogRequest, + storage_node_client::StorageNodeClient, CatalogFilter, ColumnProjection, + FetchRecordingRequest, QueryCatalogRequest, QueryRequest, RecordingType, + RegisterRecordingRequest, UpdateCatalogRequest, }, }; use re_sdk::{ApplicationId, ComponentName, StoreId, StoreKind, Time, Timeline}; @@ -190,13 +190,34 @@ impl PyStorageNodeClient { #[pymethods] impl PyStorageNodeClient { - /// Get the metadata for all recordings in the storage node. - fn query_catalog(&mut self) -> PyResult>> { + /// Get the metadata for recordings in the storage node. + /// + /// Parameters + /// ---------- + /// columns : Optional[list[str]] + /// The columns to fetch. If `None`, fetch all columns. + /// recording_ids : Optional[list[str]] + /// Fetch metadata of only specific recordings. If `None`, fetch for all. + #[pyo3(signature = ( + columns = None, + recording_ids = None, + ))] + fn query_catalog( + &mut self, + columns: Option>, + recording_ids: Option>, + ) -> PyResult>> { let reader = self.runtime.block_on(async { - // TODO(jleibs): Support column projection and filtering + let column_projection = columns.map(|columns| ColumnProjection { columns }); + let filter = recording_ids.map(|recording_ids| CatalogFilter { + recording_ids: recording_ids + .into_iter() + .map(|id| RecordingId { id }) + .collect(), + }); let request = QueryCatalogRequest { - column_projection: None, - filter: None, + column_projection, + filter, }; let transport_chunks = self From c171b04c9ad20fdd456c411182d78b0c42fb5a26 Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Mon, 13 Jan 2025 09:18:03 +0100 Subject: [PATCH 05/57] New types and traits for (co-existing!) eager serialization (#8642) This introduces `SerializedComponentBatch`, which will become the main type we use to carry user data around internally. ```rust /// The serialized contents of a [`ComponentBatch`] with associated [`ComponentDescriptor`]. /// /// This is what gets logged into Rerun: /// * See [`ComponentBatch`] to easily serialize component data. /// * See [`AsComponents`] for logging serialized data. /// /// [`AsComponents`]: [crate::AsComponents] #[derive(Debug, Clone)] pub struct SerializedComponentBatch { pub array: arrow::array::ArrayRef, // TODO(cmc): Maybe Cow<> this one if it grows bigger. Or intern descriptors altogether, most likely. pub descriptor: ComponentDescriptor, } ``` The goal is to keep the `ComponentBatch` trait isolated at the edge, where it is used as a means of easily converting any data into arrow arrays, instead of simultaneously being used as a means of transporting data around through the internals. `ComponentBatch` is here to stay, if only for its conversion capabilities. This opens a lot of opportunities of improvements in terms of DX, UX and future features (e.g. generics). The two code paths will co-exist for the foreseeable future, until all archetypes have been made eager. * Part of https://github.com/rerun-io/rerun/issues/7245 --- crates/store/re_chunk/src/builder.rs | 65 +++++- crates/store/re_entity_db/tests/clear.rs | 32 +-- .../store/re_types_core/src/as_components.rs | 203 +++++++++--------- crates/store/re_types_core/src/lib.rs | 1 + .../store/re_types_core/src/loggable_batch.rs | 154 ++++++++++++- crates/top/re_sdk/src/lib.rs | 1 + crates/top/re_sdk/src/recording_stream.rs | 93 +++++++- .../descriptors/descr_builtin_component.rs | 5 +- .../all/descriptors/descr_custom_component.rs | 15 +- docs/snippets/all/tutorials/custom_data.rs | 25 +-- scripts/ci/check_large_files.py | 1 + 11 files changed, 420 insertions(+), 175 deletions(-) diff --git a/crates/store/re_chunk/src/builder.rs b/crates/store/re_chunk/src/builder.rs index 279aa625a223..e08e20132fab 100644 --- a/crates/store/re_chunk/src/builder.rs +++ b/crates/store/re_chunk/src/builder.rs @@ -3,7 +3,7 @@ use itertools::Itertools; use nohash_hasher::IntMap; use re_log_types::{EntityPath, TimeInt, TimePoint, Timeline}; -use re_types_core::{AsComponents, ComponentBatch, ComponentDescriptor}; +use re_types_core::{AsComponents, ComponentBatch, ComponentDescriptor, SerializedComponentBatch}; use crate::{arrow_util, chunk::ChunkComponents, Chunk, ChunkId, ChunkResult, RowId, TimeColumn}; @@ -121,14 +121,8 @@ impl ChunkBuilder { timepoint: impl Into, as_components: &dyn AsComponents, ) -> Self { - let batches = as_components.as_component_batches(); - self.with_component_batches( - row_id, - timepoint, - batches - .iter() - .map(|batch| batch as &dyn re_types_core::ComponentBatch), - ) + let batches = as_components.as_serialized_batches(); + self.with_serialized_batches(row_id, timepoint, batches) } /// Add a row's worth of data by serializing a single [`ComponentBatch`]. @@ -193,6 +187,59 @@ impl ChunkBuilder { ) } + /// Add a row's worth of data by serializing a single [`ComponentBatch`]. + #[inline] + pub fn with_serialized_batch( + self, + row_id: RowId, + timepoint: impl Into, + component_batch: SerializedComponentBatch, + ) -> Self { + self.with_row( + row_id, + timepoint, + [(component_batch.descriptor, component_batch.array)], + ) + } + + /// Add a row's worth of data by serializing many [`ComponentBatch`]es. + #[inline] + pub fn with_serialized_batches( + self, + row_id: RowId, + timepoint: impl Into, + component_batches: impl IntoIterator, + ) -> Self { + self.with_row( + row_id, + timepoint, + component_batches + .into_iter() + .map(|component_batch| (component_batch.descriptor, component_batch.array)), + ) + } + + /// Add a row's worth of data by serializing many sparse [`ComponentBatch`]es. + #[inline] + pub fn with_sparse_serialized_batches( + self, + row_id: RowId, + timepoint: impl Into, + component_batches: impl IntoIterator< + Item = (ComponentDescriptor, Option), + >, + ) -> Self { + self.with_sparse_row( + row_id, + timepoint, + component_batches + .into_iter() + .map(|(component_desc, component_batch)| { + (component_desc, component_batch.map(|batch| batch.array)) + }), + ) + } + /// Builds and returns the final [`Chunk`]. /// /// The arrow datatype of each individual column will be guessed by inspecting the data. diff --git a/crates/store/re_entity_db/tests/clear.rs b/crates/store/re_entity_db/tests/clear.rs index c72944b49b82..dbbb4a78927b 100644 --- a/crates/store/re_entity_db/tests/clear.rs +++ b/crates/store/re_entity_db/tests/clear.rs @@ -122,14 +122,7 @@ fn clears() -> anyhow::Result<()> { let timepoint = TimePoint::from_iter([(timeline_frame, 10)]); let clear = Clear::flat(); let chunk = Chunk::builder(entity_path_parent.clone()) - .with_component_batches( - row_id, - timepoint, - clear - .as_component_batches() - .iter() - .map(|b| b as &dyn re_types_core::ComponentBatch), - ) + .with_serialized_batches(row_id, timepoint, clear.as_serialized_batches()) .build()?; db.add_chunk(&Arc::new(chunk))?; @@ -163,14 +156,7 @@ fn clears() -> anyhow::Result<()> { let timepoint = TimePoint::from_iter([(timeline_frame, 10)]); let clear = Clear::recursive(); let chunk = Chunk::builder(entity_path_parent.clone()) - .with_component_batches( - row_id, - timepoint, - clear - .as_component_batches() - .iter() - .map(|b| b as &dyn re_types_core::ComponentBatch), - ) + .with_serialized_batches(row_id, timepoint, clear.as_serialized_batches()) .build()?; db.add_chunk(&Arc::new(chunk))?; @@ -351,13 +337,10 @@ fn clears_respect_index_order() -> anyhow::Result<()> { let clear = Clear::recursive(); let chunk = Chunk::builder(entity_path.clone()) - .with_component_batches( + .with_serialized_batches( row_id1, // older row id! timepoint.clone(), - clear - .as_component_batches() - .iter() - .map(|b| b as &dyn re_types_core::ComponentBatch), + clear.as_serialized_batches(), ) .build()?; @@ -378,13 +361,10 @@ fn clears_respect_index_order() -> anyhow::Result<()> { let clear = Clear::recursive(); let chunk = Chunk::builder(entity_path.clone()) - .with_component_batches( + .with_serialized_batches( row_id3, // newer row id! timepoint.clone(), - clear - .as_component_batches() - .iter() - .map(|b| b as &dyn re_types_core::ComponentBatch), + clear.as_serialized_batches(), ) .build()?; diff --git a/crates/store/re_types_core/src/as_components.rs b/crates/store/re_types_core/src/as_components.rs index 9e88fa0c950f..498d7c139221 100644 --- a/crates/store/re_types_core/src/as_components.rs +++ b/crates/store/re_types_core/src/as_components.rs @@ -1,6 +1,5 @@ use crate::{ - ComponentBatch, ComponentBatchCowWithDescriptor, LoggableBatch as _, ResultExt as _, - SerializationResult, + ComponentBatch, ComponentBatchCowWithDescriptor, SerializationResult, SerializedComponentBatch, }; /// Describes the interface for interpreting an object as a bundle of [`Component`]s. @@ -20,6 +19,8 @@ use crate::{ /// [Custom Data Loader]: https://github.com/rerun-io/rerun/blob/latest/examples/rust/custom_data_loader /// [`Component`]: [crate::Component] pub trait AsComponents { + /// Deprecated. Do not use. See [`AsComponents::as_serialized_batches`] instead. + /// /// Exposes the object's contents as a set of [`ComponentBatch`]s. /// /// This is the main mechanism for easily extending builtin archetypes or even writing @@ -34,7 +35,37 @@ pub trait AsComponents { // // NOTE: Don't bother returning a CoW here: we need to dynamically discard optional components // depending on their presence (or lack thereof) at runtime anyway. - fn as_component_batches(&self) -> Vec>; + #[deprecated(since = "0.22.0", note = "use as_serialized_batches instead")] + #[allow(clippy::unimplemented)] // temporary, this method is about to be replaced + fn as_component_batches(&self) -> Vec> { + // Eagerly serialized archetypes simply cannot implement this. + // + // This method only exist while we are in the process of making all existing archetypes + // eagerly serialized, at which point it'll be removed. + unimplemented!() + } + + /// Exposes the object's contents as a set of [`SerializedComponentBatch`]es. + /// + /// This is the main mechanism for easily extending builtin archetypes or even writing + /// fully custom ones. + /// Have a look at our [Custom Data Loader] example to learn more about extending archetypes. + /// + /// Implementers of [`AsComponents`] get one last chance to override the tags in the + /// [`ComponentDescriptor`], see [`SerializedComponentBatch::with_descriptor_override`]. + /// + /// [Custom Data Loader]: https://github.com/rerun-io/rerun/blob/latest/docs/snippets/all/tutorials/custom_data.rs + /// [`ComponentDescriptor`]: [crate::ComponentDescriptor] + // + // NOTE: Don't bother returning a CoW here: we need to dynamically discard optional components + // depending on their presence (or lack thereof) at runtime anyway. + fn as_serialized_batches(&self) -> Vec { + #[allow(deprecated)] // that's the whole point + self.as_component_batches() + .into_iter() + .filter_map(|batch| batch.serialized()) + .collect() + } // --- @@ -48,20 +79,15 @@ pub trait AsComponents { fn to_arrow( &self, ) -> SerializationResult> { - self.as_component_batches() + self.as_serialized_batches() .into_iter() .map(|comp_batch| { - comp_batch - .to_arrow() - .map(|array| { - let field = arrow::datatypes::Field::new( - comp_batch.name().to_string(), - array.data_type().clone(), - false, - ); - (field, array) - }) - .with_context(comp_batch.name()) + let field = arrow::datatypes::Field::new( + comp_batch.descriptor.component_name.to_string(), + comp_batch.array.data_type().clone(), + false, + ); + Ok((field, comp_batch.array)) }) .collect() } @@ -77,20 +103,15 @@ pub trait AsComponents { &self, ) -> SerializationResult)>> { - self.as_component_batches() + self.as_serialized_batches() .into_iter() .map(|comp_batch| { - comp_batch - .to_arrow2() - .map(|array| { - let field = arrow2::datatypes::Field::new( - comp_batch.name().to_string(), - array.data_type().clone(), - false, - ); - (field, array) - }) - .with_context(comp_batch.name()) + let field = arrow2::datatypes::Field::new( + comp_batch.descriptor.component_name.to_string(), + comp_batch.array.data_type().clone().into(), + false, + ); + Ok((field, comp_batch.array.into())) }) .collect() } @@ -103,106 +124,96 @@ fn assert_object_safe() { impl AsComponents for dyn ComponentBatch { #[inline] - fn as_component_batches(&self) -> Vec> { - vec![ComponentBatchCowWithDescriptor::new(self)] + fn as_serialized_batches(&self) -> Vec { + self.serialized().into_iter().collect() } } impl AsComponents for [&dyn ComponentBatch; N] { #[inline] - fn as_component_batches(&self) -> Vec> { - self.iter() - .map(|batch| ComponentBatchCowWithDescriptor::new(*batch)) - .collect() + fn as_serialized_batches(&self) -> Vec { + self.iter().filter_map(|batch| batch.serialized()).collect() } } impl AsComponents for [Box; N] { #[inline] - fn as_component_batches(&self) -> Vec> { - self.iter() - .map(|batch| ComponentBatchCowWithDescriptor::new(&**batch)) - .collect() + fn as_serialized_batches(&self) -> Vec { + self.iter().filter_map(|batch| batch.serialized()).collect() } } impl AsComponents for Vec<&dyn ComponentBatch> { #[inline] - fn as_component_batches(&self) -> Vec> { - self.iter() - .map(|batch| ComponentBatchCowWithDescriptor::new(*batch)) - .collect() + fn as_serialized_batches(&self) -> Vec { + self.iter().filter_map(|batch| batch.serialized()).collect() } } impl AsComponents for Vec> { #[inline] - fn as_component_batches(&self) -> Vec> { - self.iter() - .map(|batch| ComponentBatchCowWithDescriptor::new(&**batch)) - .collect() + fn as_serialized_batches(&self) -> Vec { + self.iter().filter_map(|batch| batch.serialized()).collect() } } -impl AsComponents for [AS] { +impl AsComponents for SerializedComponentBatch { #[inline] - fn as_component_batches(&self) -> Vec> { - self.iter() - .flat_map(|as_components| as_components.as_component_batches()) - .collect() + fn as_serialized_batches(&self) -> Vec { + vec![self.clone()] } } impl AsComponents for [AS; N] { #[inline] - fn as_component_batches(&self) -> Vec> { + fn as_serialized_batches(&self) -> Vec { self.iter() - .flat_map(|as_components| as_components.as_component_batches()) + .flat_map(|as_components| as_components.as_serialized_batches()) .collect() } } impl AsComponents for [&dyn AsComponents; N] { #[inline] - fn as_component_batches(&self) -> Vec> { + fn as_serialized_batches(&self) -> Vec { self.iter() - .flat_map(|as_components| as_components.as_component_batches()) + .flat_map(|as_components| as_components.as_serialized_batches()) .collect() } } impl AsComponents for [Box; N] { #[inline] - fn as_component_batches(&self) -> Vec> { + fn as_serialized_batches(&self) -> Vec { self.iter() - .flat_map(|as_components| as_components.as_component_batches()) + .flat_map(|as_components| as_components.as_serialized_batches()) .collect() } } impl AsComponents for Vec { #[inline] - fn as_component_batches(&self) -> Vec> { + fn as_serialized_batches(&self) -> Vec { self.iter() - .flat_map(|as_components| as_components.as_component_batches()) + .flat_map(|as_components| as_components.as_serialized_batches()) .collect() } } impl AsComponents for Vec<&dyn AsComponents> { #[inline] - fn as_component_batches(&self) -> Vec> { + fn as_serialized_batches(&self) -> Vec { self.iter() - .flat_map(|as_components| as_components.as_component_batches()) + .flat_map(|as_components| as_components.as_serialized_batches()) .collect() } } impl AsComponents for Vec> { #[inline] - fn as_component_batches(&self) -> Vec> { + fn as_serialized_batches(&self) -> Vec { self.iter() - .flat_map(|as_components| as_components.as_component_batches()) + .flat_map(|as_components| as_components.as_serialized_batches()) .collect() } } @@ -293,10 +304,9 @@ mod tests { use arrow::array::{ types::UInt32Type, Array as ArrowArray, PrimitiveArray as ArrowPrimitiveArray, }; + use itertools::Itertools; use similar_asserts::assert_eq; - use crate::LoggableBatch; - #[derive(Clone, Copy, Debug, PartialEq, Eq, bytemuck::Pod, bytemuck::Zeroable)] #[repr(transparent)] pub struct MyColor(pub u32); @@ -356,24 +366,21 @@ mod tests { } #[test] - fn single_ascomponents_howto() -> anyhow::Result<()> { + fn single_ascomponents_howto() { let (red, _, _, _) = data(); let got = { let red = &red as &dyn crate::ComponentBatch; - let got: Result, _> = (&[red] as &dyn crate::AsComponents) - .as_component_batches() + (&[red] as &dyn crate::AsComponents) + .as_serialized_batches() .into_iter() - .map(|batch| batch.to_arrow()) - .collect(); - got? + .map(|batch| batch.array) + .collect_vec() }; let expected = vec![ Arc::new(ArrowPrimitiveArray::::from(vec![red.0])) as Arc, ]; assert_eq!(&expected, &got); - - Ok(()) } #[test] @@ -390,24 +397,21 @@ mod tests { } #[test] - fn single_ascomponents_wrapped_howto() -> anyhow::Result<()> { + fn single_ascomponents_wrapped_howto() { let (red, _, _, _) = data(); let got = { let red = &red as &dyn crate::ComponentBatch; - let got: Result, _> = (&[red] as &dyn crate::AsComponents) - .as_component_batches() + (&[red] as &dyn crate::AsComponents) + .as_serialized_batches() .into_iter() - .map(|batch| batch.to_arrow()) - .collect(); - got? + .map(|batch| batch.array) + .collect_vec() }; let expected = vec![ Arc::new(ArrowPrimitiveArray::::from(vec![red.0])) as Arc, ]; assert_eq!(&expected, &got); - - Ok(()) } #[test] @@ -424,19 +428,18 @@ mod tests { } #[test] - fn single_ascomponents_wrapped_many_howto() -> anyhow::Result<()> { + fn single_ascomponents_wrapped_many_howto() { let (red, green, blue, _) = data(); let got = { let red = &red as &dyn crate::ComponentBatch; let green = &green as &dyn crate::ComponentBatch; let blue = &blue as &dyn crate::ComponentBatch; - let got: Result, _> = (&[red, green, blue] as &dyn crate::AsComponents) - .as_component_batches() + (&[red, green, blue] as &dyn crate::AsComponents) + .as_serialized_batches() .into_iter() - .map(|batch| batch.to_arrow()) - .collect(); - got? + .map(|batch| batch.array) + .collect_vec() }; let expected = vec![ Arc::new(ArrowPrimitiveArray::::from(vec![red.0])) as Arc, @@ -444,8 +447,6 @@ mod tests { Arc::new(ArrowPrimitiveArray::::from(vec![blue.0])) as Arc, ]; assert_eq!(&expected, &got); - - Ok(()) } #[test] @@ -477,39 +478,35 @@ mod tests { } #[test] - fn many_ascomponents_wrapped_howto() -> anyhow::Result<()> { + fn many_ascomponents_wrapped_howto() { let (red, green, blue, colors) = data(); let got = { let colors = &colors as &dyn crate::ComponentBatch; - let got: Result, _> = (&[colors] as &dyn crate::AsComponents) - .as_component_batches() + (&[colors] as &dyn crate::AsComponents) + .as_serialized_batches() .into_iter() - .map(|batch| batch.to_arrow()) - .collect(); - got? + .map(|batch| batch.array) + .collect_vec() }; let expected = vec![Arc::new(ArrowPrimitiveArray::::from(vec![ red.0, green.0, blue.0, ])) as Arc]; assert_eq!(&expected, &got); - - Ok(()) } #[test] - fn many_ascomponents_wrapped_many_howto() -> anyhow::Result<()> { + fn many_ascomponents_wrapped_many_howto() { let (red, green, blue, colors) = data(); // Nothing out of the ordinary here, a collection of batches is indeed a collection of batches. let got = { let colors = &colors as &dyn crate::ComponentBatch; - let got: Result, _> = (&[colors, colors, colors] as &dyn crate::AsComponents) - .as_component_batches() + (&[colors, colors, colors] as &dyn crate::AsComponents) + .as_serialized_batches() .into_iter() - .map(|batch| batch.to_arrow()) - .collect(); - got? + .map(|batch| batch.array) + .collect_vec() }; let expected = vec![ Arc::new(ArrowPrimitiveArray::::from(vec![ @@ -523,7 +520,5 @@ mod tests { ])) as Arc, ]; assert_eq!(&expected, &got); - - Ok(()) } } diff --git a/crates/store/re_types_core/src/lib.rs b/crates/store/re_types_core/src/lib.rs index c631ebc35b65..aa012b7bcab3 100644 --- a/crates/store/re_types_core/src/lib.rs +++ b/crates/store/re_types_core/src/lib.rs @@ -52,6 +52,7 @@ pub use self::{ }, loggable_batch::{ ComponentBatch, ComponentBatchCow, ComponentBatchCowWithDescriptor, LoggableBatch, + SerializedComponentBatch, }, result::{ DeserializationError, DeserializationResult, ResultExt, SerializationError, diff --git a/crates/store/re_types_core/src/loggable_batch.rs b/crates/store/re_types_core/src/loggable_batch.rs index 72f23628f052..6c1c3cd2110f 100644 --- a/crates/store/re_types_core/src/loggable_batch.rs +++ b/crates/store/re_types_core/src/loggable_batch.rs @@ -1,6 +1,9 @@ use std::borrow::Cow; -use crate::{Component, ComponentDescriptor, ComponentName, Loggable, SerializationResult}; +use crate::{ + ArchetypeFieldName, ArchetypeName, Component, ComponentDescriptor, ComponentName, Loggable, + SerializationResult, +}; use arrow2::array::ListArray as Arrow2ListArray; @@ -55,6 +58,9 @@ pub trait ComponentBatch: LoggableBatch { fn descriptor(&self) -> Cow<'_, ComponentDescriptor>; // Wraps the current [`ComponentBatch`] with the given descriptor. + // + // TODO(cmc): This should probably go away, but we'll see about that once I start tackling + // partial updates themselves. fn with_descriptor( &self, descriptor: ComponentDescriptor, @@ -66,6 +72,69 @@ pub trait ComponentBatch: LoggableBatch { .with_descriptor_override(descriptor) } + /// Serializes the contents of this [`ComponentBatch`]. + /// + /// Once serialized, the data is ready to be logged into Rerun via the [`AsComponents`] trait. + /// + /// # Fallibility + /// + /// There are very few ways in which serialization can fail, all of which are very rare to hit + /// in practice. + /// One such example is trying to serialize data with more than 2^31 elements into a `ListArray`. + /// + /// For that reason, this method favors a nice user experience over error handling: errors will + /// merely be logged, not returned (except in debug builds, where all errors panic). + /// + /// See also [`ComponentBatch::try_serialized`]. + /// + /// [`AsComponents`]: [crate::AsComponents] + #[inline] + fn serialized(&self) -> Option { + match self.try_serialized() { + Ok(array) => Some(array), + + #[cfg(debug_assertions)] + Err(err) => { + panic!( + "failed to serialize data for {}: {}", + self.descriptor(), + re_error::format_ref(&err) + ) + } + + #[cfg(not(debug_assertions))] + Err(err) => { + re_log::error!( + descriptor = %self.descriptor(), + "failed to serialize data: {}", + re_error::format_ref(&err) + ); + None + } + } + } + + /// Serializes the contents of this [`ComponentBatch`]. + /// + /// Once serialized, the data is ready to be logged into Rerun via the [`AsComponents`] trait. + /// + /// # Fallibility + /// + /// There are very few ways in which serialization can fail, all of which are very rare to hit + /// in practice. + /// + /// For that reason, it generally makes sense to favor a nice user experience over error handling + /// in most cases, see [`ComponentBatch::serialized`]. + /// + /// [`AsComponents`]: [crate::AsComponents] + #[inline] + fn try_serialized(&self) -> SerializationResult { + Ok(SerializedComponentBatch { + array: self.to_arrow()?, + descriptor: self.descriptor().into_owned(), + }) + } + /// The fully-qualified name of this component batch, e.g. `rerun.components.Position2D`. /// /// This is a trivial but useful helper for `self.descriptor().component_name`. @@ -85,6 +154,89 @@ fn assert_component_batch_object_safe() { let _: &dyn LoggableBatch; } +/// The serialized contents of a [`ComponentBatch`] with associated [`ComponentDescriptor`]. +/// +/// This is what gets logged into Rerun: +/// * See [`ComponentBatch`] to easily serialize component data. +/// * See [`AsComponents`] for logging serialized data. +/// +/// [`AsComponents`]: [crate::AsComponents] +#[derive(Debug, Clone)] +pub struct SerializedComponentBatch { + pub array: arrow::array::ArrayRef, + + // TODO(cmc): Maybe Cow<> this one if it grows bigger. Or intern descriptors altogether, most likely. + pub descriptor: ComponentDescriptor, +} + +impl re_byte_size::SizeBytes for SerializedComponentBatch { + #[inline] + fn heap_size_bytes(&self) -> u64 { + let Self { array, descriptor } = self; + array.heap_size_bytes() + descriptor.heap_size_bytes() + } +} + +impl PartialEq for SerializedComponentBatch { + #[inline] + fn eq(&self, other: &Self) -> bool { + let Self { array, descriptor } = self; + + // Descriptor first! + *descriptor == other.descriptor && **array == *other.array + } +} + +impl SerializedComponentBatch { + #[inline] + pub fn new(array: arrow::array::ArrayRef, descriptor: ComponentDescriptor) -> Self { + Self { array, descriptor } + } + + #[inline] + pub fn with_descriptor_override(self, descriptor: ComponentDescriptor) -> Self { + Self { descriptor, ..self } + } + + /// Unconditionally sets the descriptor's `archetype_name` to the given one. + #[inline] + pub fn with_archetype_name(mut self, archetype_name: ArchetypeName) -> Self { + self.descriptor = self.descriptor.with_archetype_name(archetype_name); + self + } + + /// Unconditionally sets the descriptor's `archetype_field_name` to the given one. + #[inline] + pub fn with_archetype_field_name(mut self, archetype_field_name: ArchetypeFieldName) -> Self { + self.descriptor = self + .descriptor + .with_archetype_field_name(archetype_field_name); + self + } + + /// Sets the descriptor's `archetype_name` to the given one iff it's not already set. + #[inline] + pub fn or_with_archetype_name(mut self, archetype_name: impl Fn() -> ArchetypeName) -> Self { + self.descriptor = self.descriptor.or_with_archetype_name(archetype_name); + self + } + + /// Sets the descriptor's `archetype_field_name` to the given one iff it's not already set. + #[inline] + pub fn or_with_archetype_field_name( + mut self, + archetype_field_name: impl FnOnce() -> ArchetypeFieldName, + ) -> Self { + self.descriptor = self + .descriptor + .or_with_archetype_field_name(archetype_field_name); + self + } +} + +// TODO(cmc): All these crazy types are about to disappear. ComponentBatch should only live at the +// edge, and therefore not require all these crazy kinds of derivatives (require eager serialization). + /// Some [`ComponentBatch`], optionally with an overridden [`ComponentDescriptor`]. /// /// Used by implementers of [`crate::AsComponents`] to both efficiently expose their component data diff --git a/crates/top/re_sdk/src/lib.rs b/crates/top/re_sdk/src/lib.rs index 642e844ae903..5756313ef465 100644 --- a/crates/top/re_sdk/src/lib.rs +++ b/crates/top/re_sdk/src/lib.rs @@ -95,6 +95,7 @@ pub use re_types_core::{ ComponentBatchCowWithDescriptor, ComponentDescriptor, ComponentName, DatatypeName, DeserializationError, DeserializationResult, GenericIndicatorComponent, Loggable, LoggableBatch, NamedIndicatorComponent, SerializationError, SerializationResult, + SerializedComponentBatch, }; pub use re_byte_size::SizeBytes; diff --git a/crates/top/re_sdk/src/recording_stream.rs b/crates/top/re_sdk/src/recording_stream.rs index 8771691ac47c..7333056146a4 100644 --- a/crates/top/re_sdk/src/recording_stream.rs +++ b/crates/top/re_sdk/src/recording_stream.rs @@ -1033,10 +1033,10 @@ impl RecordingStream { #[deprecated(since = "0.16.0", note = "use `log_static` instead")] #[doc(hidden)] #[inline] - pub fn log_timeless( + pub fn log_timeless( &self, ent_path: impl Into, - arch: &impl AsComponents, + arch: &AS, ) -> RecordingStreamResult<()> { self.log_static(ent_path, arch) } @@ -1063,10 +1063,10 @@ impl RecordingStream { /// [SDK Micro Batching]: https://www.rerun.io/docs/reference/sdk/micro-batching /// [component bundle]: [`AsComponents`] #[inline] - pub fn log_static( + pub fn log_static( &self, ent_path: impl Into, - as_components: &impl AsComponents, + as_components: &AS, ) -> RecordingStreamResult<()> { self.log_with_static(ent_path, true, as_components) } @@ -1074,11 +1074,11 @@ impl RecordingStream { #[deprecated(since = "0.16.0", note = "use `log_static` instead")] #[doc(hidden)] #[inline] - pub fn log_with_timeless( + pub fn log_with_timeless( &self, ent_path: impl Into, static_: bool, - arch: &impl AsComponents, + arch: &AS, ) -> RecordingStreamResult<()> { self.log_with_static(ent_path, static_, arch) } @@ -1113,14 +1113,11 @@ impl RecordingStream { as_components: &AS, ) -> RecordingStreamResult<()> { let row_id = RowId::new(); // Create row-id as early as possible. It has a timestamp and is used to estimate e2e latency. - self.log_component_batches_impl( + self.log_serialized_batches_impl( row_id, ent_path, static_, - as_components - .as_component_batches() - .iter() - .map(|any_comp_batch| any_comp_batch as &dyn re_types_core::ComponentBatch), + as_components.as_serialized_batches(), ) } @@ -1147,6 +1144,7 @@ impl RecordingStream { /// See [SDK Micro Batching] for more information. /// /// [SDK Micro Batching]: https://www.rerun.io/docs/reference/sdk/micro-batching + #[deprecated(since = "0.22.0", note = "use log_serialized_batches instead")] pub fn log_component_batches<'a>( &self, ent_path: impl Into, @@ -1196,6 +1194,79 @@ impl RecordingStream { Ok(()) } + /// Logs a set of [`SerializedComponentBatch`]es into Rerun. + /// + /// If `static_` is set to `true`, all timestamp data associated with this message will be + /// dropped right before sending it to Rerun. + /// Static data has no time associated with it, exists on all timelines, and unconditionally shadows + /// any temporal data of the same type. + /// + /// Otherwise, the data will be timestamped automatically based on the [`RecordingStream`]'s + /// internal clock. + /// See `RecordingStream::set_time_*` family of methods for more information. + /// + /// The number of instances will be determined by the longest batch in the bundle. + /// + /// The entity path can either be a string + /// (with special characters escaped, split on unescaped slashes) + /// or an [`EntityPath`] constructed with [`crate::entity_path`]. + /// See for more on entity paths. + /// + /// Internally, the stream will automatically micro-batch multiple log calls to optimize + /// transport. + /// See [SDK Micro Batching] for more information. + /// + /// [SDK Micro Batching]: https://www.rerun.io/docs/reference/sdk/micro-batching + /// + /// [`SerializedComponentBatch`]: [re_types_core::SerializedComponentBatch] + pub fn log_serialized_batches( + &self, + ent_path: impl Into, + static_: bool, + comp_batches: impl IntoIterator, + ) -> RecordingStreamResult<()> { + let row_id = RowId::new(); // Create row-id as early as possible. It has a timestamp and is used to estimate e2e latency. + self.log_serialized_batches_impl(row_id, ent_path, static_, comp_batches) + } + + // NOTE: For bw and fw compatibility reasons, we need our logging APIs to be fallible, even + // though they really aren't at the moment. + #[allow(clippy::unnecessary_wraps)] + fn log_serialized_batches_impl( + &self, + row_id: RowId, + entity_path: impl Into, + static_: bool, + comp_batches: impl IntoIterator, + ) -> RecordingStreamResult<()> { + if !self.is_enabled() { + return Ok(()); // silently drop the message + } + + let entity_path = entity_path.into(); + + let comp_batches: Vec<_> = comp_batches + .into_iter() + .map(|comp_batch| (comp_batch.descriptor, comp_batch.array)) + .collect(); + let components: IntMap<_, _> = comp_batches.into_iter().collect(); + + // NOTE: The timepoint is irrelevant, the `RecordingStream` will overwrite it using its + // internal clock. + let timepoint = TimePoint::default(); + + if !components.is_empty() { + let row = PendingRow { + row_id, + timepoint, + components, + }; + self.record_row(entity_path, row, !static_); + } + + Ok(()) + } + /// Logs the file at the given `path` using all [`re_data_loader::DataLoader`]s available. /// /// A single `path` might be handled by more than one loader. diff --git a/docs/snippets/all/descriptors/descr_builtin_component.rs b/docs/snippets/all/descriptors/descr_builtin_component.rs index 86e6bc52c6f6..dfb391127036 100644 --- a/docs/snippets/all/descriptors/descr_builtin_component.rs +++ b/docs/snippets/all/descriptors/descr_builtin_component.rs @@ -1,10 +1,11 @@ use rerun::{ChunkStore, ChunkStoreConfig, Component as _, ComponentDescriptor, VersionPolicy}; fn example(rec: &rerun::RecordingStream) -> Result<(), Box> { - rec.log_component_batches( + use rerun::ComponentBatch as _; + rec.log_serialized_batches( "data", true, - [&rerun::components::Position3D::new(1.0, 2.0, 3.0) as &dyn rerun::ComponentBatch], + [rerun::components::Position3D::new(1.0, 2.0, 3.0).try_serialized()?], )?; Ok(()) diff --git a/docs/snippets/all/descriptors/descr_custom_component.rs b/docs/snippets/all/descriptors/descr_custom_component.rs index 14e3f20505bb..a8bb1d0f9ee2 100644 --- a/docs/snippets/all/descriptors/descr_custom_component.rs +++ b/docs/snippets/all/descriptors/descr_custom_component.rs @@ -1,13 +1,14 @@ use rerun::{ChunkStore, ChunkStoreConfig, ComponentBatch, ComponentDescriptor, VersionPolicy}; fn example(rec: &rerun::RecordingStream) -> Result<(), Box> { - let positions = rerun::components::Position3D::new(1.0, 2.0, 3.0); - let positions = positions.with_descriptor(ComponentDescriptor { - archetype_name: Some("user.CustomArchetype".into()), - archetype_field_name: Some("custom_positions".into()), - component_name: "user.CustomPosition3D".into(), - }); - rec.log_component_batches("data", true, [&positions as &dyn rerun::ComponentBatch])?; + let positions = rerun::components::Position3D::new(1.0, 2.0, 3.0) + .try_serialized()? + .with_descriptor_override(ComponentDescriptor { + archetype_name: Some("user.CustomArchetype".into()), + archetype_field_name: Some("custom_positions".into()), + component_name: "user.CustomPosition3D".into(), + }); + rec.log_serialized_batches("data", true, [positions])?; Ok(()) } diff --git a/docs/snippets/all/tutorials/custom_data.rs b/docs/snippets/all/tutorials/custom_data.rs index 7b3d3fa00b17..2857159a2729 100644 --- a/docs/snippets/all/tutorials/custom_data.rs +++ b/docs/snippets/all/tutorials/custom_data.rs @@ -3,7 +3,7 @@ use rerun::{ demo_util::grid, external::{arrow, glam, re_types}, - ComponentBatch, + ComponentBatch, SerializedComponentBatch, }; // --- @@ -18,27 +18,22 @@ struct CustomPoints3D { } impl rerun::AsComponents for CustomPoints3D { - fn as_component_batches(&self) -> Vec> { + fn as_serialized_batches(&self) -> Vec { let indicator = rerun::NamedIndicatorComponent("user.CustomPoints3DIndicator".into()); self.points3d - .as_component_batches() + .as_serialized_batches() .into_iter() .chain( [ - Some(indicator.to_batch()), - self.confidences.as_ref().map(|batch| { - rerun::ComponentBatchCowWithDescriptor::new( - batch as &dyn rerun::ComponentBatch, - ) - // Optionally override the descriptor with extra information. - .with_descriptor_override( + indicator.serialized(), + self.confidences + .as_ref() + .and_then(|batch| batch.serialized()) + .map(|batch| + // Optionally override the descriptor with extra information. batch - .descriptor() - .into_owned() .or_with_archetype_name(|| "user.CustomPoints3D".into()) - .or_with_archetype_field_name(|| "confidences".into()), - ) - }), + .or_with_archetype_field_name(|| "confidences".into())), ] .into_iter() .flatten(), diff --git a/scripts/ci/check_large_files.py b/scripts/ci/check_large_files.py index b83948029e1c..52c35878f3c4 100755 --- a/scripts/ci/check_large_files.py +++ b/scripts/ci/check_large_files.py @@ -11,6 +11,7 @@ "crates/store/re_dataframe/src/query.rs", "crates/store/re_types/src/datatypes/tensor_buffer.rs", "crates/store/re_types/src/reflection/mod.rs", + "crates/top/re_sdk/src/recording_stream.rs", "crates/viewer/re_ui/data/Inter-Medium.otf", "docs/snippets/INDEX.md", "pixi.lock", From c80d84742acb863cbff6b4d3d9a7df8df13a6927 Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Mon, 13 Jan 2025 09:19:09 +0100 Subject: [PATCH 06/57] Autogenerate tagging-compliant descriptor methods for all archetypes (#8643) Generate methods for all archetypes that allow retrieving the fully-qualified descriptor for any of the archetype's field. E.g. this method returns the descriptor for the `radii` field of `Points3D`: ```rust impl Points3D { /// Returns the [`ComponentDescriptor`] for [`Self::radii`]. #[inline] pub fn descriptor_radii() -> ComponentDescriptor { ComponentDescriptor { archetype_name: Some("rerun.archetypes.Points3D".into()), component_name: "rerun.components.Radius".into(), archetype_field_name: Some("radii".into()), } } } ``` This becomes a must as we start require tags in more and more places (e.g. partial updates APIs). * DNM: requires #8642 * Part of https://github.com/rerun-io/rerun/issues/8581 --- .../re_types_builder/src/codegen/rust/api.rs | 89 ++- .../src/archetypes/annotation_context.rs | 48 +- .../store/re_types/src/archetypes/arrows2d.rs | 246 ++++--- .../store/re_types/src/archetypes/arrows3d.rs | 218 +++--- .../store/re_types/src/archetypes/asset3d.rs | 108 ++- .../re_types/src/archetypes/asset_video.rs | 78 ++- .../re_types/src/archetypes/bar_chart.rs | 78 +-- .../store/re_types/src/archetypes/boxes2d.rs | 246 ++++--- .../store/re_types/src/archetypes/boxes3d.rs | 302 ++++---- .../re_types/src/archetypes/capsules3d.rs | 276 ++++---- .../re_types/src/archetypes/depth_image.rs | 222 +++--- .../re_types/src/archetypes/ellipsoids3d.rs | 302 ++++---- .../re_types/src/archetypes/encoded_image.rs | 134 ++-- .../src/archetypes/geo_line_strings.rs | 106 ++- .../re_types/src/archetypes/geo_points.rs | 136 ++-- .../re_types/src/archetypes/graph_edges.rs | 78 ++- .../re_types/src/archetypes/graph_nodes.rs | 188 +++-- crates/store/re_types/src/archetypes/image.rs | 142 ++-- .../src/archetypes/instance_poses3d.rs | 166 +++-- .../re_types/src/archetypes/line_strips2d.rs | 218 +++--- .../re_types/src/archetypes/line_strips3d.rs | 190 +++--- .../store/re_types/src/archetypes/mesh3d.rs | 274 ++++---- .../store/re_types/src/archetypes/pinhole.rs | 134 ++-- .../store/re_types/src/archetypes/points2d.rs | 246 ++++--- .../store/re_types/src/archetypes/points3d.rs | 218 +++--- .../store/re_types/src/archetypes/scalar.rs | 51 +- .../src/archetypes/segmentation_image.rs | 138 ++-- .../re_types/src/archetypes/series_line.rs | 138 ++-- .../re_types/src/archetypes/series_point.rs | 138 ++-- .../store/re_types/src/archetypes/tensor.rs | 78 +-- .../re_types/src/archetypes/text_document.rs | 78 +-- .../store/re_types/src/archetypes/text_log.rs | 109 ++- .../re_types/src/archetypes/transform3d.rs | 222 +++--- .../src/archetypes/video_frame_reference.rs | 78 +-- .../src/archetypes/view_coordinates.rs | 48 +- .../src/blueprint/archetypes/background.rs | 78 +-- .../archetypes/container_blueprint.rs | 246 ++++--- .../blueprint/archetypes/dataframe_query.rs | 166 +++-- .../src/blueprint/archetypes/force_center.rs | 82 ++- .../archetypes/force_collision_radius.rs | 110 ++- .../src/blueprint/archetypes/force_link.rs | 110 ++- .../blueprint/archetypes/force_many_body.rs | 82 ++- .../blueprint/archetypes/force_position.rs | 110 ++- .../src/blueprint/archetypes/line_grid3d.rs | 166 +++-- .../blueprint/archetypes/map_background.rs | 56 +- .../src/blueprint/archetypes/map_zoom.rs | 59 +- .../blueprint/archetypes/near_clip_plane.rs | 56 +- .../blueprint/archetypes/panel_blueprint.rs | 56 +- .../src/blueprint/archetypes/plot_legend.rs | 82 ++- .../src/blueprint/archetypes/scalar_axis.rs | 82 ++- .../archetypes/tensor_scalar_mapping.rs | 110 ++- .../archetypes/tensor_slice_selection.rs | 139 ++-- .../blueprint/archetypes/tensor_view_fit.rs | 56 +- .../blueprint/archetypes/view_blueprint.rs | 132 ++-- .../src/blueprint/archetypes/view_contents.rs | 56 +- .../archetypes/viewport_blueprint.rs | 166 +++-- .../archetypes/visible_time_ranges.rs | 48 +- .../blueprint/archetypes/visual_bounds2d.rs | 48 +- .../src/testing/archetypes/affix_fuzzer1.rs | 642 ++++++++---------- .../src/testing/archetypes/affix_fuzzer2.rs | 558 +++++++-------- .../src/testing/archetypes/affix_fuzzer3.rs | 530 +++++++-------- .../src/testing/archetypes/affix_fuzzer4.rs | 530 +++++++-------- .../re_types_core/src/archetypes/clear.rs | 48 +- 63 files changed, 4796 insertions(+), 5329 deletions(-) diff --git a/crates/build/re_types_builder/src/codegen/rust/api.rs b/crates/build/re_types_builder/src/codegen/rust/api.rs index 3807c76364f8..89d887f62fa2 100644 --- a/crates/build/re_types_builder/src/codegen/rust/api.rs +++ b/crates/build/re_types_builder/src/codegen/rust/api.rs @@ -1042,7 +1042,6 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { assert_eq!(kind, &ObjectKind::Archetype); let display_name = re_case::to_human_case(name); - let archetype_name = &obj.fqname; let name = format_ident!("{name}"); fn compute_component_descriptors( @@ -1056,18 +1055,11 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { field .try_get_attr::(requirement_attr_value) .map(|_| { - let Some(component_name) = field.typ.fqname() else { - panic!("Archetype field must be an object/union or an array/vector of such") - }; - - let archetype_name = &obj.fqname; + let archetype_name = format_ident!("{}", obj.name); let archetype_field_name = field.snake_case_name(); + let fn_name = format_ident!("descriptor_{archetype_field_name}"); - quote!(ComponentDescriptor { - archetype_name: Some(#archetype_name.into()), - component_name: #component_name.into(), - archetype_field_name: Some(#archetype_field_name.into()), - }) + quote!(#archetype_name::#fn_name()) }) }) .collect_vec(); @@ -1078,13 +1070,63 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { (num_descriptors, quoted_descriptors) } + let all_descriptor_methods = 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 archetype_name = &obj.fqname; + let archetype_field_name = field.snake_case_name(); + + let doc = format!( + "Returns the [`ComponentDescriptor`] for [`Self::{archetype_field_name}`]." + ); + let fn_name = format_ident!("descriptor_{archetype_field_name}"); + + quote! { + #[doc = #doc] + #[inline] + pub fn #fn_name() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some(#archetype_name.into()), + component_name: #component_name.into(), + archetype_field_name: Some(#archetype_field_name.into()), + } + } + } + }) + .chain(std::iter::once({ + let archetype_name = &obj.fqname; + let indicator_component_name = format!( + "{}Indicator", + obj.fqname.replace("archetypes", "components") + ); + + let doc = "Returns the [`ComponentDescriptor`] for the associated indicator component."; + + quote! { + #[doc = #doc] + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some(#archetype_name.into()), + component_name: #indicator_component_name.into(), + archetype_field_name: None, + } + } + } + })) + .collect_vec(); + + let archetype_name = format_ident!("{}", obj.name); let indicator_name = format!("{}Indicator", obj.name); let quoted_indicator_name = format_ident!("{indicator_name}"); let quoted_indicator_doc = format!("Indicator component for the [`{name}`] [`::re_types_core::Archetype`]"); - let indicator_component_name = - format!("{}Indicator", fqname.replace("archetypes", "components")); let (num_required_descriptors, required_descriptors) = compute_component_descriptors(obj, ATTR_RERUN_COMPONENT_REQUIRED); @@ -1096,11 +1138,7 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { num_recommended_descriptors += 1; recommended_descriptors = quote! { #recommended_descriptors - ComponentDescriptor { - archetype_name: Some(#archetype_name.into()), - component_name: #indicator_component_name.into(), - archetype_field_name: None, - }, + #archetype_name::descriptor_indicator(), }; let num_components_docstring = quote_doc_line(&format!( @@ -1160,21 +1198,14 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { quote!{ Some(&self.#field_name as &dyn ComponentBatch) } }; - let Some(component_name) = obj_field.typ.fqname() else { - panic!("Archetype field must be an object/union or an array/vector of such") - }; - let archetype_name = &obj.fqname; let archetype_field_name = obj_field.snake_case_name(); + let descr_fn_name = format_ident!("descriptor_{archetype_field_name}"); quote! { (#batch).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some(#archetype_name.into()), - archetype_field_name: Some((#archetype_field_name).into()), - component_name: (#component_name).into(), - }), + descriptor_override: Some(Self::#descr_fn_name()), } }) @@ -1261,6 +1292,10 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { }; quote! { + impl #name { + #(#all_descriptor_methods)* + } + static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; #num_required_descriptors]> = once_cell::sync::Lazy::new(|| {[#required_descriptors]}); diff --git a/crates/store/re_types/src/archetypes/annotation_context.rs b/crates/store/re_types/src/archetypes/annotation_context.rs index 373c695b33b3..a53b871fbf21 100644 --- a/crates/store/re_types/src/archetypes/annotation_context.rs +++ b/crates/store/re_types/src/archetypes/annotation_context.rs @@ -75,23 +75,33 @@ pub struct AnnotationContext { pub context: crate::components::AnnotationContext, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl AnnotationContext { + /// Returns the [`ComponentDescriptor`] for [`Self::context`]. + #[inline] + pub fn descriptor_context() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.AnnotationContext".into()), component_name: "rerun.components.AnnotationContext".into(), archetype_field_name: Some("context".into()), - }] - }); + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.AnnotationContext".into()), component_name: "rerun.components.AnnotationContextIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [AnnotationContext::descriptor_context()]); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [AnnotationContext::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = once_cell::sync::Lazy::new(|| []); @@ -99,16 +109,8 @@ static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.AnnotationContext".into()), - component_name: "rerun.components.AnnotationContext".into(), - archetype_field_name: Some("context".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.AnnotationContext".into()), - component_name: "rerun.components.AnnotationContextIndicator".into(), - archetype_field_name: None, - }, + AnnotationContext::descriptor_context(), + AnnotationContext::descriptor_indicator(), ] }); @@ -195,11 +197,7 @@ impl ::re_types_core::AsComponents for AnnotationContext { (Some(&self.context as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.AnnotationContext".into()), - archetype_field_name: Some(("context").into()), - component_name: ("rerun.components.AnnotationContext").into(), - }), + descriptor_override: Some(Self::descriptor_context()), } }), ] diff --git a/crates/store/re_types/src/archetypes/arrows2d.rs b/crates/store/re_types/src/archetypes/arrows2d.rs index c81ef1490eec..39d9b66419da 100644 --- a/crates/store/re_types/src/archetypes/arrows2d.rs +++ b/crates/store/re_types/src/archetypes/arrows2d.rs @@ -87,115 +87,133 @@ pub struct Arrows2D { pub class_ids: Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl Arrows2D { + /// Returns the [`ComponentDescriptor`] for [`Self::vectors`]. + #[inline] + pub fn descriptor_vectors() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Arrows2D".into()), component_name: "rerun.components.Vector2D".into(), archetype_field_name: Some("vectors".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::origins`]. + #[inline] + pub fn descriptor_origins() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Arrows2D".into()), + component_name: "rerun.components.Position2D".into(), + archetype_field_name: Some("origins".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::radii`]. + #[inline] + pub fn descriptor_radii() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Arrows2D".into()), + component_name: "rerun.components.Radius".into(), + archetype_field_name: Some("radii".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::colors`]. + #[inline] + pub fn descriptor_colors() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Arrows2D".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("colors".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::labels`]. + #[inline] + pub fn descriptor_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Arrows2D".into()), + component_name: "rerun.components.Text".into(), + archetype_field_name: Some("labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::show_labels`]. + #[inline] + pub fn descriptor_show_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Arrows2D".into()), + component_name: "rerun.components.ShowLabels".into(), + archetype_field_name: Some("show_labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::draw_order`]. + #[inline] + pub fn descriptor_draw_order() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Arrows2D".into()), + component_name: "rerun.components.DrawOrder".into(), + archetype_field_name: Some("draw_order".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::class_ids`]. + #[inline] + pub fn descriptor_class_ids() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Arrows2D".into()), + component_name: "rerun.components.ClassId".into(), + archetype_field_name: Some("class_ids".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Arrows2D".into()), + component_name: "rerun.components.Arrows2DIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Arrows2D::descriptor_vectors()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.Position2D".into(), - archetype_field_name: Some("origins".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.Arrows2DIndicator".into(), - archetype_field_name: None, - }, + Arrows2D::descriptor_origins(), + Arrows2D::descriptor_indicator(), ] }); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 6usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.DrawOrder".into(), - archetype_field_name: Some("draw_order".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + Arrows2D::descriptor_radii(), + Arrows2D::descriptor_colors(), + Arrows2D::descriptor_labels(), + Arrows2D::descriptor_show_labels(), + Arrows2D::descriptor_draw_order(), + Arrows2D::descriptor_class_ids(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 9usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.Vector2D".into(), - archetype_field_name: Some("vectors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.Position2D".into(), - archetype_field_name: Some("origins".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.Arrows2DIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.DrawOrder".into(), - archetype_field_name: Some("draw_order".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + Arrows2D::descriptor_vectors(), + Arrows2D::descriptor_origins(), + Arrows2D::descriptor_indicator(), + Arrows2D::descriptor_radii(), + Arrows2D::descriptor_colors(), + Arrows2D::descriptor_labels(), + Arrows2D::descriptor_show_labels(), + Arrows2D::descriptor_draw_order(), + Arrows2D::descriptor_class_ids(), ] }); @@ -368,11 +386,7 @@ impl ::re_types_core::AsComponents for Arrows2D { (Some(&self.vectors as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - archetype_field_name: Some(("vectors").into()), - component_name: ("rerun.components.Vector2D").into(), - }), + descriptor_override: Some(Self::descriptor_vectors()), } }), (self @@ -381,11 +395,7 @@ impl ::re_types_core::AsComponents for Arrows2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - archetype_field_name: Some(("origins").into()), - component_name: ("rerun.components.Position2D").into(), - }), + descriptor_override: Some(Self::descriptor_origins()), }), (self .radii @@ -393,11 +403,7 @@ impl ::re_types_core::AsComponents for Arrows2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - archetype_field_name: Some(("radii").into()), - component_name: ("rerun.components.Radius").into(), - }), + descriptor_override: Some(Self::descriptor_radii()), }), (self .colors @@ -405,11 +411,7 @@ impl ::re_types_core::AsComponents for Arrows2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - archetype_field_name: Some(("colors").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_colors()), }), (self .labels @@ -417,11 +419,7 @@ impl ::re_types_core::AsComponents for Arrows2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - archetype_field_name: Some(("labels").into()), - component_name: ("rerun.components.Text").into(), - }), + descriptor_override: Some(Self::descriptor_labels()), }), (self .show_labels @@ -429,11 +427,7 @@ impl ::re_types_core::AsComponents for Arrows2D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - archetype_field_name: Some(("show_labels").into()), - component_name: ("rerun.components.ShowLabels").into(), - }), + descriptor_override: Some(Self::descriptor_show_labels()), }), (self .draw_order @@ -441,11 +435,7 @@ impl ::re_types_core::AsComponents for Arrows2D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - archetype_field_name: Some(("draw_order").into()), - component_name: ("rerun.components.DrawOrder").into(), - }), + descriptor_override: Some(Self::descriptor_draw_order()), }), (self .class_ids @@ -453,11 +443,7 @@ impl ::re_types_core::AsComponents for Arrows2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows2D".into()), - archetype_field_name: Some(("class_ids").into()), - component_name: ("rerun.components.ClassId").into(), - }), + descriptor_override: Some(Self::descriptor_class_ids()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/arrows3d.rs b/crates/store/re_types/src/archetypes/arrows3d.rs index 69903af49d9f..6bb11ae968e1 100644 --- a/crates/store/re_types/src/archetypes/arrows3d.rs +++ b/crates/store/re_types/src/archetypes/arrows3d.rs @@ -95,105 +95,121 @@ pub struct Arrows3D { pub class_ids: Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl Arrows3D { + /// Returns the [`ComponentDescriptor`] for [`Self::vectors`]. + #[inline] + pub fn descriptor_vectors() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Arrows3D".into()), component_name: "rerun.components.Vector3D".into(), archetype_field_name: Some("vectors".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::origins`]. + #[inline] + pub fn descriptor_origins() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Arrows3D".into()), + component_name: "rerun.components.Position3D".into(), + archetype_field_name: Some("origins".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::radii`]. + #[inline] + pub fn descriptor_radii() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Arrows3D".into()), + component_name: "rerun.components.Radius".into(), + archetype_field_name: Some("radii".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::colors`]. + #[inline] + pub fn descriptor_colors() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Arrows3D".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("colors".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::labels`]. + #[inline] + pub fn descriptor_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Arrows3D".into()), + component_name: "rerun.components.Text".into(), + archetype_field_name: Some("labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::show_labels`]. + #[inline] + pub fn descriptor_show_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Arrows3D".into()), + component_name: "rerun.components.ShowLabels".into(), + archetype_field_name: Some("show_labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::class_ids`]. + #[inline] + pub fn descriptor_class_ids() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Arrows3D".into()), + component_name: "rerun.components.ClassId".into(), + archetype_field_name: Some("class_ids".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Arrows3D".into()), + component_name: "rerun.components.Arrows3DIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Arrows3D::descriptor_vectors()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - component_name: "rerun.components.Position3D".into(), - archetype_field_name: Some("origins".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - component_name: "rerun.components.Arrows3DIndicator".into(), - archetype_field_name: None, - }, + Arrows3D::descriptor_origins(), + Arrows3D::descriptor_indicator(), ] }); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + Arrows3D::descriptor_radii(), + Arrows3D::descriptor_colors(), + Arrows3D::descriptor_labels(), + Arrows3D::descriptor_show_labels(), + Arrows3D::descriptor_class_ids(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 8usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - component_name: "rerun.components.Vector3D".into(), - archetype_field_name: Some("vectors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - component_name: "rerun.components.Position3D".into(), - archetype_field_name: Some("origins".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - component_name: "rerun.components.Arrows3DIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + Arrows3D::descriptor_vectors(), + Arrows3D::descriptor_origins(), + Arrows3D::descriptor_indicator(), + Arrows3D::descriptor_radii(), + Arrows3D::descriptor_colors(), + Arrows3D::descriptor_labels(), + Arrows3D::descriptor_show_labels(), + Arrows3D::descriptor_class_ids(), ] }); @@ -356,11 +372,7 @@ impl ::re_types_core::AsComponents for Arrows3D { (Some(&self.vectors as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - archetype_field_name: Some(("vectors").into()), - component_name: ("rerun.components.Vector3D").into(), - }), + descriptor_override: Some(Self::descriptor_vectors()), } }), (self @@ -369,11 +381,7 @@ impl ::re_types_core::AsComponents for Arrows3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - archetype_field_name: Some(("origins").into()), - component_name: ("rerun.components.Position3D").into(), - }), + descriptor_override: Some(Self::descriptor_origins()), }), (self .radii @@ -381,11 +389,7 @@ impl ::re_types_core::AsComponents for Arrows3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - archetype_field_name: Some(("radii").into()), - component_name: ("rerun.components.Radius").into(), - }), + descriptor_override: Some(Self::descriptor_radii()), }), (self .colors @@ -393,11 +397,7 @@ impl ::re_types_core::AsComponents for Arrows3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - archetype_field_name: Some(("colors").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_colors()), }), (self .labels @@ -405,11 +405,7 @@ impl ::re_types_core::AsComponents for Arrows3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - archetype_field_name: Some(("labels").into()), - component_name: ("rerun.components.Text").into(), - }), + descriptor_override: Some(Self::descriptor_labels()), }), (self .show_labels @@ -417,11 +413,7 @@ impl ::re_types_core::AsComponents for Arrows3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - archetype_field_name: Some(("show_labels").into()), - component_name: ("rerun.components.ShowLabels").into(), - }), + descriptor_override: Some(Self::descriptor_show_labels()), }), (self .class_ids @@ -429,11 +421,7 @@ impl ::re_types_core::AsComponents for Arrows3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Arrows3D".into()), - archetype_field_name: Some(("class_ids").into()), - component_name: ("rerun.components.ClassId").into(), - }), + descriptor_override: Some(Self::descriptor_class_ids()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/asset3d.rs b/crates/store/re_types/src/archetypes/asset3d.rs index b694e03facd4..7521cd4d6134 100644 --- a/crates/store/re_types/src/archetypes/asset3d.rs +++ b/crates/store/re_types/src/archetypes/asset3d.rs @@ -78,63 +78,69 @@ pub struct Asset3D { pub albedo_factor: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl Asset3D { + /// Returns the [`ComponentDescriptor`] for [`Self::blob`]. + #[inline] + pub fn descriptor_blob() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Asset3D".into()), component_name: "rerun.components.Blob".into(), archetype_field_name: Some("blob".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::media_type`]. + #[inline] + pub fn descriptor_media_type() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Asset3D".into()), + component_name: "rerun.components.MediaType".into(), + archetype_field_name: Some("media_type".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::albedo_factor`]. + #[inline] + pub fn descriptor_albedo_factor() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Asset3D".into()), + component_name: "rerun.components.AlbedoFactor".into(), + archetype_field_name: Some("albedo_factor".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Asset3D".into()), + component_name: "rerun.components.Asset3DIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Asset3D::descriptor_blob()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Asset3D".into()), - component_name: "rerun.components.MediaType".into(), - archetype_field_name: Some("media_type".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Asset3D".into()), - component_name: "rerun.components.Asset3DIndicator".into(), - archetype_field_name: None, - }, + Asset3D::descriptor_media_type(), + Asset3D::descriptor_indicator(), ] }); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Asset3D".into()), - component_name: "rerun.components.AlbedoFactor".into(), - archetype_field_name: Some("albedo_factor".into()), - }] - }); + once_cell::sync::Lazy::new(|| [Asset3D::descriptor_albedo_factor()]); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 4usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Asset3D".into()), - component_name: "rerun.components.Blob".into(), - archetype_field_name: Some("blob".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Asset3D".into()), - component_name: "rerun.components.MediaType".into(), - archetype_field_name: Some("media_type".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Asset3D".into()), - component_name: "rerun.components.Asset3DIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Asset3D".into()), - component_name: "rerun.components.AlbedoFactor".into(), - archetype_field_name: Some("albedo_factor".into()), - }, + Asset3D::descriptor_blob(), + Asset3D::descriptor_media_type(), + Asset3D::descriptor_indicator(), + Asset3D::descriptor_albedo_factor(), ] }); @@ -244,11 +250,7 @@ impl ::re_types_core::AsComponents for Asset3D { (Some(&self.blob as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Asset3D".into()), - archetype_field_name: Some(("blob").into()), - component_name: ("rerun.components.Blob").into(), - }), + descriptor_override: Some(Self::descriptor_blob()), } }), (self @@ -257,11 +259,7 @@ impl ::re_types_core::AsComponents for Asset3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Asset3D".into()), - archetype_field_name: Some(("media_type").into()), - component_name: ("rerun.components.MediaType").into(), - }), + descriptor_override: Some(Self::descriptor_media_type()), }), (self .albedo_factor @@ -269,11 +267,7 @@ impl ::re_types_core::AsComponents for Asset3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Asset3D".into()), - archetype_field_name: Some(("albedo_factor").into()), - component_name: ("rerun.components.AlbedoFactor").into(), - }), + descriptor_override: Some(Self::descriptor_albedo_factor()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/asset_video.rs b/crates/store/re_types/src/archetypes/asset_video.rs index 856a17b1f6b7..0b7a9a7b8b75 100644 --- a/crates/store/re_types/src/archetypes/asset_video.rs +++ b/crates/store/re_types/src/archetypes/asset_video.rs @@ -139,28 +139,46 @@ pub struct AssetVideo { pub media_type: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl AssetVideo { + /// Returns the [`ComponentDescriptor`] for [`Self::blob`]. + #[inline] + pub fn descriptor_blob() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.AssetVideo".into()), component_name: "rerun.components.Blob".into(), archetype_field_name: Some("blob".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::media_type`]. + #[inline] + pub fn descriptor_media_type() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.AssetVideo".into()), + component_name: "rerun.components.MediaType".into(), + archetype_field_name: Some("media_type".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.AssetVideo".into()), + component_name: "rerun.components.AssetVideoIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [AssetVideo::descriptor_blob()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.AssetVideo".into()), - component_name: "rerun.components.MediaType".into(), - archetype_field_name: Some("media_type".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.AssetVideo".into()), - component_name: "rerun.components.AssetVideoIndicator".into(), - archetype_field_name: None, - }, + AssetVideo::descriptor_media_type(), + AssetVideo::descriptor_indicator(), ] }); @@ -170,21 +188,9 @@ static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.AssetVideo".into()), - component_name: "rerun.components.Blob".into(), - archetype_field_name: Some("blob".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.AssetVideo".into()), - component_name: "rerun.components.MediaType".into(), - archetype_field_name: Some("media_type".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.AssetVideo".into()), - component_name: "rerun.components.AssetVideoIndicator".into(), - archetype_field_name: None, - }, + AssetVideo::descriptor_blob(), + AssetVideo::descriptor_media_type(), + AssetVideo::descriptor_indicator(), ] }); @@ -280,11 +286,7 @@ impl ::re_types_core::AsComponents for AssetVideo { (Some(&self.blob as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.AssetVideo".into()), - archetype_field_name: Some(("blob").into()), - component_name: ("rerun.components.Blob").into(), - }), + descriptor_override: Some(Self::descriptor_blob()), } }), (self @@ -293,11 +295,7 @@ impl ::re_types_core::AsComponents for AssetVideo { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.AssetVideo".into()), - archetype_field_name: Some(("media_type").into()), - component_name: ("rerun.components.MediaType").into(), - }), + descriptor_override: Some(Self::descriptor_media_type()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/bar_chart.rs b/crates/store/re_types/src/archetypes/bar_chart.rs index 97828fb96aa7..9266923588a8 100644 --- a/crates/store/re_types/src/archetypes/bar_chart.rs +++ b/crates/store/re_types/src/archetypes/bar_chart.rs @@ -55,51 +55,53 @@ pub struct BarChart { pub color: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl BarChart { + /// Returns the [`ComponentDescriptor`] for [`Self::values`]. + #[inline] + pub fn descriptor_values() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.BarChart".into()), component_name: "rerun.components.TensorData".into(), archetype_field_name: Some("values".into()), - }] - }); + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::color`]. + #[inline] + pub fn descriptor_color() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.BarChart".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("color".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.BarChart".into()), component_name: "rerun.components.BarChartIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [BarChart::descriptor_values()]); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [BarChart::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.archetypes.BarChart".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("color".into()), - }] - }); + once_cell::sync::Lazy::new(|| [BarChart::descriptor_color()]); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.BarChart".into()), - component_name: "rerun.components.TensorData".into(), - archetype_field_name: Some("values".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.BarChart".into()), - component_name: "rerun.components.BarChartIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.BarChart".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("color".into()), - }, + BarChart::descriptor_values(), + BarChart::descriptor_indicator(), + BarChart::descriptor_color(), ] }); @@ -195,11 +197,7 @@ impl ::re_types_core::AsComponents for BarChart { (Some(&self.values as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.BarChart".into()), - archetype_field_name: Some(("values").into()), - component_name: ("rerun.components.TensorData").into(), - }), + descriptor_override: Some(Self::descriptor_values()), } }), (self @@ -208,11 +206,7 @@ impl ::re_types_core::AsComponents for BarChart { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.BarChart".into()), - archetype_field_name: Some(("color").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_color()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/boxes2d.rs b/crates/store/re_types/src/archetypes/boxes2d.rs index 621dd5c88ec3..e63a642cf149 100644 --- a/crates/store/re_types/src/archetypes/boxes2d.rs +++ b/crates/store/re_types/src/archetypes/boxes2d.rs @@ -80,115 +80,133 @@ pub struct Boxes2D { pub class_ids: Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl Boxes2D { + /// Returns the [`ComponentDescriptor`] for [`Self::half_sizes`]. + #[inline] + pub fn descriptor_half_sizes() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Boxes2D".into()), component_name: "rerun.components.HalfSize2D".into(), archetype_field_name: Some("half_sizes".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::centers`]. + #[inline] + pub fn descriptor_centers() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes2D".into()), + component_name: "rerun.components.Position2D".into(), + archetype_field_name: Some("centers".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::colors`]. + #[inline] + pub fn descriptor_colors() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes2D".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("colors".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::radii`]. + #[inline] + pub fn descriptor_radii() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes2D".into()), + component_name: "rerun.components.Radius".into(), + archetype_field_name: Some("radii".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::labels`]. + #[inline] + pub fn descriptor_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes2D".into()), + component_name: "rerun.components.Text".into(), + archetype_field_name: Some("labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::show_labels`]. + #[inline] + pub fn descriptor_show_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes2D".into()), + component_name: "rerun.components.ShowLabels".into(), + archetype_field_name: Some("show_labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::draw_order`]. + #[inline] + pub fn descriptor_draw_order() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes2D".into()), + component_name: "rerun.components.DrawOrder".into(), + archetype_field_name: Some("draw_order".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::class_ids`]. + #[inline] + pub fn descriptor_class_ids() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes2D".into()), + component_name: "rerun.components.ClassId".into(), + archetype_field_name: Some("class_ids".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes2D".into()), + component_name: "rerun.components.Boxes2DIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Boxes2D::descriptor_half_sizes()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.Position2D".into(), - archetype_field_name: Some("centers".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.Boxes2DIndicator".into(), - archetype_field_name: None, - }, + Boxes2D::descriptor_centers(), + Boxes2D::descriptor_colors(), + Boxes2D::descriptor_indicator(), ] }); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.DrawOrder".into(), - archetype_field_name: Some("draw_order".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + Boxes2D::descriptor_radii(), + Boxes2D::descriptor_labels(), + Boxes2D::descriptor_show_labels(), + Boxes2D::descriptor_draw_order(), + Boxes2D::descriptor_class_ids(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 9usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.HalfSize2D".into(), - archetype_field_name: Some("half_sizes".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.Position2D".into(), - archetype_field_name: Some("centers".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.Boxes2DIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.DrawOrder".into(), - archetype_field_name: Some("draw_order".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + Boxes2D::descriptor_half_sizes(), + Boxes2D::descriptor_centers(), + Boxes2D::descriptor_colors(), + Boxes2D::descriptor_indicator(), + Boxes2D::descriptor_radii(), + Boxes2D::descriptor_labels(), + Boxes2D::descriptor_show_labels(), + Boxes2D::descriptor_draw_order(), + Boxes2D::descriptor_class_ids(), ] }); @@ -361,11 +379,7 @@ impl ::re_types_core::AsComponents for Boxes2D { (Some(&self.half_sizes as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - archetype_field_name: Some(("half_sizes").into()), - component_name: ("rerun.components.HalfSize2D").into(), - }), + descriptor_override: Some(Self::descriptor_half_sizes()), } }), (self @@ -374,11 +388,7 @@ impl ::re_types_core::AsComponents for Boxes2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - archetype_field_name: Some(("centers").into()), - component_name: ("rerun.components.Position2D").into(), - }), + descriptor_override: Some(Self::descriptor_centers()), }), (self .colors @@ -386,11 +396,7 @@ impl ::re_types_core::AsComponents for Boxes2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - archetype_field_name: Some(("colors").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_colors()), }), (self .radii @@ -398,11 +404,7 @@ impl ::re_types_core::AsComponents for Boxes2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - archetype_field_name: Some(("radii").into()), - component_name: ("rerun.components.Radius").into(), - }), + descriptor_override: Some(Self::descriptor_radii()), }), (self .labels @@ -410,11 +412,7 @@ impl ::re_types_core::AsComponents for Boxes2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - archetype_field_name: Some(("labels").into()), - component_name: ("rerun.components.Text").into(), - }), + descriptor_override: Some(Self::descriptor_labels()), }), (self .show_labels @@ -422,11 +420,7 @@ impl ::re_types_core::AsComponents for Boxes2D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - archetype_field_name: Some(("show_labels").into()), - component_name: ("rerun.components.ShowLabels").into(), - }), + descriptor_override: Some(Self::descriptor_show_labels()), }), (self .draw_order @@ -434,11 +428,7 @@ impl ::re_types_core::AsComponents for Boxes2D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - archetype_field_name: Some(("draw_order").into()), - component_name: ("rerun.components.DrawOrder").into(), - }), + descriptor_override: Some(Self::descriptor_draw_order()), }), (self .class_ids @@ -446,11 +436,7 @@ impl ::re_types_core::AsComponents for Boxes2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes2D".into()), - archetype_field_name: Some(("class_ids").into()), - component_name: ("rerun.components.ClassId").into(), - }), + descriptor_override: Some(Self::descriptor_class_ids()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/boxes3d.rs b/crates/store/re_types/src/archetypes/boxes3d.rs index 5a00f5fa2ca4..ff315f90f4f1 100644 --- a/crates/store/re_types/src/archetypes/boxes3d.rs +++ b/crates/store/re_types/src/archetypes/boxes3d.rs @@ -110,135 +110,157 @@ pub struct Boxes3D { pub class_ids: Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl Boxes3D { + /// Returns the [`ComponentDescriptor`] for [`Self::half_sizes`]. + #[inline] + pub fn descriptor_half_sizes() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Boxes3D".into()), component_name: "rerun.components.HalfSize3D".into(), archetype_field_name: Some("half_sizes".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::centers`]. + #[inline] + pub fn descriptor_centers() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes3D".into()), + component_name: "rerun.components.PoseTranslation3D".into(), + archetype_field_name: Some("centers".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::rotation_axis_angles`]. + #[inline] + pub fn descriptor_rotation_axis_angles() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes3D".into()), + component_name: "rerun.components.PoseRotationAxisAngle".into(), + archetype_field_name: Some("rotation_axis_angles".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::quaternions`]. + #[inline] + pub fn descriptor_quaternions() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes3D".into()), + component_name: "rerun.components.PoseRotationQuat".into(), + archetype_field_name: Some("quaternions".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::colors`]. + #[inline] + pub fn descriptor_colors() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes3D".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("colors".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::radii`]. + #[inline] + pub fn descriptor_radii() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes3D".into()), + component_name: "rerun.components.Radius".into(), + archetype_field_name: Some("radii".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fill_mode`]. + #[inline] + pub fn descriptor_fill_mode() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes3D".into()), + component_name: "rerun.components.FillMode".into(), + archetype_field_name: Some("fill_mode".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::labels`]. + #[inline] + pub fn descriptor_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes3D".into()), + component_name: "rerun.components.Text".into(), + archetype_field_name: Some("labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::show_labels`]. + #[inline] + pub fn descriptor_show_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes3D".into()), + component_name: "rerun.components.ShowLabels".into(), + archetype_field_name: Some("show_labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::class_ids`]. + #[inline] + pub fn descriptor_class_ids() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes3D".into()), + component_name: "rerun.components.ClassId".into(), + archetype_field_name: Some("class_ids".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Boxes3D".into()), + component_name: "rerun.components.Boxes3DIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Boxes3D::descriptor_half_sizes()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.PoseTranslation3D".into(), - archetype_field_name: Some("centers".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.Boxes3DIndicator".into(), - archetype_field_name: None, - }, + Boxes3D::descriptor_centers(), + Boxes3D::descriptor_colors(), + Boxes3D::descriptor_indicator(), ] }); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 7usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.PoseRotationAxisAngle".into(), - archetype_field_name: Some("rotation_axis_angles".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.PoseRotationQuat".into(), - archetype_field_name: Some("quaternions".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.FillMode".into(), - archetype_field_name: Some("fill_mode".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + Boxes3D::descriptor_rotation_axis_angles(), + Boxes3D::descriptor_quaternions(), + Boxes3D::descriptor_radii(), + Boxes3D::descriptor_fill_mode(), + Boxes3D::descriptor_labels(), + Boxes3D::descriptor_show_labels(), + Boxes3D::descriptor_class_ids(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 11usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.HalfSize3D".into(), - archetype_field_name: Some("half_sizes".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.PoseTranslation3D".into(), - archetype_field_name: Some("centers".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.Boxes3DIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.PoseRotationAxisAngle".into(), - archetype_field_name: Some("rotation_axis_angles".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.PoseRotationQuat".into(), - archetype_field_name: Some("quaternions".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.FillMode".into(), - archetype_field_name: Some("fill_mode".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + Boxes3D::descriptor_half_sizes(), + Boxes3D::descriptor_centers(), + Boxes3D::descriptor_colors(), + Boxes3D::descriptor_indicator(), + Boxes3D::descriptor_rotation_axis_angles(), + Boxes3D::descriptor_quaternions(), + Boxes3D::descriptor_radii(), + Boxes3D::descriptor_fill_mode(), + Boxes3D::descriptor_labels(), + Boxes3D::descriptor_show_labels(), + Boxes3D::descriptor_class_ids(), ] }); @@ -440,11 +462,7 @@ impl ::re_types_core::AsComponents for Boxes3D { (Some(&self.half_sizes as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - archetype_field_name: Some(("half_sizes").into()), - component_name: ("rerun.components.HalfSize3D").into(), - }), + descriptor_override: Some(Self::descriptor_half_sizes()), } }), (self @@ -453,11 +471,7 @@ impl ::re_types_core::AsComponents for Boxes3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - archetype_field_name: Some(("centers").into()), - component_name: ("rerun.components.PoseTranslation3D").into(), - }), + descriptor_override: Some(Self::descriptor_centers()), }), (self .rotation_axis_angles @@ -465,11 +479,7 @@ impl ::re_types_core::AsComponents for Boxes3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - archetype_field_name: Some(("rotation_axis_angles").into()), - component_name: ("rerun.components.PoseRotationAxisAngle").into(), - }), + descriptor_override: Some(Self::descriptor_rotation_axis_angles()), }), (self .quaternions @@ -477,11 +487,7 @@ impl ::re_types_core::AsComponents for Boxes3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - archetype_field_name: Some(("quaternions").into()), - component_name: ("rerun.components.PoseRotationQuat").into(), - }), + descriptor_override: Some(Self::descriptor_quaternions()), }), (self .colors @@ -489,11 +495,7 @@ impl ::re_types_core::AsComponents for Boxes3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - archetype_field_name: Some(("colors").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_colors()), }), (self .radii @@ -501,11 +503,7 @@ impl ::re_types_core::AsComponents for Boxes3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - archetype_field_name: Some(("radii").into()), - component_name: ("rerun.components.Radius").into(), - }), + descriptor_override: Some(Self::descriptor_radii()), }), (self .fill_mode @@ -513,11 +511,7 @@ impl ::re_types_core::AsComponents for Boxes3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - archetype_field_name: Some(("fill_mode").into()), - component_name: ("rerun.components.FillMode").into(), - }), + descriptor_override: Some(Self::descriptor_fill_mode()), }), (self .labels @@ -525,11 +519,7 @@ impl ::re_types_core::AsComponents for Boxes3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - archetype_field_name: Some(("labels").into()), - component_name: ("rerun.components.Text").into(), - }), + descriptor_override: Some(Self::descriptor_labels()), }), (self .show_labels @@ -537,11 +527,7 @@ impl ::re_types_core::AsComponents for Boxes3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - archetype_field_name: Some(("show_labels").into()), - component_name: ("rerun.components.ShowLabels").into(), - }), + descriptor_override: Some(Self::descriptor_show_labels()), }), (self .class_ids @@ -549,11 +535,7 @@ impl ::re_types_core::AsComponents for Boxes3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Boxes3D".into()), - archetype_field_name: Some(("class_ids").into()), - component_name: ("rerun.components.ClassId").into(), - }), + descriptor_override: Some(Self::descriptor_class_ids()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/capsules3d.rs b/crates/store/re_types/src/archetypes/capsules3d.rs index 410b68eebb6d..cde7146f436e 100644 --- a/crates/store/re_types/src/archetypes/capsules3d.rs +++ b/crates/store/re_types/src/archetypes/capsules3d.rs @@ -112,127 +112,149 @@ pub struct Capsules3D { pub class_ids: Option>, } +impl Capsules3D { + /// Returns the [`ComponentDescriptor`] for [`Self::lengths`]. + #[inline] + pub fn descriptor_lengths() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Capsules3D".into()), + component_name: "rerun.components.Length".into(), + archetype_field_name: Some("lengths".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::radii`]. + #[inline] + pub fn descriptor_radii() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Capsules3D".into()), + component_name: "rerun.components.Radius".into(), + archetype_field_name: Some("radii".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::translations`]. + #[inline] + pub fn descriptor_translations() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Capsules3D".into()), + component_name: "rerun.components.PoseTranslation3D".into(), + archetype_field_name: Some("translations".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::rotation_axis_angles`]. + #[inline] + pub fn descriptor_rotation_axis_angles() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Capsules3D".into()), + component_name: "rerun.components.PoseRotationAxisAngle".into(), + archetype_field_name: Some("rotation_axis_angles".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::quaternions`]. + #[inline] + pub fn descriptor_quaternions() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Capsules3D".into()), + component_name: "rerun.components.PoseRotationQuat".into(), + archetype_field_name: Some("quaternions".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::colors`]. + #[inline] + pub fn descriptor_colors() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Capsules3D".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("colors".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::labels`]. + #[inline] + pub fn descriptor_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Capsules3D".into()), + component_name: "rerun.components.Text".into(), + archetype_field_name: Some("labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::show_labels`]. + #[inline] + pub fn descriptor_show_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Capsules3D".into()), + component_name: "rerun.components.ShowLabels".into(), + archetype_field_name: Some("show_labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::class_ids`]. + #[inline] + pub fn descriptor_class_ids() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Capsules3D".into()), + component_name: "rerun.components.ClassId".into(), + archetype_field_name: Some("class_ids".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Capsules3D".into()), + component_name: "rerun.components.Capsules3DIndicator".into(), + archetype_field_name: None, + } + } +} + static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.Length".into(), - archetype_field_name: Some("lengths".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, + Capsules3D::descriptor_lengths(), + Capsules3D::descriptor_radii(), ] }); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.PoseTranslation3D".into(), - archetype_field_name: Some("translations".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.Capsules3DIndicator".into(), - archetype_field_name: None, - }, + Capsules3D::descriptor_translations(), + Capsules3D::descriptor_colors(), + Capsules3D::descriptor_indicator(), ] }); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.PoseRotationAxisAngle".into(), - archetype_field_name: Some("rotation_axis_angles".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.PoseRotationQuat".into(), - archetype_field_name: Some("quaternions".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + Capsules3D::descriptor_rotation_axis_angles(), + Capsules3D::descriptor_quaternions(), + Capsules3D::descriptor_labels(), + Capsules3D::descriptor_show_labels(), + Capsules3D::descriptor_class_ids(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 10usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.Length".into(), - archetype_field_name: Some("lengths".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.PoseTranslation3D".into(), - archetype_field_name: Some("translations".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.Capsules3DIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.PoseRotationAxisAngle".into(), - archetype_field_name: Some("rotation_axis_angles".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.PoseRotationQuat".into(), - archetype_field_name: Some("quaternions".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + Capsules3D::descriptor_lengths(), + Capsules3D::descriptor_radii(), + Capsules3D::descriptor_translations(), + Capsules3D::descriptor_colors(), + Capsules3D::descriptor_indicator(), + Capsules3D::descriptor_rotation_axis_angles(), + Capsules3D::descriptor_quaternions(), + Capsules3D::descriptor_labels(), + Capsules3D::descriptor_show_labels(), + Capsules3D::descriptor_class_ids(), ] }); @@ -424,21 +446,13 @@ impl ::re_types_core::AsComponents for Capsules3D { (Some(&self.lengths as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - archetype_field_name: Some(("lengths").into()), - component_name: ("rerun.components.Length").into(), - }), + descriptor_override: Some(Self::descriptor_lengths()), } }), (Some(&self.radii as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - archetype_field_name: Some(("radii").into()), - component_name: ("rerun.components.Radius").into(), - }), + descriptor_override: Some(Self::descriptor_radii()), } }), (self @@ -447,11 +461,7 @@ impl ::re_types_core::AsComponents for Capsules3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - archetype_field_name: Some(("translations").into()), - component_name: ("rerun.components.PoseTranslation3D").into(), - }), + descriptor_override: Some(Self::descriptor_translations()), }), (self .rotation_axis_angles @@ -459,11 +469,7 @@ impl ::re_types_core::AsComponents for Capsules3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - archetype_field_name: Some(("rotation_axis_angles").into()), - component_name: ("rerun.components.PoseRotationAxisAngle").into(), - }), + descriptor_override: Some(Self::descriptor_rotation_axis_angles()), }), (self .quaternions @@ -471,11 +477,7 @@ impl ::re_types_core::AsComponents for Capsules3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - archetype_field_name: Some(("quaternions").into()), - component_name: ("rerun.components.PoseRotationQuat").into(), - }), + descriptor_override: Some(Self::descriptor_quaternions()), }), (self .colors @@ -483,11 +485,7 @@ impl ::re_types_core::AsComponents for Capsules3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - archetype_field_name: Some(("colors").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_colors()), }), (self .labels @@ -495,11 +493,7 @@ impl ::re_types_core::AsComponents for Capsules3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - archetype_field_name: Some(("labels").into()), - component_name: ("rerun.components.Text").into(), - }), + descriptor_override: Some(Self::descriptor_labels()), }), (self .show_labels @@ -507,11 +501,7 @@ impl ::re_types_core::AsComponents for Capsules3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - archetype_field_name: Some(("show_labels").into()), - component_name: ("rerun.components.ShowLabels").into(), - }), + descriptor_override: Some(Self::descriptor_show_labels()), }), (self .class_ids @@ -519,11 +509,7 @@ impl ::re_types_core::AsComponents for Capsules3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Capsules3D".into()), - archetype_field_name: Some(("class_ids").into()), - component_name: ("rerun.components.ClassId").into(), - }), + descriptor_override: Some(Self::descriptor_class_ids()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/depth_image.rs b/crates/store/re_types/src/archetypes/depth_image.rs index 2e5eb6b738b3..11beeea781fd 100644 --- a/crates/store/re_types/src/archetypes/depth_image.rs +++ b/crates/store/re_types/src/archetypes/depth_image.rs @@ -114,105 +114,121 @@ pub struct DepthImage { pub draw_order: Option, } +impl DepthImage { + /// Returns the [`ComponentDescriptor`] for [`Self::buffer`]. + #[inline] + pub fn descriptor_buffer() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.DepthImage".into()), + component_name: "rerun.components.ImageBuffer".into(), + archetype_field_name: Some("buffer".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::format`]. + #[inline] + pub fn descriptor_format() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.DepthImage".into()), + component_name: "rerun.components.ImageFormat".into(), + archetype_field_name: Some("format".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::meter`]. + #[inline] + pub fn descriptor_meter() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.DepthImage".into()), + component_name: "rerun.components.DepthMeter".into(), + archetype_field_name: Some("meter".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::colormap`]. + #[inline] + pub fn descriptor_colormap() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.DepthImage".into()), + component_name: "rerun.components.Colormap".into(), + archetype_field_name: Some("colormap".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::depth_range`]. + #[inline] + pub fn descriptor_depth_range() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.DepthImage".into()), + component_name: "rerun.components.ValueRange".into(), + archetype_field_name: Some("depth_range".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::point_fill_ratio`]. + #[inline] + pub fn descriptor_point_fill_ratio() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.DepthImage".into()), + component_name: "rerun.components.FillRatio".into(), + archetype_field_name: Some("point_fill_ratio".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::draw_order`]. + #[inline] + pub fn descriptor_draw_order() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.DepthImage".into()), + component_name: "rerun.components.DrawOrder".into(), + archetype_field_name: Some("draw_order".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.DepthImage".into()), + component_name: "rerun.components.DepthImageIndicator".into(), + archetype_field_name: None, + } + } +} + static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - component_name: "rerun.components.ImageBuffer".into(), - archetype_field_name: Some("buffer".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - component_name: "rerun.components.ImageFormat".into(), - archetype_field_name: Some("format".into()), - }, + DepthImage::descriptor_buffer(), + DepthImage::descriptor_format(), ] }); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - component_name: "rerun.components.DepthImageIndicator".into(), - archetype_field_name: None, - }] - }); + once_cell::sync::Lazy::new(|| [DepthImage::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - component_name: "rerun.components.DepthMeter".into(), - archetype_field_name: Some("meter".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - component_name: "rerun.components.Colormap".into(), - archetype_field_name: Some("colormap".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - component_name: "rerun.components.ValueRange".into(), - archetype_field_name: Some("depth_range".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - component_name: "rerun.components.FillRatio".into(), - archetype_field_name: Some("point_fill_ratio".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - component_name: "rerun.components.DrawOrder".into(), - archetype_field_name: Some("draw_order".into()), - }, + DepthImage::descriptor_meter(), + DepthImage::descriptor_colormap(), + DepthImage::descriptor_depth_range(), + DepthImage::descriptor_point_fill_ratio(), + DepthImage::descriptor_draw_order(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 8usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - component_name: "rerun.components.ImageBuffer".into(), - archetype_field_name: Some("buffer".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - component_name: "rerun.components.ImageFormat".into(), - archetype_field_name: Some("format".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - component_name: "rerun.components.DepthImageIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - component_name: "rerun.components.DepthMeter".into(), - archetype_field_name: Some("meter".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - component_name: "rerun.components.Colormap".into(), - archetype_field_name: Some("colormap".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - component_name: "rerun.components.ValueRange".into(), - archetype_field_name: Some("depth_range".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - component_name: "rerun.components.FillRatio".into(), - archetype_field_name: Some("point_fill_ratio".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - component_name: "rerun.components.DrawOrder".into(), - archetype_field_name: Some("draw_order".into()), - }, + DepthImage::descriptor_buffer(), + DepthImage::descriptor_format(), + DepthImage::descriptor_indicator(), + DepthImage::descriptor_meter(), + DepthImage::descriptor_colormap(), + DepthImage::descriptor_depth_range(), + DepthImage::descriptor_point_fill_ratio(), + DepthImage::descriptor_draw_order(), ] }); @@ -366,21 +382,13 @@ impl ::re_types_core::AsComponents for DepthImage { (Some(&self.buffer as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - archetype_field_name: Some(("buffer").into()), - component_name: ("rerun.components.ImageBuffer").into(), - }), + descriptor_override: Some(Self::descriptor_buffer()), } }), (Some(&self.format as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - archetype_field_name: Some(("format").into()), - component_name: ("rerun.components.ImageFormat").into(), - }), + descriptor_override: Some(Self::descriptor_format()), } }), (self @@ -389,11 +397,7 @@ impl ::re_types_core::AsComponents for DepthImage { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - archetype_field_name: Some(("meter").into()), - component_name: ("rerun.components.DepthMeter").into(), - }), + descriptor_override: Some(Self::descriptor_meter()), }), (self .colormap @@ -401,11 +405,7 @@ impl ::re_types_core::AsComponents for DepthImage { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - archetype_field_name: Some(("colormap").into()), - component_name: ("rerun.components.Colormap").into(), - }), + descriptor_override: Some(Self::descriptor_colormap()), }), (self .depth_range @@ -413,11 +413,7 @@ impl ::re_types_core::AsComponents for DepthImage { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - archetype_field_name: Some(("depth_range").into()), - component_name: ("rerun.components.ValueRange").into(), - }), + descriptor_override: Some(Self::descriptor_depth_range()), }), (self .point_fill_ratio @@ -425,11 +421,7 @@ impl ::re_types_core::AsComponents for DepthImage { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - archetype_field_name: Some(("point_fill_ratio").into()), - component_name: ("rerun.components.FillRatio").into(), - }), + descriptor_override: Some(Self::descriptor_point_fill_ratio()), }), (self .draw_order @@ -437,11 +429,7 @@ impl ::re_types_core::AsComponents for DepthImage { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.DepthImage".into()), - archetype_field_name: Some(("draw_order").into()), - component_name: ("rerun.components.DrawOrder").into(), - }), + descriptor_override: Some(Self::descriptor_draw_order()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/ellipsoids3d.rs b/crates/store/re_types/src/archetypes/ellipsoids3d.rs index 599594eb024c..298b0dc8c72f 100644 --- a/crates/store/re_types/src/archetypes/ellipsoids3d.rs +++ b/crates/store/re_types/src/archetypes/ellipsoids3d.rs @@ -125,135 +125,157 @@ pub struct Ellipsoids3D { pub class_ids: Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl Ellipsoids3D { + /// Returns the [`ComponentDescriptor`] for [`Self::half_sizes`]. + #[inline] + pub fn descriptor_half_sizes() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), component_name: "rerun.components.HalfSize3D".into(), archetype_field_name: Some("half_sizes".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::centers`]. + #[inline] + pub fn descriptor_centers() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), + component_name: "rerun.components.PoseTranslation3D".into(), + archetype_field_name: Some("centers".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::rotation_axis_angles`]. + #[inline] + pub fn descriptor_rotation_axis_angles() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), + component_name: "rerun.components.PoseRotationAxisAngle".into(), + archetype_field_name: Some("rotation_axis_angles".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::quaternions`]. + #[inline] + pub fn descriptor_quaternions() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), + component_name: "rerun.components.PoseRotationQuat".into(), + archetype_field_name: Some("quaternions".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::colors`]. + #[inline] + pub fn descriptor_colors() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("colors".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::line_radii`]. + #[inline] + pub fn descriptor_line_radii() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), + component_name: "rerun.components.Radius".into(), + archetype_field_name: Some("line_radii".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fill_mode`]. + #[inline] + pub fn descriptor_fill_mode() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), + component_name: "rerun.components.FillMode".into(), + archetype_field_name: Some("fill_mode".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::labels`]. + #[inline] + pub fn descriptor_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), + component_name: "rerun.components.Text".into(), + archetype_field_name: Some("labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::show_labels`]. + #[inline] + pub fn descriptor_show_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), + component_name: "rerun.components.ShowLabels".into(), + archetype_field_name: Some("show_labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::class_ids`]. + #[inline] + pub fn descriptor_class_ids() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), + component_name: "rerun.components.ClassId".into(), + archetype_field_name: Some("class_ids".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), + component_name: "rerun.components.Ellipsoids3DIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Ellipsoids3D::descriptor_half_sizes()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.PoseTranslation3D".into(), - archetype_field_name: Some("centers".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.Ellipsoids3DIndicator".into(), - archetype_field_name: None, - }, + Ellipsoids3D::descriptor_centers(), + Ellipsoids3D::descriptor_colors(), + Ellipsoids3D::descriptor_indicator(), ] }); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 7usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.PoseRotationAxisAngle".into(), - archetype_field_name: Some("rotation_axis_angles".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.PoseRotationQuat".into(), - archetype_field_name: Some("quaternions".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("line_radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.FillMode".into(), - archetype_field_name: Some("fill_mode".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + Ellipsoids3D::descriptor_rotation_axis_angles(), + Ellipsoids3D::descriptor_quaternions(), + Ellipsoids3D::descriptor_line_radii(), + Ellipsoids3D::descriptor_fill_mode(), + Ellipsoids3D::descriptor_labels(), + Ellipsoids3D::descriptor_show_labels(), + Ellipsoids3D::descriptor_class_ids(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 11usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.HalfSize3D".into(), - archetype_field_name: Some("half_sizes".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.PoseTranslation3D".into(), - archetype_field_name: Some("centers".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.Ellipsoids3DIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.PoseRotationAxisAngle".into(), - archetype_field_name: Some("rotation_axis_angles".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.PoseRotationQuat".into(), - archetype_field_name: Some("quaternions".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("line_radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.FillMode".into(), - archetype_field_name: Some("fill_mode".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + Ellipsoids3D::descriptor_half_sizes(), + Ellipsoids3D::descriptor_centers(), + Ellipsoids3D::descriptor_colors(), + Ellipsoids3D::descriptor_indicator(), + Ellipsoids3D::descriptor_rotation_axis_angles(), + Ellipsoids3D::descriptor_quaternions(), + Ellipsoids3D::descriptor_line_radii(), + Ellipsoids3D::descriptor_fill_mode(), + Ellipsoids3D::descriptor_labels(), + Ellipsoids3D::descriptor_show_labels(), + Ellipsoids3D::descriptor_class_ids(), ] }); @@ -455,11 +477,7 @@ impl ::re_types_core::AsComponents for Ellipsoids3D { (Some(&self.half_sizes as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - archetype_field_name: Some(("half_sizes").into()), - component_name: ("rerun.components.HalfSize3D").into(), - }), + descriptor_override: Some(Self::descriptor_half_sizes()), } }), (self @@ -468,11 +486,7 @@ impl ::re_types_core::AsComponents for Ellipsoids3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - archetype_field_name: Some(("centers").into()), - component_name: ("rerun.components.PoseTranslation3D").into(), - }), + descriptor_override: Some(Self::descriptor_centers()), }), (self .rotation_axis_angles @@ -480,11 +494,7 @@ impl ::re_types_core::AsComponents for Ellipsoids3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - archetype_field_name: Some(("rotation_axis_angles").into()), - component_name: ("rerun.components.PoseRotationAxisAngle").into(), - }), + descriptor_override: Some(Self::descriptor_rotation_axis_angles()), }), (self .quaternions @@ -492,11 +502,7 @@ impl ::re_types_core::AsComponents for Ellipsoids3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - archetype_field_name: Some(("quaternions").into()), - component_name: ("rerun.components.PoseRotationQuat").into(), - }), + descriptor_override: Some(Self::descriptor_quaternions()), }), (self .colors @@ -504,11 +510,7 @@ impl ::re_types_core::AsComponents for Ellipsoids3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - archetype_field_name: Some(("colors").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_colors()), }), (self .line_radii @@ -516,11 +518,7 @@ impl ::re_types_core::AsComponents for Ellipsoids3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - archetype_field_name: Some(("line_radii").into()), - component_name: ("rerun.components.Radius").into(), - }), + descriptor_override: Some(Self::descriptor_line_radii()), }), (self .fill_mode @@ -528,11 +526,7 @@ impl ::re_types_core::AsComponents for Ellipsoids3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - archetype_field_name: Some(("fill_mode").into()), - component_name: ("rerun.components.FillMode").into(), - }), + descriptor_override: Some(Self::descriptor_fill_mode()), }), (self .labels @@ -540,11 +534,7 @@ impl ::re_types_core::AsComponents for Ellipsoids3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - archetype_field_name: Some(("labels").into()), - component_name: ("rerun.components.Text").into(), - }), + descriptor_override: Some(Self::descriptor_labels()), }), (self .show_labels @@ -552,11 +542,7 @@ impl ::re_types_core::AsComponents for Ellipsoids3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - archetype_field_name: Some(("show_labels").into()), - component_name: ("rerun.components.ShowLabels").into(), - }), + descriptor_override: Some(Self::descriptor_show_labels()), }), (self .class_ids @@ -564,11 +550,7 @@ impl ::re_types_core::AsComponents for Ellipsoids3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Ellipsoids3D".into()), - archetype_field_name: Some(("class_ids").into()), - component_name: ("rerun.components.ClassId").into(), - }), + descriptor_override: Some(Self::descriptor_class_ids()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/encoded_image.rs b/crates/store/re_types/src/archetypes/encoded_image.rs index 1b52f4ffea6c..06cbdfc4fe80 100644 --- a/crates/store/re_types/src/archetypes/encoded_image.rs +++ b/crates/store/re_types/src/archetypes/encoded_image.rs @@ -66,75 +66,85 @@ pub struct EncodedImage { pub draw_order: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl EncodedImage { + /// Returns the [`ComponentDescriptor`] for [`Self::blob`]. + #[inline] + pub fn descriptor_blob() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.EncodedImage".into()), component_name: "rerun.components.Blob".into(), archetype_field_name: Some("blob".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::media_type`]. + #[inline] + pub fn descriptor_media_type() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.EncodedImage".into()), + component_name: "rerun.components.MediaType".into(), + archetype_field_name: Some("media_type".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::opacity`]. + #[inline] + pub fn descriptor_opacity() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.EncodedImage".into()), + component_name: "rerun.components.Opacity".into(), + archetype_field_name: Some("opacity".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::draw_order`]. + #[inline] + pub fn descriptor_draw_order() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.EncodedImage".into()), + component_name: "rerun.components.DrawOrder".into(), + archetype_field_name: Some("draw_order".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.EncodedImage".into()), + component_name: "rerun.components.EncodedImageIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [EncodedImage::descriptor_blob()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.EncodedImage".into()), - component_name: "rerun.components.MediaType".into(), - archetype_field_name: Some("media_type".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.EncodedImage".into()), - component_name: "rerun.components.EncodedImageIndicator".into(), - archetype_field_name: None, - }, + EncodedImage::descriptor_media_type(), + EncodedImage::descriptor_indicator(), ] }); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.EncodedImage".into()), - component_name: "rerun.components.Opacity".into(), - archetype_field_name: Some("opacity".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.EncodedImage".into()), - component_name: "rerun.components.DrawOrder".into(), - archetype_field_name: Some("draw_order".into()), - }, + EncodedImage::descriptor_opacity(), + EncodedImage::descriptor_draw_order(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.EncodedImage".into()), - component_name: "rerun.components.Blob".into(), - archetype_field_name: Some("blob".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.EncodedImage".into()), - component_name: "rerun.components.MediaType".into(), - archetype_field_name: Some("media_type".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.EncodedImage".into()), - component_name: "rerun.components.EncodedImageIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.EncodedImage".into()), - component_name: "rerun.components.Opacity".into(), - archetype_field_name: Some("opacity".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.EncodedImage".into()), - component_name: "rerun.components.DrawOrder".into(), - archetype_field_name: Some("draw_order".into()), - }, + EncodedImage::descriptor_blob(), + EncodedImage::descriptor_media_type(), + EncodedImage::descriptor_indicator(), + EncodedImage::descriptor_opacity(), + EncodedImage::descriptor_draw_order(), ] }); @@ -253,11 +263,7 @@ impl ::re_types_core::AsComponents for EncodedImage { (Some(&self.blob as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.EncodedImage".into()), - archetype_field_name: Some(("blob").into()), - component_name: ("rerun.components.Blob").into(), - }), + descriptor_override: Some(Self::descriptor_blob()), } }), (self @@ -266,11 +272,7 @@ impl ::re_types_core::AsComponents for EncodedImage { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.EncodedImage".into()), - archetype_field_name: Some(("media_type").into()), - component_name: ("rerun.components.MediaType").into(), - }), + descriptor_override: Some(Self::descriptor_media_type()), }), (self .opacity @@ -278,11 +280,7 @@ impl ::re_types_core::AsComponents for EncodedImage { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.EncodedImage".into()), - archetype_field_name: Some(("opacity").into()), - component_name: ("rerun.components.Opacity").into(), - }), + descriptor_override: Some(Self::descriptor_opacity()), }), (self .draw_order @@ -290,11 +288,7 @@ impl ::re_types_core::AsComponents for EncodedImage { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.EncodedImage".into()), - archetype_field_name: Some(("draw_order").into()), - component_name: ("rerun.components.DrawOrder").into(), - }), + descriptor_override: Some(Self::descriptor_draw_order()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/geo_line_strings.rs b/crates/store/re_types/src/archetypes/geo_line_strings.rs index 966ec1322fed..31b18ba53665 100644 --- a/crates/store/re_types/src/archetypes/geo_line_strings.rs +++ b/crates/store/re_types/src/archetypes/geo_line_strings.rs @@ -69,33 +69,57 @@ pub struct GeoLineStrings { pub colors: Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl GeoLineStrings { + /// Returns the [`ComponentDescriptor`] for [`Self::line_strings`]. + #[inline] + pub fn descriptor_line_strings() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.GeoLineStrings".into()), component_name: "rerun.components.GeoLineString".into(), archetype_field_name: Some("line_strings".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::radii`]. + #[inline] + pub fn descriptor_radii() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.GeoLineStrings".into()), + component_name: "rerun.components.Radius".into(), + archetype_field_name: Some("radii".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::colors`]. + #[inline] + pub fn descriptor_colors() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.GeoLineStrings".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("colors".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.GeoLineStrings".into()), + component_name: "rerun.components.GeoLineStringsIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [GeoLineStrings::descriptor_line_strings()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoLineStrings".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoLineStrings".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoLineStrings".into()), - component_name: "rerun.components.GeoLineStringsIndicator".into(), - archetype_field_name: None, - }, + GeoLineStrings::descriptor_radii(), + GeoLineStrings::descriptor_colors(), + GeoLineStrings::descriptor_indicator(), ] }); @@ -105,26 +129,10 @@ static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 4usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoLineStrings".into()), - component_name: "rerun.components.GeoLineString".into(), - archetype_field_name: Some("line_strings".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoLineStrings".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoLineStrings".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoLineStrings".into()), - component_name: "rerun.components.GeoLineStringsIndicator".into(), - archetype_field_name: None, - }, + GeoLineStrings::descriptor_line_strings(), + GeoLineStrings::descriptor_radii(), + GeoLineStrings::descriptor_colors(), + GeoLineStrings::descriptor_indicator(), ] }); @@ -238,11 +246,7 @@ impl ::re_types_core::AsComponents for GeoLineStrings { (Some(&self.line_strings as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoLineStrings".into()), - archetype_field_name: Some(("line_strings").into()), - component_name: ("rerun.components.GeoLineString").into(), - }), + descriptor_override: Some(Self::descriptor_line_strings()), } }), (self @@ -251,11 +255,7 @@ impl ::re_types_core::AsComponents for GeoLineStrings { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoLineStrings".into()), - archetype_field_name: Some(("radii").into()), - component_name: ("rerun.components.Radius").into(), - }), + descriptor_override: Some(Self::descriptor_radii()), }), (self .colors @@ -263,11 +263,7 @@ impl ::re_types_core::AsComponents for GeoLineStrings { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoLineStrings".into()), - archetype_field_name: Some(("colors").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_colors()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/geo_points.rs b/crates/store/re_types/src/archetypes/geo_points.rs index 6848922417a8..80f8c1e41005 100644 --- a/crates/store/re_types/src/archetypes/geo_points.rs +++ b/crates/store/re_types/src/archetypes/geo_points.rs @@ -65,73 +65,81 @@ pub struct GeoPoints { pub class_ids: Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl GeoPoints { + /// Returns the [`ComponentDescriptor`] for [`Self::positions`]. + #[inline] + pub fn descriptor_positions() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.GeoPoints".into()), component_name: "rerun.components.LatLon".into(), archetype_field_name: Some("positions".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::radii`]. + #[inline] + pub fn descriptor_radii() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.GeoPoints".into()), + component_name: "rerun.components.Radius".into(), + archetype_field_name: Some("radii".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::colors`]. + #[inline] + pub fn descriptor_colors() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.GeoPoints".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("colors".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::class_ids`]. + #[inline] + pub fn descriptor_class_ids() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.GeoPoints".into()), + component_name: "rerun.components.ClassId".into(), + archetype_field_name: Some("class_ids".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.GeoPoints".into()), + component_name: "rerun.components.GeoPointsIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [GeoPoints::descriptor_positions()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoPoints".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoPoints".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoPoints".into()), - component_name: "rerun.components.GeoPointsIndicator".into(), - archetype_field_name: None, - }, + GeoPoints::descriptor_radii(), + GeoPoints::descriptor_colors(), + GeoPoints::descriptor_indicator(), ] }); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoPoints".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }] - }); + once_cell::sync::Lazy::new(|| [GeoPoints::descriptor_class_ids()]); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoPoints".into()), - component_name: "rerun.components.LatLon".into(), - archetype_field_name: Some("positions".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoPoints".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoPoints".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoPoints".into()), - component_name: "rerun.components.GeoPointsIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoPoints".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + GeoPoints::descriptor_positions(), + GeoPoints::descriptor_radii(), + GeoPoints::descriptor_colors(), + GeoPoints::descriptor_indicator(), + GeoPoints::descriptor_class_ids(), ] }); @@ -258,11 +266,7 @@ impl ::re_types_core::AsComponents for GeoPoints { (Some(&self.positions as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoPoints".into()), - archetype_field_name: Some(("positions").into()), - component_name: ("rerun.components.LatLon").into(), - }), + descriptor_override: Some(Self::descriptor_positions()), } }), (self @@ -271,11 +275,7 @@ impl ::re_types_core::AsComponents for GeoPoints { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoPoints".into()), - archetype_field_name: Some(("radii").into()), - component_name: ("rerun.components.Radius").into(), - }), + descriptor_override: Some(Self::descriptor_radii()), }), (self .colors @@ -283,11 +283,7 @@ impl ::re_types_core::AsComponents for GeoPoints { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoPoints".into()), - archetype_field_name: Some(("colors").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_colors()), }), (self .class_ids @@ -295,11 +291,7 @@ impl ::re_types_core::AsComponents for GeoPoints { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GeoPoints".into()), - archetype_field_name: Some(("class_ids").into()), - component_name: ("rerun.components.ClassId").into(), - }), + descriptor_override: Some(Self::descriptor_class_ids()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/graph_edges.rs b/crates/store/re_types/src/archetypes/graph_edges.rs index ceba5572d6b6..6371259a5cdf 100644 --- a/crates/store/re_types/src/archetypes/graph_edges.rs +++ b/crates/store/re_types/src/archetypes/graph_edges.rs @@ -62,28 +62,46 @@ pub struct GraphEdges { pub graph_type: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl GraphEdges { + /// Returns the [`ComponentDescriptor`] for [`Self::edges`]. + #[inline] + pub fn descriptor_edges() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.GraphEdges".into()), component_name: "rerun.components.GraphEdge".into(), archetype_field_name: Some("edges".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::graph_type`]. + #[inline] + pub fn descriptor_graph_type() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.GraphEdges".into()), + component_name: "rerun.components.GraphType".into(), + archetype_field_name: Some("graph_type".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.GraphEdges".into()), + component_name: "rerun.components.GraphEdgesIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [GraphEdges::descriptor_edges()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphEdges".into()), - component_name: "rerun.components.GraphType".into(), - archetype_field_name: Some("graph_type".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphEdges".into()), - component_name: "rerun.components.GraphEdgesIndicator".into(), - archetype_field_name: None, - }, + GraphEdges::descriptor_graph_type(), + GraphEdges::descriptor_indicator(), ] }); @@ -93,21 +111,9 @@ static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphEdges".into()), - component_name: "rerun.components.GraphEdge".into(), - archetype_field_name: Some("edges".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphEdges".into()), - component_name: "rerun.components.GraphType".into(), - archetype_field_name: Some("graph_type".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphEdges".into()), - component_name: "rerun.components.GraphEdgesIndicator".into(), - archetype_field_name: None, - }, + GraphEdges::descriptor_edges(), + GraphEdges::descriptor_graph_type(), + GraphEdges::descriptor_indicator(), ] }); @@ -202,11 +208,7 @@ impl ::re_types_core::AsComponents for GraphEdges { (Some(&self.edges as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphEdges".into()), - archetype_field_name: Some(("edges").into()), - component_name: ("rerun.components.GraphEdge").into(), - }), + descriptor_override: Some(Self::descriptor_edges()), } }), (self @@ -215,11 +217,7 @@ impl ::re_types_core::AsComponents for GraphEdges { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphEdges".into()), - archetype_field_name: Some(("graph_type").into()), - component_name: ("rerun.components.GraphType").into(), - }), + descriptor_override: Some(Self::descriptor_graph_type()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/graph_nodes.rs b/crates/store/re_types/src/archetypes/graph_nodes.rs index 31c505661c08..8186855da835 100644 --- a/crates/store/re_types/src/archetypes/graph_nodes.rs +++ b/crates/store/re_types/src/archetypes/graph_nodes.rs @@ -70,93 +70,105 @@ pub struct GraphNodes { pub radii: Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl GraphNodes { + /// Returns the [`ComponentDescriptor`] for [`Self::node_ids`]. + #[inline] + pub fn descriptor_node_ids() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.GraphNodes".into()), component_name: "rerun.components.GraphNode".into(), archetype_field_name: Some("node_ids".into()), - }] - }); + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::positions`]. + #[inline] + pub fn descriptor_positions() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.GraphNodes".into()), + component_name: "rerun.components.Position2D".into(), + archetype_field_name: Some("positions".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::colors`]. + #[inline] + pub fn descriptor_colors() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.GraphNodes".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("colors".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::labels`]. + #[inline] + pub fn descriptor_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.GraphNodes".into()), + component_name: "rerun.components.Text".into(), + archetype_field_name: Some("labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::show_labels`]. + #[inline] + pub fn descriptor_show_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.GraphNodes".into()), + component_name: "rerun.components.ShowLabels".into(), + archetype_field_name: Some("show_labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::radii`]. + #[inline] + pub fn descriptor_radii() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.GraphNodes".into()), + component_name: "rerun.components.Radius".into(), + archetype_field_name: Some("radii".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.GraphNodes".into()), component_name: "rerun.components.GraphNodesIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [GraphNodes::descriptor_node_ids()]); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [GraphNodes::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - component_name: "rerun.components.Position2D".into(), - archetype_field_name: Some("positions".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, + GraphNodes::descriptor_positions(), + GraphNodes::descriptor_colors(), + GraphNodes::descriptor_labels(), + GraphNodes::descriptor_show_labels(), + GraphNodes::descriptor_radii(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 7usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - component_name: "rerun.components.GraphNode".into(), - archetype_field_name: Some("node_ids".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - component_name: "rerun.components.GraphNodesIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - component_name: "rerun.components.Position2D".into(), - archetype_field_name: Some("positions".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, + GraphNodes::descriptor_node_ids(), + GraphNodes::descriptor_indicator(), + GraphNodes::descriptor_positions(), + GraphNodes::descriptor_colors(), + GraphNodes::descriptor_labels(), + GraphNodes::descriptor_show_labels(), + GraphNodes::descriptor_radii(), ] }); @@ -306,11 +318,7 @@ impl ::re_types_core::AsComponents for GraphNodes { (Some(&self.node_ids as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - archetype_field_name: Some(("node_ids").into()), - component_name: ("rerun.components.GraphNode").into(), - }), + descriptor_override: Some(Self::descriptor_node_ids()), } }), (self @@ -319,11 +327,7 @@ impl ::re_types_core::AsComponents for GraphNodes { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - archetype_field_name: Some(("positions").into()), - component_name: ("rerun.components.Position2D").into(), - }), + descriptor_override: Some(Self::descriptor_positions()), }), (self .colors @@ -331,11 +335,7 @@ impl ::re_types_core::AsComponents for GraphNodes { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - archetype_field_name: Some(("colors").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_colors()), }), (self .labels @@ -343,11 +343,7 @@ impl ::re_types_core::AsComponents for GraphNodes { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - archetype_field_name: Some(("labels").into()), - component_name: ("rerun.components.Text").into(), - }), + descriptor_override: Some(Self::descriptor_labels()), }), (self .show_labels @@ -355,11 +351,7 @@ impl ::re_types_core::AsComponents for GraphNodes { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - archetype_field_name: Some(("show_labels").into()), - component_name: ("rerun.components.ShowLabels").into(), - }), + descriptor_override: Some(Self::descriptor_show_labels()), }), (self .radii @@ -367,11 +359,7 @@ impl ::re_types_core::AsComponents for GraphNodes { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.GraphNodes".into()), - archetype_field_name: Some(("radii").into()), - component_name: ("rerun.components.Radius").into(), - }), + descriptor_override: Some(Self::descriptor_radii()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/image.rs b/crates/store/re_types/src/archetypes/image.rs index 8995771ba366..25d6705fcbca 100644 --- a/crates/store/re_types/src/archetypes/image.rs +++ b/crates/store/re_types/src/archetypes/image.rs @@ -145,75 +145,75 @@ pub struct Image { pub draw_order: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = - once_cell::sync::Lazy::new(|| { - [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Image".into()), - component_name: "rerun.components.ImageBuffer".into(), - archetype_field_name: Some("buffer".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Image".into()), - component_name: "rerun.components.ImageFormat".into(), - archetype_field_name: Some("format".into()), - }, - ] - }); +impl Image { + /// Returns the [`ComponentDescriptor`] for [`Self::buffer`]. + #[inline] + pub fn descriptor_buffer() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Image".into()), + component_name: "rerun.components.ImageBuffer".into(), + archetype_field_name: Some("buffer".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::format`]. + #[inline] + pub fn descriptor_format() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Image".into()), + component_name: "rerun.components.ImageFormat".into(), + archetype_field_name: Some("format".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::opacity`]. + #[inline] + pub fn descriptor_opacity() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Image".into()), + component_name: "rerun.components.Opacity".into(), + archetype_field_name: Some("opacity".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::draw_order`]. + #[inline] + pub fn descriptor_draw_order() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Image".into()), + component_name: "rerun.components.DrawOrder".into(), + archetype_field_name: Some("draw_order".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Image".into()), component_name: "rerun.components.ImageIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = + once_cell::sync::Lazy::new(|| [Image::descriptor_buffer(), Image::descriptor_format()]); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Image::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = - once_cell::sync::Lazy::new(|| { - [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Image".into()), - component_name: "rerun.components.Opacity".into(), - archetype_field_name: Some("opacity".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Image".into()), - component_name: "rerun.components.DrawOrder".into(), - archetype_field_name: Some("draw_order".into()), - }, - ] - }); + once_cell::sync::Lazy::new(|| [Image::descriptor_opacity(), Image::descriptor_draw_order()]); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Image".into()), - component_name: "rerun.components.ImageBuffer".into(), - archetype_field_name: Some("buffer".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Image".into()), - component_name: "rerun.components.ImageFormat".into(), - archetype_field_name: Some("format".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Image".into()), - component_name: "rerun.components.ImageIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Image".into()), - component_name: "rerun.components.Opacity".into(), - archetype_field_name: Some("opacity".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Image".into()), - component_name: "rerun.components.DrawOrder".into(), - archetype_field_name: Some("draw_order".into()), - }, + Image::descriptor_buffer(), + Image::descriptor_format(), + Image::descriptor_indicator(), + Image::descriptor_opacity(), + Image::descriptor_draw_order(), ] }); @@ -336,21 +336,13 @@ impl ::re_types_core::AsComponents for Image { (Some(&self.buffer as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Image".into()), - archetype_field_name: Some(("buffer").into()), - component_name: ("rerun.components.ImageBuffer").into(), - }), + descriptor_override: Some(Self::descriptor_buffer()), } }), (Some(&self.format as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Image".into()), - archetype_field_name: Some(("format").into()), - component_name: ("rerun.components.ImageFormat").into(), - }), + descriptor_override: Some(Self::descriptor_format()), } }), (self @@ -359,11 +351,7 @@ impl ::re_types_core::AsComponents for Image { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Image".into()), - archetype_field_name: Some(("opacity").into()), - component_name: ("rerun.components.Opacity").into(), - }), + descriptor_override: Some(Self::descriptor_opacity()), }), (self .draw_order @@ -371,11 +359,7 @@ impl ::re_types_core::AsComponents for Image { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Image".into()), - archetype_field_name: Some(("draw_order").into()), - component_name: ("rerun.components.DrawOrder").into(), - }), + descriptor_override: Some(Self::descriptor_draw_order()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/instance_poses3d.rs b/crates/store/re_types/src/archetypes/instance_poses3d.rs index 7442878ae3c3..b4bcf815c838 100644 --- a/crates/store/re_types/src/archetypes/instance_poses3d.rs +++ b/crates/store/re_types/src/archetypes/instance_poses3d.rs @@ -108,82 +108,94 @@ pub struct InstancePoses3D { pub mat3x3: Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl InstancePoses3D { + /// Returns the [`ComponentDescriptor`] for [`Self::translations`]. + #[inline] + pub fn descriptor_translations() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), + component_name: "rerun.components.PoseTranslation3D".into(), + archetype_field_name: Some("translations".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::rotation_axis_angles`]. + #[inline] + pub fn descriptor_rotation_axis_angles() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), + component_name: "rerun.components.PoseRotationAxisAngle".into(), + archetype_field_name: Some("rotation_axis_angles".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::quaternions`]. + #[inline] + pub fn descriptor_quaternions() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), + component_name: "rerun.components.PoseRotationQuat".into(), + archetype_field_name: Some("quaternions".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::scales`]. + #[inline] + pub fn descriptor_scales() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), + component_name: "rerun.components.PoseScale3D".into(), + archetype_field_name: Some("scales".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::mat3x3`]. + #[inline] + pub fn descriptor_mat3x3() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), + component_name: "rerun.components.PoseTransformMat3x3".into(), + archetype_field_name: Some("mat3x3".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), component_name: "rerun.components.InstancePoses3DIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [InstancePoses3D::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), - component_name: "rerun.components.PoseTranslation3D".into(), - archetype_field_name: Some("translations".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), - component_name: "rerun.components.PoseRotationAxisAngle".into(), - archetype_field_name: Some("rotation_axis_angles".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), - component_name: "rerun.components.PoseRotationQuat".into(), - archetype_field_name: Some("quaternions".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), - component_name: "rerun.components.PoseScale3D".into(), - archetype_field_name: Some("scales".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), - component_name: "rerun.components.PoseTransformMat3x3".into(), - archetype_field_name: Some("mat3x3".into()), - }, + InstancePoses3D::descriptor_translations(), + InstancePoses3D::descriptor_rotation_axis_angles(), + InstancePoses3D::descriptor_quaternions(), + InstancePoses3D::descriptor_scales(), + InstancePoses3D::descriptor_mat3x3(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 6usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), - component_name: "rerun.components.InstancePoses3DIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), - component_name: "rerun.components.PoseTranslation3D".into(), - archetype_field_name: Some("translations".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), - component_name: "rerun.components.PoseRotationAxisAngle".into(), - archetype_field_name: Some("rotation_axis_angles".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), - component_name: "rerun.components.PoseRotationQuat".into(), - archetype_field_name: Some("quaternions".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), - component_name: "rerun.components.PoseScale3D".into(), - archetype_field_name: Some("scales".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), - component_name: "rerun.components.PoseTransformMat3x3".into(), - archetype_field_name: Some("mat3x3".into()), - }, + InstancePoses3D::descriptor_indicator(), + InstancePoses3D::descriptor_translations(), + InstancePoses3D::descriptor_rotation_axis_angles(), + InstancePoses3D::descriptor_quaternions(), + InstancePoses3D::descriptor_scales(), + InstancePoses3D::descriptor_mat3x3(), ] }); @@ -330,11 +342,7 @@ impl ::re_types_core::AsComponents for InstancePoses3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), - archetype_field_name: Some(("translations").into()), - component_name: ("rerun.components.PoseTranslation3D").into(), - }), + descriptor_override: Some(Self::descriptor_translations()), }), (self .rotation_axis_angles @@ -342,11 +350,7 @@ impl ::re_types_core::AsComponents for InstancePoses3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), - archetype_field_name: Some(("rotation_axis_angles").into()), - component_name: ("rerun.components.PoseRotationAxisAngle").into(), - }), + descriptor_override: Some(Self::descriptor_rotation_axis_angles()), }), (self .quaternions @@ -354,11 +358,7 @@ impl ::re_types_core::AsComponents for InstancePoses3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), - archetype_field_name: Some(("quaternions").into()), - component_name: ("rerun.components.PoseRotationQuat").into(), - }), + descriptor_override: Some(Self::descriptor_quaternions()), }), (self .scales @@ -366,11 +366,7 @@ impl ::re_types_core::AsComponents for InstancePoses3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), - archetype_field_name: Some(("scales").into()), - component_name: ("rerun.components.PoseScale3D").into(), - }), + descriptor_override: Some(Self::descriptor_scales()), }), (self .mat3x3 @@ -378,11 +374,7 @@ impl ::re_types_core::AsComponents for InstancePoses3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.InstancePoses3D".into()), - archetype_field_name: Some(("mat3x3").into()), - component_name: ("rerun.components.PoseTransformMat3x3").into(), - }), + descriptor_override: Some(Self::descriptor_mat3x3()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/line_strips2d.rs b/crates/store/re_types/src/archetypes/line_strips2d.rs index 624d249f6303..f59c7b2fe77b 100644 --- a/crates/store/re_types/src/archetypes/line_strips2d.rs +++ b/crates/store/re_types/src/archetypes/line_strips2d.rs @@ -116,105 +116,121 @@ pub struct LineStrips2D { pub class_ids: Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl LineStrips2D { + /// Returns the [`ComponentDescriptor`] for [`Self::strips`]. + #[inline] + pub fn descriptor_strips() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.LineStrips2D".into()), component_name: "rerun.components.LineStrip2D".into(), archetype_field_name: Some("strips".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::radii`]. + #[inline] + pub fn descriptor_radii() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.LineStrips2D".into()), + component_name: "rerun.components.Radius".into(), + archetype_field_name: Some("radii".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::colors`]. + #[inline] + pub fn descriptor_colors() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.LineStrips2D".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("colors".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::labels`]. + #[inline] + pub fn descriptor_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.LineStrips2D".into()), + component_name: "rerun.components.Text".into(), + archetype_field_name: Some("labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::show_labels`]. + #[inline] + pub fn descriptor_show_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.LineStrips2D".into()), + component_name: "rerun.components.ShowLabels".into(), + archetype_field_name: Some("show_labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::draw_order`]. + #[inline] + pub fn descriptor_draw_order() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.LineStrips2D".into()), + component_name: "rerun.components.DrawOrder".into(), + archetype_field_name: Some("draw_order".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::class_ids`]. + #[inline] + pub fn descriptor_class_ids() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.LineStrips2D".into()), + component_name: "rerun.components.ClassId".into(), + archetype_field_name: Some("class_ids".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.LineStrips2D".into()), + component_name: "rerun.components.LineStrips2DIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [LineStrips2D::descriptor_strips()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - component_name: "rerun.components.LineStrips2DIndicator".into(), - archetype_field_name: None, - }, + LineStrips2D::descriptor_radii(), + LineStrips2D::descriptor_colors(), + LineStrips2D::descriptor_indicator(), ] }); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 4usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - component_name: "rerun.components.DrawOrder".into(), - archetype_field_name: Some("draw_order".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + LineStrips2D::descriptor_labels(), + LineStrips2D::descriptor_show_labels(), + LineStrips2D::descriptor_draw_order(), + LineStrips2D::descriptor_class_ids(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 8usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - component_name: "rerun.components.LineStrip2D".into(), - archetype_field_name: Some("strips".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - component_name: "rerun.components.LineStrips2DIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - component_name: "rerun.components.DrawOrder".into(), - archetype_field_name: Some("draw_order".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + LineStrips2D::descriptor_strips(), + LineStrips2D::descriptor_radii(), + LineStrips2D::descriptor_colors(), + LineStrips2D::descriptor_indicator(), + LineStrips2D::descriptor_labels(), + LineStrips2D::descriptor_show_labels(), + LineStrips2D::descriptor_draw_order(), + LineStrips2D::descriptor_class_ids(), ] }); @@ -374,11 +390,7 @@ impl ::re_types_core::AsComponents for LineStrips2D { (Some(&self.strips as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - archetype_field_name: Some(("strips").into()), - component_name: ("rerun.components.LineStrip2D").into(), - }), + descriptor_override: Some(Self::descriptor_strips()), } }), (self @@ -387,11 +399,7 @@ impl ::re_types_core::AsComponents for LineStrips2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - archetype_field_name: Some(("radii").into()), - component_name: ("rerun.components.Radius").into(), - }), + descriptor_override: Some(Self::descriptor_radii()), }), (self .colors @@ -399,11 +407,7 @@ impl ::re_types_core::AsComponents for LineStrips2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - archetype_field_name: Some(("colors").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_colors()), }), (self .labels @@ -411,11 +415,7 @@ impl ::re_types_core::AsComponents for LineStrips2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - archetype_field_name: Some(("labels").into()), - component_name: ("rerun.components.Text").into(), - }), + descriptor_override: Some(Self::descriptor_labels()), }), (self .show_labels @@ -423,11 +423,7 @@ impl ::re_types_core::AsComponents for LineStrips2D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - archetype_field_name: Some(("show_labels").into()), - component_name: ("rerun.components.ShowLabels").into(), - }), + descriptor_override: Some(Self::descriptor_show_labels()), }), (self .draw_order @@ -435,11 +431,7 @@ impl ::re_types_core::AsComponents for LineStrips2D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - archetype_field_name: Some(("draw_order").into()), - component_name: ("rerun.components.DrawOrder").into(), - }), + descriptor_override: Some(Self::descriptor_draw_order()), }), (self .class_ids @@ -447,11 +439,7 @@ impl ::re_types_core::AsComponents for LineStrips2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips2D".into()), - archetype_field_name: Some(("class_ids").into()), - component_name: ("rerun.components.ClassId").into(), - }), + descriptor_override: Some(Self::descriptor_class_ids()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/line_strips3d.rs b/crates/store/re_types/src/archetypes/line_strips3d.rs index 980b3b4e05d0..c9d3c89ed9b9 100644 --- a/crates/store/re_types/src/archetypes/line_strips3d.rs +++ b/crates/store/re_types/src/archetypes/line_strips3d.rs @@ -124,95 +124,109 @@ pub struct LineStrips3D { pub class_ids: Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl LineStrips3D { + /// Returns the [`ComponentDescriptor`] for [`Self::strips`]. + #[inline] + pub fn descriptor_strips() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.LineStrips3D".into()), component_name: "rerun.components.LineStrip3D".into(), archetype_field_name: Some("strips".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::radii`]. + #[inline] + pub fn descriptor_radii() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.LineStrips3D".into()), + component_name: "rerun.components.Radius".into(), + archetype_field_name: Some("radii".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::colors`]. + #[inline] + pub fn descriptor_colors() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.LineStrips3D".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("colors".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::labels`]. + #[inline] + pub fn descriptor_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.LineStrips3D".into()), + component_name: "rerun.components.Text".into(), + archetype_field_name: Some("labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::show_labels`]. + #[inline] + pub fn descriptor_show_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.LineStrips3D".into()), + component_name: "rerun.components.ShowLabels".into(), + archetype_field_name: Some("show_labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::class_ids`]. + #[inline] + pub fn descriptor_class_ids() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.LineStrips3D".into()), + component_name: "rerun.components.ClassId".into(), + archetype_field_name: Some("class_ids".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.LineStrips3D".into()), + component_name: "rerun.components.LineStrips3DIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [LineStrips3D::descriptor_strips()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - component_name: "rerun.components.LineStrips3DIndicator".into(), - archetype_field_name: None, - }, + LineStrips3D::descriptor_radii(), + LineStrips3D::descriptor_colors(), + LineStrips3D::descriptor_indicator(), ] }); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + LineStrips3D::descriptor_labels(), + LineStrips3D::descriptor_show_labels(), + LineStrips3D::descriptor_class_ids(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 7usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - component_name: "rerun.components.LineStrip3D".into(), - archetype_field_name: Some("strips".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - component_name: "rerun.components.LineStrips3DIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + LineStrips3D::descriptor_strips(), + LineStrips3D::descriptor_radii(), + LineStrips3D::descriptor_colors(), + LineStrips3D::descriptor_indicator(), + LineStrips3D::descriptor_labels(), + LineStrips3D::descriptor_show_labels(), + LineStrips3D::descriptor_class_ids(), ] }); @@ -362,11 +376,7 @@ impl ::re_types_core::AsComponents for LineStrips3D { (Some(&self.strips as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - archetype_field_name: Some(("strips").into()), - component_name: ("rerun.components.LineStrip3D").into(), - }), + descriptor_override: Some(Self::descriptor_strips()), } }), (self @@ -375,11 +385,7 @@ impl ::re_types_core::AsComponents for LineStrips3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - archetype_field_name: Some(("radii").into()), - component_name: ("rerun.components.Radius").into(), - }), + descriptor_override: Some(Self::descriptor_radii()), }), (self .colors @@ -387,11 +393,7 @@ impl ::re_types_core::AsComponents for LineStrips3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - archetype_field_name: Some(("colors").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_colors()), }), (self .labels @@ -399,11 +401,7 @@ impl ::re_types_core::AsComponents for LineStrips3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - archetype_field_name: Some(("labels").into()), - component_name: ("rerun.components.Text").into(), - }), + descriptor_override: Some(Self::descriptor_labels()), }), (self .show_labels @@ -411,11 +409,7 @@ impl ::re_types_core::AsComponents for LineStrips3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - archetype_field_name: Some(("show_labels").into()), - component_name: ("rerun.components.ShowLabels").into(), - }), + descriptor_override: Some(Self::descriptor_show_labels()), }), (self .class_ids @@ -423,11 +417,7 @@ impl ::re_types_core::AsComponents for LineStrips3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.LineStrips3D".into()), - archetype_field_name: Some(("class_ids").into()), - component_name: ("rerun.components.ClassId").into(), - }), + descriptor_override: Some(Self::descriptor_class_ids()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/mesh3d.rs b/crates/store/re_types/src/archetypes/mesh3d.rs index 7d0841510ab6..5093db01c82e 100644 --- a/crates/store/re_types/src/archetypes/mesh3d.rs +++ b/crates/store/re_types/src/archetypes/mesh3d.rs @@ -145,125 +145,145 @@ pub struct Mesh3D { pub class_ids: Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl Mesh3D { + /// Returns the [`ComponentDescriptor`] for [`Self::vertex_positions`]. + #[inline] + pub fn descriptor_vertex_positions() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Mesh3D".into()), component_name: "rerun.components.Position3D".into(), archetype_field_name: Some("vertex_positions".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::triangle_indices`]. + #[inline] + pub fn descriptor_triangle_indices() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Mesh3D".into()), + component_name: "rerun.components.TriangleIndices".into(), + archetype_field_name: Some("triangle_indices".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::vertex_normals`]. + #[inline] + pub fn descriptor_vertex_normals() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Mesh3D".into()), + component_name: "rerun.components.Vector3D".into(), + archetype_field_name: Some("vertex_normals".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::vertex_colors`]. + #[inline] + pub fn descriptor_vertex_colors() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Mesh3D".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("vertex_colors".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::vertex_texcoords`]. + #[inline] + pub fn descriptor_vertex_texcoords() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Mesh3D".into()), + component_name: "rerun.components.Texcoord2D".into(), + archetype_field_name: Some("vertex_texcoords".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::albedo_factor`]. + #[inline] + pub fn descriptor_albedo_factor() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Mesh3D".into()), + component_name: "rerun.components.AlbedoFactor".into(), + archetype_field_name: Some("albedo_factor".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::albedo_texture_buffer`]. + #[inline] + pub fn descriptor_albedo_texture_buffer() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Mesh3D".into()), + component_name: "rerun.components.ImageBuffer".into(), + archetype_field_name: Some("albedo_texture_buffer".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::albedo_texture_format`]. + #[inline] + pub fn descriptor_albedo_texture_format() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Mesh3D".into()), + component_name: "rerun.components.ImageFormat".into(), + archetype_field_name: Some("albedo_texture_format".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::class_ids`]. + #[inline] + pub fn descriptor_class_ids() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Mesh3D".into()), + component_name: "rerun.components.ClassId".into(), + archetype_field_name: Some("class_ids".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Mesh3D".into()), + component_name: "rerun.components.Mesh3DIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Mesh3D::descriptor_vertex_positions()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.TriangleIndices".into(), - archetype_field_name: Some("triangle_indices".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.Vector3D".into(), - archetype_field_name: Some("vertex_normals".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.Mesh3DIndicator".into(), - archetype_field_name: None, - }, + Mesh3D::descriptor_triangle_indices(), + Mesh3D::descriptor_vertex_normals(), + Mesh3D::descriptor_indicator(), ] }); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 6usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("vertex_colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.Texcoord2D".into(), - archetype_field_name: Some("vertex_texcoords".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.AlbedoFactor".into(), - archetype_field_name: Some("albedo_factor".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.ImageBuffer".into(), - archetype_field_name: Some("albedo_texture_buffer".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.ImageFormat".into(), - archetype_field_name: Some("albedo_texture_format".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + Mesh3D::descriptor_vertex_colors(), + Mesh3D::descriptor_vertex_texcoords(), + Mesh3D::descriptor_albedo_factor(), + Mesh3D::descriptor_albedo_texture_buffer(), + Mesh3D::descriptor_albedo_texture_format(), + Mesh3D::descriptor_class_ids(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 10usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.Position3D".into(), - archetype_field_name: Some("vertex_positions".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.TriangleIndices".into(), - archetype_field_name: Some("triangle_indices".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.Vector3D".into(), - archetype_field_name: Some("vertex_normals".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.Mesh3DIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("vertex_colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.Texcoord2D".into(), - archetype_field_name: Some("vertex_texcoords".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.AlbedoFactor".into(), - archetype_field_name: Some("albedo_factor".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.ImageBuffer".into(), - archetype_field_name: Some("albedo_texture_buffer".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.ImageFormat".into(), - archetype_field_name: Some("albedo_texture_format".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, + Mesh3D::descriptor_vertex_positions(), + Mesh3D::descriptor_triangle_indices(), + Mesh3D::descriptor_vertex_normals(), + Mesh3D::descriptor_indicator(), + Mesh3D::descriptor_vertex_colors(), + Mesh3D::descriptor_vertex_texcoords(), + Mesh3D::descriptor_albedo_factor(), + Mesh3D::descriptor_albedo_texture_buffer(), + Mesh3D::descriptor_albedo_texture_format(), + Mesh3D::descriptor_class_ids(), ] }); @@ -451,11 +471,7 @@ impl ::re_types_core::AsComponents for Mesh3D { (Some(&self.vertex_positions as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - archetype_field_name: Some(("vertex_positions").into()), - component_name: ("rerun.components.Position3D").into(), - }), + descriptor_override: Some(Self::descriptor_vertex_positions()), } }), (self @@ -464,11 +480,7 @@ impl ::re_types_core::AsComponents for Mesh3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - archetype_field_name: Some(("triangle_indices").into()), - component_name: ("rerun.components.TriangleIndices").into(), - }), + descriptor_override: Some(Self::descriptor_triangle_indices()), }), (self .vertex_normals @@ -476,11 +488,7 @@ impl ::re_types_core::AsComponents for Mesh3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - archetype_field_name: Some(("vertex_normals").into()), - component_name: ("rerun.components.Vector3D").into(), - }), + descriptor_override: Some(Self::descriptor_vertex_normals()), }), (self .vertex_colors @@ -488,11 +496,7 @@ impl ::re_types_core::AsComponents for Mesh3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - archetype_field_name: Some(("vertex_colors").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_vertex_colors()), }), (self .vertex_texcoords @@ -500,11 +504,7 @@ impl ::re_types_core::AsComponents for Mesh3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - archetype_field_name: Some(("vertex_texcoords").into()), - component_name: ("rerun.components.Texcoord2D").into(), - }), + descriptor_override: Some(Self::descriptor_vertex_texcoords()), }), (self .albedo_factor @@ -512,11 +512,7 @@ impl ::re_types_core::AsComponents for Mesh3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - archetype_field_name: Some(("albedo_factor").into()), - component_name: ("rerun.components.AlbedoFactor").into(), - }), + descriptor_override: Some(Self::descriptor_albedo_factor()), }), (self .albedo_texture_buffer @@ -524,11 +520,7 @@ impl ::re_types_core::AsComponents for Mesh3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - archetype_field_name: Some(("albedo_texture_buffer").into()), - component_name: ("rerun.components.ImageBuffer").into(), - }), + descriptor_override: Some(Self::descriptor_albedo_texture_buffer()), }), (self .albedo_texture_format @@ -536,11 +528,7 @@ impl ::re_types_core::AsComponents for Mesh3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - archetype_field_name: Some(("albedo_texture_format").into()), - component_name: ("rerun.components.ImageFormat").into(), - }), + descriptor_override: Some(Self::descriptor_albedo_texture_format()), }), (self .class_ids @@ -548,11 +536,7 @@ impl ::re_types_core::AsComponents for Mesh3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Mesh3D".into()), - archetype_field_name: Some(("class_ids").into()), - component_name: ("rerun.components.ClassId").into(), - }), + descriptor_override: Some(Self::descriptor_class_ids()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/pinhole.rs b/crates/store/re_types/src/archetypes/pinhole.rs index 8a39cf1e9814..75524c97e438 100644 --- a/crates/store/re_types/src/archetypes/pinhole.rs +++ b/crates/store/re_types/src/archetypes/pinhole.rs @@ -136,75 +136,85 @@ pub struct Pinhole { pub image_plane_distance: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl Pinhole { + /// Returns the [`ComponentDescriptor`] for [`Self::image_from_camera`]. + #[inline] + pub fn descriptor_image_from_camera() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Pinhole".into()), component_name: "rerun.components.PinholeProjection".into(), archetype_field_name: Some("image_from_camera".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::resolution`]. + #[inline] + pub fn descriptor_resolution() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Pinhole".into()), + component_name: "rerun.components.Resolution".into(), + archetype_field_name: Some("resolution".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::camera_xyz`]. + #[inline] + pub fn descriptor_camera_xyz() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Pinhole".into()), + component_name: "rerun.components.ViewCoordinates".into(), + archetype_field_name: Some("camera_xyz".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::image_plane_distance`]. + #[inline] + pub fn descriptor_image_plane_distance() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Pinhole".into()), + component_name: "rerun.components.ImagePlaneDistance".into(), + archetype_field_name: Some("image_plane_distance".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Pinhole".into()), + component_name: "rerun.components.PinholeIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Pinhole::descriptor_image_from_camera()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Pinhole".into()), - component_name: "rerun.components.Resolution".into(), - archetype_field_name: Some("resolution".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Pinhole".into()), - component_name: "rerun.components.PinholeIndicator".into(), - archetype_field_name: None, - }, + Pinhole::descriptor_resolution(), + Pinhole::descriptor_indicator(), ] }); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Pinhole".into()), - component_name: "rerun.components.ViewCoordinates".into(), - archetype_field_name: Some("camera_xyz".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Pinhole".into()), - component_name: "rerun.components.ImagePlaneDistance".into(), - archetype_field_name: Some("image_plane_distance".into()), - }, + Pinhole::descriptor_camera_xyz(), + Pinhole::descriptor_image_plane_distance(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Pinhole".into()), - component_name: "rerun.components.PinholeProjection".into(), - archetype_field_name: Some("image_from_camera".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Pinhole".into()), - component_name: "rerun.components.Resolution".into(), - archetype_field_name: Some("resolution".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Pinhole".into()), - component_name: "rerun.components.PinholeIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Pinhole".into()), - component_name: "rerun.components.ViewCoordinates".into(), - archetype_field_name: Some("camera_xyz".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Pinhole".into()), - component_name: "rerun.components.ImagePlaneDistance".into(), - archetype_field_name: Some("image_plane_distance".into()), - }, + Pinhole::descriptor_image_from_camera(), + Pinhole::descriptor_resolution(), + Pinhole::descriptor_indicator(), + Pinhole::descriptor_camera_xyz(), + Pinhole::descriptor_image_plane_distance(), ] }); @@ -325,11 +335,7 @@ impl ::re_types_core::AsComponents for Pinhole { (Some(&self.image_from_camera as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Pinhole".into()), - archetype_field_name: Some(("image_from_camera").into()), - component_name: ("rerun.components.PinholeProjection").into(), - }), + descriptor_override: Some(Self::descriptor_image_from_camera()), } }), (self @@ -338,11 +344,7 @@ impl ::re_types_core::AsComponents for Pinhole { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Pinhole".into()), - archetype_field_name: Some(("resolution").into()), - component_name: ("rerun.components.Resolution").into(), - }), + descriptor_override: Some(Self::descriptor_resolution()), }), (self .camera_xyz @@ -350,11 +352,7 @@ impl ::re_types_core::AsComponents for Pinhole { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Pinhole".into()), - archetype_field_name: Some(("camera_xyz").into()), - component_name: ("rerun.components.ViewCoordinates").into(), - }), + descriptor_override: Some(Self::descriptor_camera_xyz()), }), (self .image_plane_distance @@ -362,11 +360,7 @@ impl ::re_types_core::AsComponents for Pinhole { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Pinhole".into()), - archetype_field_name: Some(("image_plane_distance").into()), - component_name: ("rerun.components.ImagePlaneDistance").into(), - }), + descriptor_override: Some(Self::descriptor_image_plane_distance()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/points2d.rs b/crates/store/re_types/src/archetypes/points2d.rs index 868fb2c4811d..dbadf1148a63 100644 --- a/crates/store/re_types/src/archetypes/points2d.rs +++ b/crates/store/re_types/src/archetypes/points2d.rs @@ -137,115 +137,133 @@ pub struct Points2D { pub keypoint_ids: Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl Points2D { + /// Returns the [`ComponentDescriptor`] for [`Self::positions`]. + #[inline] + pub fn descriptor_positions() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Points2D".into()), component_name: "rerun.components.Position2D".into(), archetype_field_name: Some("positions".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::radii`]. + #[inline] + pub fn descriptor_radii() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Points2D".into()), + component_name: "rerun.components.Radius".into(), + archetype_field_name: Some("radii".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::colors`]. + #[inline] + pub fn descriptor_colors() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Points2D".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("colors".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::labels`]. + #[inline] + pub fn descriptor_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Points2D".into()), + component_name: "rerun.components.Text".into(), + archetype_field_name: Some("labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::show_labels`]. + #[inline] + pub fn descriptor_show_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Points2D".into()), + component_name: "rerun.components.ShowLabels".into(), + archetype_field_name: Some("show_labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::draw_order`]. + #[inline] + pub fn descriptor_draw_order() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Points2D".into()), + component_name: "rerun.components.DrawOrder".into(), + archetype_field_name: Some("draw_order".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::class_ids`]. + #[inline] + pub fn descriptor_class_ids() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Points2D".into()), + component_name: "rerun.components.ClassId".into(), + archetype_field_name: Some("class_ids".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::keypoint_ids`]. + #[inline] + pub fn descriptor_keypoint_ids() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Points2D".into()), + component_name: "rerun.components.KeypointId".into(), + archetype_field_name: Some("keypoint_ids".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Points2D".into()), + component_name: "rerun.components.Points2DIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Points2D::descriptor_positions()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.Points2DIndicator".into(), - archetype_field_name: None, - }, + Points2D::descriptor_radii(), + Points2D::descriptor_colors(), + Points2D::descriptor_indicator(), ] }); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.DrawOrder".into(), - archetype_field_name: Some("draw_order".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.KeypointId".into(), - archetype_field_name: Some("keypoint_ids".into()), - }, + Points2D::descriptor_labels(), + Points2D::descriptor_show_labels(), + Points2D::descriptor_draw_order(), + Points2D::descriptor_class_ids(), + Points2D::descriptor_keypoint_ids(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 9usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.Position2D".into(), - archetype_field_name: Some("positions".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.Points2DIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.DrawOrder".into(), - archetype_field_name: Some("draw_order".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - component_name: "rerun.components.KeypointId".into(), - archetype_field_name: Some("keypoint_ids".into()), - }, + Points2D::descriptor_positions(), + Points2D::descriptor_radii(), + Points2D::descriptor_colors(), + Points2D::descriptor_indicator(), + Points2D::descriptor_labels(), + Points2D::descriptor_show_labels(), + Points2D::descriptor_draw_order(), + Points2D::descriptor_class_ids(), + Points2D::descriptor_keypoint_ids(), ] }); @@ -418,11 +436,7 @@ impl ::re_types_core::AsComponents for Points2D { (Some(&self.positions as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - archetype_field_name: Some(("positions").into()), - component_name: ("rerun.components.Position2D").into(), - }), + descriptor_override: Some(Self::descriptor_positions()), } }), (self @@ -431,11 +445,7 @@ impl ::re_types_core::AsComponents for Points2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - archetype_field_name: Some(("radii").into()), - component_name: ("rerun.components.Radius").into(), - }), + descriptor_override: Some(Self::descriptor_radii()), }), (self .colors @@ -443,11 +453,7 @@ impl ::re_types_core::AsComponents for Points2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - archetype_field_name: Some(("colors").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_colors()), }), (self .labels @@ -455,11 +461,7 @@ impl ::re_types_core::AsComponents for Points2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - archetype_field_name: Some(("labels").into()), - component_name: ("rerun.components.Text").into(), - }), + descriptor_override: Some(Self::descriptor_labels()), }), (self .show_labels @@ -467,11 +469,7 @@ impl ::re_types_core::AsComponents for Points2D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - archetype_field_name: Some(("show_labels").into()), - component_name: ("rerun.components.ShowLabels").into(), - }), + descriptor_override: Some(Self::descriptor_show_labels()), }), (self .draw_order @@ -479,11 +477,7 @@ impl ::re_types_core::AsComponents for Points2D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - archetype_field_name: Some(("draw_order").into()), - component_name: ("rerun.components.DrawOrder").into(), - }), + descriptor_override: Some(Self::descriptor_draw_order()), }), (self .class_ids @@ -491,11 +485,7 @@ impl ::re_types_core::AsComponents for Points2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - archetype_field_name: Some(("class_ids").into()), - component_name: ("rerun.components.ClassId").into(), - }), + descriptor_override: Some(Self::descriptor_class_ids()), }), (self .keypoint_ids @@ -503,11 +493,7 @@ impl ::re_types_core::AsComponents for Points2D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points2D".into()), - archetype_field_name: Some(("keypoint_ids").into()), - component_name: ("rerun.components.KeypointId").into(), - }), + descriptor_override: Some(Self::descriptor_keypoint_ids()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/points3d.rs b/crates/store/re_types/src/archetypes/points3d.rs index e09385eb9d62..4e51d42badb5 100644 --- a/crates/store/re_types/src/archetypes/points3d.rs +++ b/crates/store/re_types/src/archetypes/points3d.rs @@ -130,105 +130,121 @@ pub struct Points3D { pub keypoint_ids: Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl Points3D { + /// Returns the [`ComponentDescriptor`] for [`Self::positions`]. + #[inline] + pub fn descriptor_positions() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Points3D".into()), component_name: "rerun.components.Position3D".into(), archetype_field_name: Some("positions".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::radii`]. + #[inline] + pub fn descriptor_radii() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Points3D".into()), + component_name: "rerun.components.Radius".into(), + archetype_field_name: Some("radii".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::colors`]. + #[inline] + pub fn descriptor_colors() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Points3D".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("colors".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::labels`]. + #[inline] + pub fn descriptor_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Points3D".into()), + component_name: "rerun.components.Text".into(), + archetype_field_name: Some("labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::show_labels`]. + #[inline] + pub fn descriptor_show_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Points3D".into()), + component_name: "rerun.components.ShowLabels".into(), + archetype_field_name: Some("show_labels".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::class_ids`]. + #[inline] + pub fn descriptor_class_ids() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Points3D".into()), + component_name: "rerun.components.ClassId".into(), + archetype_field_name: Some("class_ids".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::keypoint_ids`]. + #[inline] + pub fn descriptor_keypoint_ids() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Points3D".into()), + component_name: "rerun.components.KeypointId".into(), + archetype_field_name: Some("keypoint_ids".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Points3D".into()), + component_name: "rerun.components.Points3DIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Points3D::descriptor_positions()]); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - component_name: "rerun.components.Points3DIndicator".into(), - archetype_field_name: None, - }, + Points3D::descriptor_radii(), + Points3D::descriptor_colors(), + Points3D::descriptor_indicator(), ] }); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 4usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - component_name: "rerun.components.KeypointId".into(), - archetype_field_name: Some("keypoint_ids".into()), - }, + Points3D::descriptor_labels(), + Points3D::descriptor_show_labels(), + Points3D::descriptor_class_ids(), + Points3D::descriptor_keypoint_ids(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 8usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - component_name: "rerun.components.Position3D".into(), - archetype_field_name: Some("positions".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - component_name: "rerun.components.Radius".into(), - archetype_field_name: Some("radii".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("colors".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - component_name: "rerun.components.Points3DIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - component_name: "rerun.components.ShowLabels".into(), - archetype_field_name: Some("show_labels".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - component_name: "rerun.components.ClassId".into(), - archetype_field_name: Some("class_ids".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - component_name: "rerun.components.KeypointId".into(), - archetype_field_name: Some("keypoint_ids".into()), - }, + Points3D::descriptor_positions(), + Points3D::descriptor_radii(), + Points3D::descriptor_colors(), + Points3D::descriptor_indicator(), + Points3D::descriptor_labels(), + Points3D::descriptor_show_labels(), + Points3D::descriptor_class_ids(), + Points3D::descriptor_keypoint_ids(), ] }); @@ -391,11 +407,7 @@ impl ::re_types_core::AsComponents for Points3D { (Some(&self.positions as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - archetype_field_name: Some(("positions").into()), - component_name: ("rerun.components.Position3D").into(), - }), + descriptor_override: Some(Self::descriptor_positions()), } }), (self @@ -404,11 +416,7 @@ impl ::re_types_core::AsComponents for Points3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - archetype_field_name: Some(("radii").into()), - component_name: ("rerun.components.Radius").into(), - }), + descriptor_override: Some(Self::descriptor_radii()), }), (self .colors @@ -416,11 +424,7 @@ impl ::re_types_core::AsComponents for Points3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - archetype_field_name: Some(("colors").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_colors()), }), (self .labels @@ -428,11 +432,7 @@ impl ::re_types_core::AsComponents for Points3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - archetype_field_name: Some(("labels").into()), - component_name: ("rerun.components.Text").into(), - }), + descriptor_override: Some(Self::descriptor_labels()), }), (self .show_labels @@ -440,11 +440,7 @@ impl ::re_types_core::AsComponents for Points3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - archetype_field_name: Some(("show_labels").into()), - component_name: ("rerun.components.ShowLabels").into(), - }), + descriptor_override: Some(Self::descriptor_show_labels()), }), (self .class_ids @@ -452,11 +448,7 @@ impl ::re_types_core::AsComponents for Points3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - archetype_field_name: Some(("class_ids").into()), - component_name: ("rerun.components.ClassId").into(), - }), + descriptor_override: Some(Self::descriptor_class_ids()), }), (self .keypoint_ids @@ -464,11 +456,7 @@ impl ::re_types_core::AsComponents for Points3D { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Points3D".into()), - archetype_field_name: Some(("keypoint_ids").into()), - component_name: ("rerun.components.KeypointId").into(), - }), + descriptor_override: Some(Self::descriptor_keypoint_ids()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/scalar.rs b/crates/store/re_types/src/archetypes/scalar.rs index 51272a55878c..24f92629f31f 100644 --- a/crates/store/re_types/src/archetypes/scalar.rs +++ b/crates/store/re_types/src/archetypes/scalar.rs @@ -59,42 +59,39 @@ pub struct Scalar { pub scalar: crate::components::Scalar, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl Scalar { + /// Returns the [`ComponentDescriptor`] for [`Self::scalar`]. + #[inline] + pub fn descriptor_scalar() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Scalar".into()), component_name: "rerun.components.Scalar".into(), archetype_field_name: Some("scalar".into()), - }] - }); + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Scalar".into()), component_name: "rerun.components.ScalarIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Scalar::descriptor_scalar()]); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Scalar::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = once_cell::sync::Lazy::new(|| []); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = - once_cell::sync::Lazy::new(|| { - [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Scalar".into()), - component_name: "rerun.components.Scalar".into(), - archetype_field_name: Some("scalar".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Scalar".into()), - component_name: "rerun.components.ScalarIndicator".into(), - archetype_field_name: None, - }, - ] - }); + once_cell::sync::Lazy::new(|| [Scalar::descriptor_scalar(), Scalar::descriptor_indicator()]); impl Scalar { /// The total number of components in the archetype: 1 required, 1 recommended, 0 optional @@ -179,11 +176,7 @@ impl ::re_types_core::AsComponents for Scalar { (Some(&self.scalar as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Scalar".into()), - archetype_field_name: Some(("scalar").into()), - component_name: ("rerun.components.Scalar").into(), - }), + descriptor_override: Some(Self::descriptor_scalar()), } }), ] diff --git a/crates/store/re_types/src/archetypes/segmentation_image.rs b/crates/store/re_types/src/archetypes/segmentation_image.rs index cfb6e61c5db3..f852817c0175 100644 --- a/crates/store/re_types/src/archetypes/segmentation_image.rs +++ b/crates/store/re_types/src/archetypes/segmentation_image.rs @@ -83,75 +83,85 @@ pub struct SegmentationImage { pub draw_order: Option, } +impl SegmentationImage { + /// Returns the [`ComponentDescriptor`] for [`Self::buffer`]. + #[inline] + pub fn descriptor_buffer() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.SegmentationImage".into()), + component_name: "rerun.components.ImageBuffer".into(), + archetype_field_name: Some("buffer".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::format`]. + #[inline] + pub fn descriptor_format() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.SegmentationImage".into()), + component_name: "rerun.components.ImageFormat".into(), + archetype_field_name: Some("format".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::opacity`]. + #[inline] + pub fn descriptor_opacity() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.SegmentationImage".into()), + component_name: "rerun.components.Opacity".into(), + archetype_field_name: Some("opacity".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::draw_order`]. + #[inline] + pub fn descriptor_draw_order() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.SegmentationImage".into()), + component_name: "rerun.components.DrawOrder".into(), + archetype_field_name: Some("draw_order".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.SegmentationImage".into()), + component_name: "rerun.components.SegmentationImageIndicator".into(), + archetype_field_name: None, + } + } +} + static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SegmentationImage".into()), - component_name: "rerun.components.ImageBuffer".into(), - archetype_field_name: Some("buffer".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SegmentationImage".into()), - component_name: "rerun.components.ImageFormat".into(), - archetype_field_name: Some("format".into()), - }, + SegmentationImage::descriptor_buffer(), + SegmentationImage::descriptor_format(), ] }); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SegmentationImage".into()), - component_name: "rerun.components.SegmentationImageIndicator".into(), - archetype_field_name: None, - }] - }); + once_cell::sync::Lazy::new(|| [SegmentationImage::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SegmentationImage".into()), - component_name: "rerun.components.Opacity".into(), - archetype_field_name: Some("opacity".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SegmentationImage".into()), - component_name: "rerun.components.DrawOrder".into(), - archetype_field_name: Some("draw_order".into()), - }, + SegmentationImage::descriptor_opacity(), + SegmentationImage::descriptor_draw_order(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SegmentationImage".into()), - component_name: "rerun.components.ImageBuffer".into(), - archetype_field_name: Some("buffer".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SegmentationImage".into()), - component_name: "rerun.components.ImageFormat".into(), - archetype_field_name: Some("format".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SegmentationImage".into()), - component_name: "rerun.components.SegmentationImageIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SegmentationImage".into()), - component_name: "rerun.components.Opacity".into(), - archetype_field_name: Some("opacity".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SegmentationImage".into()), - component_name: "rerun.components.DrawOrder".into(), - archetype_field_name: Some("draw_order".into()), - }, + SegmentationImage::descriptor_buffer(), + SegmentationImage::descriptor_format(), + SegmentationImage::descriptor_indicator(), + SegmentationImage::descriptor_opacity(), + SegmentationImage::descriptor_draw_order(), ] }); @@ -274,21 +284,13 @@ impl ::re_types_core::AsComponents for SegmentationImage { (Some(&self.buffer as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SegmentationImage".into()), - archetype_field_name: Some(("buffer").into()), - component_name: ("rerun.components.ImageBuffer").into(), - }), + descriptor_override: Some(Self::descriptor_buffer()), } }), (Some(&self.format as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SegmentationImage".into()), - archetype_field_name: Some(("format").into()), - component_name: ("rerun.components.ImageFormat").into(), - }), + descriptor_override: Some(Self::descriptor_format()), } }), (self @@ -297,11 +299,7 @@ impl ::re_types_core::AsComponents for SegmentationImage { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SegmentationImage".into()), - archetype_field_name: Some(("opacity").into()), - component_name: ("rerun.components.Opacity").into(), - }), + descriptor_override: Some(Self::descriptor_opacity()), }), (self .draw_order @@ -309,11 +307,7 @@ impl ::re_types_core::AsComponents for SegmentationImage { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SegmentationImage".into()), - archetype_field_name: Some(("draw_order").into()), - component_name: ("rerun.components.DrawOrder").into(), - }), + descriptor_override: Some(Self::descriptor_draw_order()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/series_line.rs b/crates/store/re_types/src/archetypes/series_line.rs index 6bffe4d30b1b..0f6407314bdb 100644 --- a/crates/store/re_types/src/archetypes/series_line.rs +++ b/crates/store/re_types/src/archetypes/series_line.rs @@ -90,72 +90,82 @@ pub struct SeriesLine { pub aggregation_policy: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl SeriesLine { + /// Returns the [`ComponentDescriptor`] for [`Self::color`]. + #[inline] + pub fn descriptor_color() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.SeriesLine".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("color".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::width`]. + #[inline] + pub fn descriptor_width() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.SeriesLine".into()), + component_name: "rerun.components.StrokeWidth".into(), + archetype_field_name: Some("width".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::name`]. + #[inline] + pub fn descriptor_name() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.SeriesLine".into()), + component_name: "rerun.components.Name".into(), + archetype_field_name: Some("name".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::aggregation_policy`]. + #[inline] + pub fn descriptor_aggregation_policy() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.SeriesLine".into()), + component_name: "rerun.components.AggregationPolicy".into(), + archetype_field_name: Some("aggregation_policy".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.SeriesLine".into()), component_name: "rerun.components.SeriesLineIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [SeriesLine::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 4usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesLine".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("color".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesLine".into()), - component_name: "rerun.components.StrokeWidth".into(), - archetype_field_name: Some("width".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesLine".into()), - component_name: "rerun.components.Name".into(), - archetype_field_name: Some("name".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesLine".into()), - component_name: "rerun.components.AggregationPolicy".into(), - archetype_field_name: Some("aggregation_policy".into()), - }, + SeriesLine::descriptor_color(), + SeriesLine::descriptor_width(), + SeriesLine::descriptor_name(), + SeriesLine::descriptor_aggregation_policy(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesLine".into()), - component_name: "rerun.components.SeriesLineIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesLine".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("color".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesLine".into()), - component_name: "rerun.components.StrokeWidth".into(), - archetype_field_name: Some("width".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesLine".into()), - component_name: "rerun.components.Name".into(), - archetype_field_name: Some("name".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesLine".into()), - component_name: "rerun.components.AggregationPolicy".into(), - archetype_field_name: Some("aggregation_policy".into()), - }, + SeriesLine::descriptor_indicator(), + SeriesLine::descriptor_color(), + SeriesLine::descriptor_width(), + SeriesLine::descriptor_name(), + SeriesLine::descriptor_aggregation_policy(), ] }); @@ -274,11 +284,7 @@ impl ::re_types_core::AsComponents for SeriesLine { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesLine".into()), - archetype_field_name: Some(("color").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_color()), }), (self .width @@ -286,20 +292,12 @@ impl ::re_types_core::AsComponents for SeriesLine { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesLine".into()), - archetype_field_name: Some(("width").into()), - component_name: ("rerun.components.StrokeWidth").into(), - }), + descriptor_override: Some(Self::descriptor_width()), }), (self.name.as_ref().map(|comp| (comp as &dyn ComponentBatch))).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesLine".into()), - archetype_field_name: Some(("name").into()), - component_name: ("rerun.components.Name").into(), - }), + descriptor_override: Some(Self::descriptor_name()), } }), (self @@ -308,11 +306,7 @@ impl ::re_types_core::AsComponents for SeriesLine { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesLine".into()), - archetype_field_name: Some(("aggregation_policy").into()), - component_name: ("rerun.components.AggregationPolicy").into(), - }), + descriptor_override: Some(Self::descriptor_aggregation_policy()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/series_point.rs b/crates/store/re_types/src/archetypes/series_point.rs index a1f15eb7240a..4639279ce0ab 100644 --- a/crates/store/re_types/src/archetypes/series_point.rs +++ b/crates/store/re_types/src/archetypes/series_point.rs @@ -88,72 +88,82 @@ pub struct SeriesPoint { pub marker_size: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl SeriesPoint { + /// Returns the [`ComponentDescriptor`] for [`Self::color`]. + #[inline] + pub fn descriptor_color() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.SeriesPoint".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("color".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::marker`]. + #[inline] + pub fn descriptor_marker() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.SeriesPoint".into()), + component_name: "rerun.components.MarkerShape".into(), + archetype_field_name: Some("marker".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::name`]. + #[inline] + pub fn descriptor_name() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.SeriesPoint".into()), + component_name: "rerun.components.Name".into(), + archetype_field_name: Some("name".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::marker_size`]. + #[inline] + pub fn descriptor_marker_size() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.SeriesPoint".into()), + component_name: "rerun.components.MarkerSize".into(), + archetype_field_name: Some("marker_size".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.SeriesPoint".into()), component_name: "rerun.components.SeriesPointIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [SeriesPoint::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 4usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesPoint".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("color".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesPoint".into()), - component_name: "rerun.components.MarkerShape".into(), - archetype_field_name: Some("marker".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesPoint".into()), - component_name: "rerun.components.Name".into(), - archetype_field_name: Some("name".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesPoint".into()), - component_name: "rerun.components.MarkerSize".into(), - archetype_field_name: Some("marker_size".into()), - }, + SeriesPoint::descriptor_color(), + SeriesPoint::descriptor_marker(), + SeriesPoint::descriptor_name(), + SeriesPoint::descriptor_marker_size(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesPoint".into()), - component_name: "rerun.components.SeriesPointIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesPoint".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("color".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesPoint".into()), - component_name: "rerun.components.MarkerShape".into(), - archetype_field_name: Some("marker".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesPoint".into()), - component_name: "rerun.components.Name".into(), - archetype_field_name: Some("name".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesPoint".into()), - component_name: "rerun.components.MarkerSize".into(), - archetype_field_name: Some("marker_size".into()), - }, + SeriesPoint::descriptor_indicator(), + SeriesPoint::descriptor_color(), + SeriesPoint::descriptor_marker(), + SeriesPoint::descriptor_name(), + SeriesPoint::descriptor_marker_size(), ] }); @@ -271,11 +281,7 @@ impl ::re_types_core::AsComponents for SeriesPoint { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesPoint".into()), - archetype_field_name: Some(("color").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_color()), }), (self .marker @@ -283,20 +289,12 @@ impl ::re_types_core::AsComponents for SeriesPoint { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesPoint".into()), - archetype_field_name: Some(("marker").into()), - component_name: ("rerun.components.MarkerShape").into(), - }), + descriptor_override: Some(Self::descriptor_marker()), }), (self.name.as_ref().map(|comp| (comp as &dyn ComponentBatch))).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesPoint".into()), - archetype_field_name: Some(("name").into()), - component_name: ("rerun.components.Name").into(), - }), + descriptor_override: Some(Self::descriptor_name()), } }), (self @@ -305,11 +303,7 @@ impl ::re_types_core::AsComponents for SeriesPoint { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.SeriesPoint".into()), - archetype_field_name: Some(("marker_size").into()), - component_name: ("rerun.components.MarkerSize").into(), - }), + descriptor_override: Some(Self::descriptor_marker_size()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/tensor.rs b/crates/store/re_types/src/archetypes/tensor.rs index fdfbb5561c79..a3e6ab751271 100644 --- a/crates/store/re_types/src/archetypes/tensor.rs +++ b/crates/store/re_types/src/archetypes/tensor.rs @@ -67,51 +67,53 @@ pub struct Tensor { pub value_range: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl Tensor { + /// Returns the [`ComponentDescriptor`] for [`Self::data`]. + #[inline] + pub fn descriptor_data() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Tensor".into()), component_name: "rerun.components.TensorData".into(), archetype_field_name: Some("data".into()), - }] - }); + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::value_range`]. + #[inline] + pub fn descriptor_value_range() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Tensor".into()), + component_name: "rerun.components.ValueRange".into(), + archetype_field_name: Some("value_range".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Tensor".into()), component_name: "rerun.components.TensorIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Tensor::descriptor_data()]); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Tensor::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Tensor".into()), - component_name: "rerun.components.ValueRange".into(), - archetype_field_name: Some("value_range".into()), - }] - }); + once_cell::sync::Lazy::new(|| [Tensor::descriptor_value_range()]); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Tensor".into()), - component_name: "rerun.components.TensorData".into(), - archetype_field_name: Some("data".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Tensor".into()), - component_name: "rerun.components.TensorIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Tensor".into()), - component_name: "rerun.components.ValueRange".into(), - archetype_field_name: Some("value_range".into()), - }, + Tensor::descriptor_data(), + Tensor::descriptor_indicator(), + Tensor::descriptor_value_range(), ] }); @@ -207,11 +209,7 @@ impl ::re_types_core::AsComponents for Tensor { (Some(&self.data as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Tensor".into()), - archetype_field_name: Some(("data").into()), - component_name: ("rerun.components.TensorData").into(), - }), + descriptor_override: Some(Self::descriptor_data()), } }), (self @@ -220,11 +218,7 @@ impl ::re_types_core::AsComponents for Tensor { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Tensor".into()), - archetype_field_name: Some(("value_range").into()), - component_name: ("rerun.components.ValueRange").into(), - }), + descriptor_override: Some(Self::descriptor_value_range()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/text_document.rs b/crates/store/re_types/src/archetypes/text_document.rs index c4d0b358cbd0..db9e3dbf4dfe 100644 --- a/crates/store/re_types/src/archetypes/text_document.rs +++ b/crates/store/re_types/src/archetypes/text_document.rs @@ -102,51 +102,53 @@ pub struct TextDocument { pub media_type: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl TextDocument { + /// Returns the [`ComponentDescriptor`] for [`Self::text`]. + #[inline] + pub fn descriptor_text() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.TextDocument".into()), component_name: "rerun.components.Text".into(), archetype_field_name: Some("text".into()), - }] - }); + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::media_type`]. + #[inline] + pub fn descriptor_media_type() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.TextDocument".into()), + component_name: "rerun.components.MediaType".into(), + archetype_field_name: Some("media_type".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.TextDocument".into()), component_name: "rerun.components.TextDocumentIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [TextDocument::descriptor_text()]); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [TextDocument::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.archetypes.TextDocument".into()), - component_name: "rerun.components.MediaType".into(), - archetype_field_name: Some("media_type".into()), - }] - }); + once_cell::sync::Lazy::new(|| [TextDocument::descriptor_media_type()]); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.TextDocument".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("text".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.TextDocument".into()), - component_name: "rerun.components.TextDocumentIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.TextDocument".into()), - component_name: "rerun.components.MediaType".into(), - archetype_field_name: Some("media_type".into()), - }, + TextDocument::descriptor_text(), + TextDocument::descriptor_indicator(), + TextDocument::descriptor_media_type(), ] }); @@ -242,11 +244,7 @@ impl ::re_types_core::AsComponents for TextDocument { (Some(&self.text as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.TextDocument".into()), - archetype_field_name: Some(("text").into()), - component_name: ("rerun.components.Text").into(), - }), + descriptor_override: Some(Self::descriptor_text()), } }), (self @@ -255,11 +253,7 @@ impl ::re_types_core::AsComponents for TextDocument { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.TextDocument".into()), - archetype_field_name: Some(("media_type").into()), - component_name: ("rerun.components.MediaType").into(), - }), + descriptor_override: Some(Self::descriptor_media_type()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/text_log.rs b/crates/store/re_types/src/archetypes/text_log.rs index 1e7954cc39b9..cd24949847ec 100644 --- a/crates/store/re_types/src/archetypes/text_log.rs +++ b/crates/store/re_types/src/archetypes/text_log.rs @@ -72,63 +72,64 @@ pub struct TextLog { pub color: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl TextLog { + /// Returns the [`ComponentDescriptor`] for [`Self::text`]. + #[inline] + pub fn descriptor_text() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.TextLog".into()), component_name: "rerun.components.Text".into(), archetype_field_name: Some("text".into()), - }] - }); + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = - once_cell::sync::Lazy::new(|| { - [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.TextLog".into()), - component_name: "rerun.components.TextLogLevel".into(), - archetype_field_name: Some("level".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.TextLog".into()), - component_name: "rerun.components.TextLogIndicator".into(), - archetype_field_name: None, - }, - ] - }); + /// Returns the [`ComponentDescriptor`] for [`Self::level`]. + #[inline] + pub fn descriptor_level() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.TextLog".into()), + component_name: "rerun.components.TextLogLevel".into(), + archetype_field_name: Some("level".into()), + } + } -static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::color`]. + #[inline] + pub fn descriptor_color() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.TextLog".into()), component_name: "rerun.components.Color".into(), archetype_field_name: Some("color".into()), - }] - }); + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.TextLog".into()), + component_name: "rerun.components.TextLogIndicator".into(), + archetype_field_name: None, + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [TextLog::descriptor_text()]); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = + once_cell::sync::Lazy::new(|| [TextLog::descriptor_level(), TextLog::descriptor_indicator()]); + +static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [TextLog::descriptor_color()]); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 4usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.TextLog".into()), - component_name: "rerun.components.Text".into(), - archetype_field_name: Some("text".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.TextLog".into()), - component_name: "rerun.components.TextLogLevel".into(), - archetype_field_name: Some("level".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.TextLog".into()), - component_name: "rerun.components.TextLogIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.TextLog".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("color".into()), - }, + TextLog::descriptor_text(), + TextLog::descriptor_level(), + TextLog::descriptor_indicator(), + TextLog::descriptor_color(), ] }); @@ -233,11 +234,7 @@ impl ::re_types_core::AsComponents for TextLog { (Some(&self.text as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.TextLog".into()), - archetype_field_name: Some(("text").into()), - component_name: ("rerun.components.Text").into(), - }), + descriptor_override: Some(Self::descriptor_text()), } }), (self @@ -246,11 +243,7 @@ impl ::re_types_core::AsComponents for TextLog { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.TextLog".into()), - archetype_field_name: Some(("level").into()), - component_name: ("rerun.components.TextLogLevel").into(), - }), + descriptor_override: Some(Self::descriptor_level()), }), (self .color @@ -258,11 +251,7 @@ impl ::re_types_core::AsComponents for TextLog { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.TextLog".into()), - archetype_field_name: Some(("color").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_color()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/transform3d.rs b/crates/store/re_types/src/archetypes/transform3d.rs index d7130769365a..7314c2e5d726 100644 --- a/crates/store/re_types/src/archetypes/transform3d.rs +++ b/crates/store/re_types/src/archetypes/transform3d.rs @@ -193,102 +193,118 @@ pub struct Transform3D { pub axis_length: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl Transform3D { + /// Returns the [`ComponentDescriptor`] for [`Self::translation`]. + #[inline] + pub fn descriptor_translation() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Transform3D".into()), + component_name: "rerun.components.Translation3D".into(), + archetype_field_name: Some("translation".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::rotation_axis_angle`]. + #[inline] + pub fn descriptor_rotation_axis_angle() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Transform3D".into()), + component_name: "rerun.components.RotationAxisAngle".into(), + archetype_field_name: Some("rotation_axis_angle".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::quaternion`]. + #[inline] + pub fn descriptor_quaternion() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Transform3D".into()), + component_name: "rerun.components.RotationQuat".into(), + archetype_field_name: Some("quaternion".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::scale`]. + #[inline] + pub fn descriptor_scale() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Transform3D".into()), + component_name: "rerun.components.Scale3D".into(), + archetype_field_name: Some("scale".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::mat3x3`]. + #[inline] + pub fn descriptor_mat3x3() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Transform3D".into()), + component_name: "rerun.components.TransformMat3x3".into(), + archetype_field_name: Some("mat3x3".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::relation`]. + #[inline] + pub fn descriptor_relation() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Transform3D".into()), + component_name: "rerun.components.TransformRelation".into(), + archetype_field_name: Some("relation".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::axis_length`]. + #[inline] + pub fn descriptor_axis_length() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.Transform3D".into()), + component_name: "rerun.components.AxisLength".into(), + archetype_field_name: Some("axis_length".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Transform3D".into()), component_name: "rerun.components.Transform3DIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Transform3D::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 7usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - component_name: "rerun.components.Translation3D".into(), - archetype_field_name: Some("translation".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - component_name: "rerun.components.RotationAxisAngle".into(), - archetype_field_name: Some("rotation_axis_angle".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - component_name: "rerun.components.RotationQuat".into(), - archetype_field_name: Some("quaternion".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - component_name: "rerun.components.Scale3D".into(), - archetype_field_name: Some("scale".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - component_name: "rerun.components.TransformMat3x3".into(), - archetype_field_name: Some("mat3x3".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - component_name: "rerun.components.TransformRelation".into(), - archetype_field_name: Some("relation".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - component_name: "rerun.components.AxisLength".into(), - archetype_field_name: Some("axis_length".into()), - }, + Transform3D::descriptor_translation(), + Transform3D::descriptor_rotation_axis_angle(), + Transform3D::descriptor_quaternion(), + Transform3D::descriptor_scale(), + Transform3D::descriptor_mat3x3(), + Transform3D::descriptor_relation(), + Transform3D::descriptor_axis_length(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 8usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - component_name: "rerun.components.Transform3DIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - component_name: "rerun.components.Translation3D".into(), - archetype_field_name: Some("translation".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - component_name: "rerun.components.RotationAxisAngle".into(), - archetype_field_name: Some("rotation_axis_angle".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - component_name: "rerun.components.RotationQuat".into(), - archetype_field_name: Some("quaternion".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - component_name: "rerun.components.Scale3D".into(), - archetype_field_name: Some("scale".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - component_name: "rerun.components.TransformMat3x3".into(), - archetype_field_name: Some("mat3x3".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - component_name: "rerun.components.TransformRelation".into(), - archetype_field_name: Some("relation".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - component_name: "rerun.components.AxisLength".into(), - archetype_field_name: Some("axis_length".into()), - }, + Transform3D::descriptor_indicator(), + Transform3D::descriptor_translation(), + Transform3D::descriptor_rotation_axis_angle(), + Transform3D::descriptor_quaternion(), + Transform3D::descriptor_scale(), + Transform3D::descriptor_mat3x3(), + Transform3D::descriptor_relation(), + Transform3D::descriptor_axis_length(), ] }); @@ -436,71 +452,43 @@ impl ::re_types_core::AsComponents for Transform3D { (Some(&self.translation as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - archetype_field_name: Some(("translation").into()), - component_name: ("rerun.components.Translation3D").into(), - }), + descriptor_override: Some(Self::descriptor_translation()), } }), (Some(&self.rotation_axis_angle as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - archetype_field_name: Some(("rotation_axis_angle").into()), - component_name: ("rerun.components.RotationAxisAngle").into(), - }), + descriptor_override: Some(Self::descriptor_rotation_axis_angle()), } }), (Some(&self.quaternion as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - archetype_field_name: Some(("quaternion").into()), - component_name: ("rerun.components.RotationQuat").into(), - }), + descriptor_override: Some(Self::descriptor_quaternion()), } }), (Some(&self.scale as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - archetype_field_name: Some(("scale").into()), - component_name: ("rerun.components.Scale3D").into(), - }), + descriptor_override: Some(Self::descriptor_scale()), } }), (Some(&self.mat3x3 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - archetype_field_name: Some(("mat3x3").into()), - component_name: ("rerun.components.TransformMat3x3").into(), - }), + descriptor_override: Some(Self::descriptor_mat3x3()), } }), (Some(&self.relation as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - archetype_field_name: Some(("relation").into()), - component_name: ("rerun.components.TransformRelation").into(), - }), + descriptor_override: Some(Self::descriptor_relation()), } }), (Some(&self.axis_length as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Transform3D".into()), - archetype_field_name: Some(("axis_length").into()), - component_name: ("rerun.components.AxisLength").into(), - }), + descriptor_override: Some(Self::descriptor_axis_length()), } }), ] diff --git a/crates/store/re_types/src/archetypes/video_frame_reference.rs b/crates/store/re_types/src/archetypes/video_frame_reference.rs index c4e3b4392bc5..c8b97239b437 100644 --- a/crates/store/re_types/src/archetypes/video_frame_reference.rs +++ b/crates/store/re_types/src/archetypes/video_frame_reference.rs @@ -146,51 +146,53 @@ pub struct VideoFrameReference { pub video_reference: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl VideoFrameReference { + /// Returns the [`ComponentDescriptor`] for [`Self::timestamp`]. + #[inline] + pub fn descriptor_timestamp() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.VideoFrameReference".into()), component_name: "rerun.components.VideoTimestamp".into(), archetype_field_name: Some("timestamp".into()), - }] - }); + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::video_reference`]. + #[inline] + pub fn descriptor_video_reference() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.archetypes.VideoFrameReference".into()), + component_name: "rerun.components.EntityPath".into(), + archetype_field_name: Some("video_reference".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.VideoFrameReference".into()), component_name: "rerun.components.VideoFrameReferenceIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [VideoFrameReference::descriptor_timestamp()]); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [VideoFrameReference::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.archetypes.VideoFrameReference".into()), - component_name: "rerun.components.EntityPath".into(), - archetype_field_name: Some("video_reference".into()), - }] - }); + once_cell::sync::Lazy::new(|| [VideoFrameReference::descriptor_video_reference()]); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.VideoFrameReference".into()), - component_name: "rerun.components.VideoTimestamp".into(), - archetype_field_name: Some("timestamp".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.VideoFrameReference".into()), - component_name: "rerun.components.VideoFrameReferenceIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.VideoFrameReference".into()), - component_name: "rerun.components.EntityPath".into(), - archetype_field_name: Some("video_reference".into()), - }, + VideoFrameReference::descriptor_timestamp(), + VideoFrameReference::descriptor_indicator(), + VideoFrameReference::descriptor_video_reference(), ] }); @@ -291,11 +293,7 @@ impl ::re_types_core::AsComponents for VideoFrameReference { (Some(&self.timestamp as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.VideoFrameReference".into()), - archetype_field_name: Some(("timestamp").into()), - component_name: ("rerun.components.VideoTimestamp").into(), - }), + descriptor_override: Some(Self::descriptor_timestamp()), } }), (self @@ -304,11 +302,7 @@ impl ::re_types_core::AsComponents for VideoFrameReference { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.VideoFrameReference".into()), - archetype_field_name: Some(("video_reference").into()), - component_name: ("rerun.components.EntityPath").into(), - }), + descriptor_override: Some(Self::descriptor_video_reference()), }), ] .into_iter() diff --git a/crates/store/re_types/src/archetypes/view_coordinates.rs b/crates/store/re_types/src/archetypes/view_coordinates.rs index a0bb30632ee9..b5a7d875c087 100644 --- a/crates/store/re_types/src/archetypes/view_coordinates.rs +++ b/crates/store/re_types/src/archetypes/view_coordinates.rs @@ -66,23 +66,33 @@ pub struct ViewCoordinates { pub xyz: crate::components::ViewCoordinates, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl ViewCoordinates { + /// Returns the [`ComponentDescriptor`] for [`Self::xyz`]. + #[inline] + pub fn descriptor_xyz() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.ViewCoordinates".into()), component_name: "rerun.components.ViewCoordinates".into(), archetype_field_name: Some("xyz".into()), - }] - }); + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.ViewCoordinates".into()), component_name: "rerun.components.ViewCoordinatesIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [ViewCoordinates::descriptor_xyz()]); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [ViewCoordinates::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = once_cell::sync::Lazy::new(|| []); @@ -90,16 +100,8 @@ static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.ViewCoordinates".into()), - component_name: "rerun.components.ViewCoordinates".into(), - archetype_field_name: Some("xyz".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.ViewCoordinates".into()), - component_name: "rerun.components.ViewCoordinatesIndicator".into(), - archetype_field_name: None, - }, + ViewCoordinates::descriptor_xyz(), + ViewCoordinates::descriptor_indicator(), ] }); @@ -186,11 +188,7 @@ impl ::re_types_core::AsComponents for ViewCoordinates { (Some(&self.xyz as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.ViewCoordinates".into()), - archetype_field_name: Some(("xyz").into()), - component_name: ("rerun.components.ViewCoordinates").into(), - }), + descriptor_override: Some(Self::descriptor_xyz()), } }), ] diff --git a/crates/store/re_types/src/blueprint/archetypes/background.rs b/crates/store/re_types/src/blueprint/archetypes/background.rs index f6d6b5417771..57443643507b 100644 --- a/crates/store/re_types/src/blueprint/archetypes/background.rs +++ b/crates/store/re_types/src/blueprint/archetypes/background.rs @@ -28,51 +28,53 @@ pub struct Background { pub color: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl Background { + /// Returns the [`ComponentDescriptor`] for [`Self::kind`]. + #[inline] + pub fn descriptor_kind() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.Background".into()), component_name: "rerun.blueprint.components.BackgroundKind".into(), archetype_field_name: Some("kind".into()), - }] - }); + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::color`]. + #[inline] + pub fn descriptor_color() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.Background".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("color".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.Background".into()), component_name: "rerun.blueprint.components.BackgroundIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Background::descriptor_kind()]); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Background::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.Background".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("color".into()), - }] - }); + once_cell::sync::Lazy::new(|| [Background::descriptor_color()]); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.Background".into()), - component_name: "rerun.blueprint.components.BackgroundKind".into(), - archetype_field_name: Some("kind".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.Background".into()), - component_name: "rerun.blueprint.components.BackgroundIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.Background".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("color".into()), - }, + Background::descriptor_kind(), + Background::descriptor_indicator(), + Background::descriptor_color(), ] }); @@ -168,11 +170,7 @@ impl ::re_types_core::AsComponents for Background { (Some(&self.kind as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.Background".into()), - archetype_field_name: Some(("kind").into()), - component_name: ("rerun.blueprint.components.BackgroundKind").into(), - }), + descriptor_override: Some(Self::descriptor_kind()), } }), (self @@ -181,11 +179,7 @@ impl ::re_types_core::AsComponents for Background { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.Background".into()), - archetype_field_name: Some(("color").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_color()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/container_blueprint.rs b/crates/store/re_types/src/blueprint/archetypes/container_blueprint.rs index 24d6cba45ff4..06d88ac97c4d 100644 --- a/crates/store/re_types/src/blueprint/archetypes/container_blueprint.rs +++ b/crates/store/re_types/src/blueprint/archetypes/container_blueprint.rs @@ -62,113 +62,129 @@ pub struct ContainerBlueprint { pub grid_columns: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl ContainerBlueprint { + /// Returns the [`ComponentDescriptor`] for [`Self::container_kind`]. + #[inline] + pub fn descriptor_container_kind() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), component_name: "rerun.blueprint.components.ContainerKind".into(), archetype_field_name: Some("container_kind".into()), - }] - }); + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::display_name`]. + #[inline] + pub fn descriptor_display_name() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), + component_name: "rerun.components.Name".into(), + archetype_field_name: Some("display_name".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::contents`]. + #[inline] + pub fn descriptor_contents() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), + component_name: "rerun.blueprint.components.IncludedContent".into(), + archetype_field_name: Some("contents".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::col_shares`]. + #[inline] + pub fn descriptor_col_shares() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), + component_name: "rerun.blueprint.components.ColumnShare".into(), + archetype_field_name: Some("col_shares".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::row_shares`]. + #[inline] + pub fn descriptor_row_shares() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), + component_name: "rerun.blueprint.components.RowShare".into(), + archetype_field_name: Some("row_shares".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::active_tab`]. + #[inline] + pub fn descriptor_active_tab() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), + component_name: "rerun.blueprint.components.ActiveTab".into(), + archetype_field_name: Some("active_tab".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::visible`]. + #[inline] + pub fn descriptor_visible() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), + component_name: "rerun.blueprint.components.Visible".into(), + archetype_field_name: Some("visible".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::grid_columns`]. + #[inline] + pub fn descriptor_grid_columns() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), + component_name: "rerun.blueprint.components.GridColumns".into(), + archetype_field_name: Some("grid_columns".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), component_name: "rerun.blueprint.components.ContainerBlueprintIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [ContainerBlueprint::descriptor_container_kind()]); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [ContainerBlueprint::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 7usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - component_name: "rerun.components.Name".into(), - archetype_field_name: Some("display_name".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - component_name: "rerun.blueprint.components.IncludedContent".into(), - archetype_field_name: Some("contents".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - component_name: "rerun.blueprint.components.ColumnShare".into(), - archetype_field_name: Some("col_shares".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - component_name: "rerun.blueprint.components.RowShare".into(), - archetype_field_name: Some("row_shares".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - component_name: "rerun.blueprint.components.ActiveTab".into(), - archetype_field_name: Some("active_tab".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - component_name: "rerun.blueprint.components.Visible".into(), - archetype_field_name: Some("visible".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - component_name: "rerun.blueprint.components.GridColumns".into(), - archetype_field_name: Some("grid_columns".into()), - }, + ContainerBlueprint::descriptor_display_name(), + ContainerBlueprint::descriptor_contents(), + ContainerBlueprint::descriptor_col_shares(), + ContainerBlueprint::descriptor_row_shares(), + ContainerBlueprint::descriptor_active_tab(), + ContainerBlueprint::descriptor_visible(), + ContainerBlueprint::descriptor_grid_columns(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 9usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - component_name: "rerun.blueprint.components.ContainerKind".into(), - archetype_field_name: Some("container_kind".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - component_name: "rerun.blueprint.components.ContainerBlueprintIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - component_name: "rerun.components.Name".into(), - archetype_field_name: Some("display_name".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - component_name: "rerun.blueprint.components.IncludedContent".into(), - archetype_field_name: Some("contents".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - component_name: "rerun.blueprint.components.ColumnShare".into(), - archetype_field_name: Some("col_shares".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - component_name: "rerun.blueprint.components.RowShare".into(), - archetype_field_name: Some("row_shares".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - component_name: "rerun.blueprint.components.ActiveTab".into(), - archetype_field_name: Some("active_tab".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - component_name: "rerun.blueprint.components.Visible".into(), - archetype_field_name: Some("visible".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - component_name: "rerun.blueprint.components.GridColumns".into(), - archetype_field_name: Some("grid_columns".into()), - }, + ContainerBlueprint::descriptor_container_kind(), + ContainerBlueprint::descriptor_indicator(), + ContainerBlueprint::descriptor_display_name(), + ContainerBlueprint::descriptor_contents(), + ContainerBlueprint::descriptor_col_shares(), + ContainerBlueprint::descriptor_row_shares(), + ContainerBlueprint::descriptor_active_tab(), + ContainerBlueprint::descriptor_visible(), + ContainerBlueprint::descriptor_grid_columns(), ] }); @@ -343,13 +359,7 @@ impl ::re_types_core::AsComponents for ContainerBlueprint { (Some(&self.container_kind as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some( - "rerun.blueprint.archetypes.ContainerBlueprint".into(), - ), - archetype_field_name: Some(("container_kind").into()), - component_name: ("rerun.blueprint.components.ContainerKind").into(), - }), + descriptor_override: Some(Self::descriptor_container_kind()), } }), (self @@ -358,11 +368,7 @@ impl ::re_types_core::AsComponents for ContainerBlueprint { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - archetype_field_name: Some(("display_name").into()), - component_name: ("rerun.components.Name").into(), - }), + descriptor_override: Some(Self::descriptor_display_name()), }), (self .contents @@ -370,11 +376,7 @@ impl ::re_types_core::AsComponents for ContainerBlueprint { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - archetype_field_name: Some(("contents").into()), - component_name: ("rerun.blueprint.components.IncludedContent").into(), - }), + descriptor_override: Some(Self::descriptor_contents()), }), (self .col_shares @@ -382,11 +384,7 @@ impl ::re_types_core::AsComponents for ContainerBlueprint { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - archetype_field_name: Some(("col_shares").into()), - component_name: ("rerun.blueprint.components.ColumnShare").into(), - }), + descriptor_override: Some(Self::descriptor_col_shares()), }), (self .row_shares @@ -394,11 +392,7 @@ impl ::re_types_core::AsComponents for ContainerBlueprint { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - archetype_field_name: Some(("row_shares").into()), - component_name: ("rerun.blueprint.components.RowShare").into(), - }), + descriptor_override: Some(Self::descriptor_row_shares()), }), (self .active_tab @@ -406,11 +400,7 @@ impl ::re_types_core::AsComponents for ContainerBlueprint { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - archetype_field_name: Some(("active_tab").into()), - component_name: ("rerun.blueprint.components.ActiveTab").into(), - }), + descriptor_override: Some(Self::descriptor_active_tab()), }), (self .visible @@ -418,11 +408,7 @@ impl ::re_types_core::AsComponents for ContainerBlueprint { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - archetype_field_name: Some(("visible").into()), - component_name: ("rerun.blueprint.components.Visible").into(), - }), + descriptor_override: Some(Self::descriptor_visible()), }), (self .grid_columns @@ -430,11 +416,7 @@ impl ::re_types_core::AsComponents for ContainerBlueprint { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ContainerBlueprint".into()), - archetype_field_name: Some(("grid_columns").into()), - component_name: ("rerun.blueprint.components.GridColumns").into(), - }), + descriptor_override: Some(Self::descriptor_grid_columns()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/dataframe_query.rs b/crates/store/re_types/src/blueprint/archetypes/dataframe_query.rs index 7dd6226ab381..29d28f4c521b 100644 --- a/crates/store/re_types/src/blueprint/archetypes/dataframe_query.rs +++ b/crates/store/re_types/src/blueprint/archetypes/dataframe_query.rs @@ -41,82 +41,94 @@ pub struct DataframeQuery { pub select: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl DataframeQuery { + /// Returns the [`ComponentDescriptor`] for [`Self::timeline`]. + #[inline] + pub fn descriptor_timeline() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), + component_name: "rerun.blueprint.components.TimelineName".into(), + archetype_field_name: Some("timeline".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::filter_by_range`]. + #[inline] + pub fn descriptor_filter_by_range() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), + component_name: "rerun.blueprint.components.FilterByRange".into(), + archetype_field_name: Some("filter_by_range".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::filter_is_not_null`]. + #[inline] + pub fn descriptor_filter_is_not_null() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), + component_name: "rerun.blueprint.components.FilterIsNotNull".into(), + archetype_field_name: Some("filter_is_not_null".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::apply_latest_at`]. + #[inline] + pub fn descriptor_apply_latest_at() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), + component_name: "rerun.blueprint.components.ApplyLatestAt".into(), + archetype_field_name: Some("apply_latest_at".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::select`]. + #[inline] + pub fn descriptor_select() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), + component_name: "rerun.blueprint.components.SelectedColumns".into(), + archetype_field_name: Some("select".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), component_name: "rerun.blueprint.components.DataframeQueryIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [DataframeQuery::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), - component_name: "rerun.blueprint.components.TimelineName".into(), - archetype_field_name: Some("timeline".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), - component_name: "rerun.blueprint.components.FilterByRange".into(), - archetype_field_name: Some("filter_by_range".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), - component_name: "rerun.blueprint.components.FilterIsNotNull".into(), - archetype_field_name: Some("filter_is_not_null".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), - component_name: "rerun.blueprint.components.ApplyLatestAt".into(), - archetype_field_name: Some("apply_latest_at".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), - component_name: "rerun.blueprint.components.SelectedColumns".into(), - archetype_field_name: Some("select".into()), - }, + DataframeQuery::descriptor_timeline(), + DataframeQuery::descriptor_filter_by_range(), + DataframeQuery::descriptor_filter_is_not_null(), + DataframeQuery::descriptor_apply_latest_at(), + DataframeQuery::descriptor_select(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 6usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), - component_name: "rerun.blueprint.components.DataframeQueryIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), - component_name: "rerun.blueprint.components.TimelineName".into(), - archetype_field_name: Some("timeline".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), - component_name: "rerun.blueprint.components.FilterByRange".into(), - archetype_field_name: Some("filter_by_range".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), - component_name: "rerun.blueprint.components.FilterIsNotNull".into(), - archetype_field_name: Some("filter_is_not_null".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), - component_name: "rerun.blueprint.components.ApplyLatestAt".into(), - archetype_field_name: Some("apply_latest_at".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), - component_name: "rerun.blueprint.components.SelectedColumns".into(), - archetype_field_name: Some("select".into()), - }, + DataframeQuery::descriptor_indicator(), + DataframeQuery::descriptor_timeline(), + DataframeQuery::descriptor_filter_by_range(), + DataframeQuery::descriptor_filter_is_not_null(), + DataframeQuery::descriptor_apply_latest_at(), + DataframeQuery::descriptor_select(), ] }); @@ -249,11 +261,7 @@ impl ::re_types_core::AsComponents for DataframeQuery { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), - archetype_field_name: Some(("timeline").into()), - component_name: ("rerun.blueprint.components.TimelineName").into(), - }), + descriptor_override: Some(Self::descriptor_timeline()), }), (self .filter_by_range @@ -261,11 +269,7 @@ impl ::re_types_core::AsComponents for DataframeQuery { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), - archetype_field_name: Some(("filter_by_range").into()), - component_name: ("rerun.blueprint.components.FilterByRange").into(), - }), + descriptor_override: Some(Self::descriptor_filter_by_range()), }), (self .filter_is_not_null @@ -273,11 +277,7 @@ impl ::re_types_core::AsComponents for DataframeQuery { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), - archetype_field_name: Some(("filter_is_not_null").into()), - component_name: ("rerun.blueprint.components.FilterIsNotNull").into(), - }), + descriptor_override: Some(Self::descriptor_filter_is_not_null()), }), (self .apply_latest_at @@ -285,11 +285,7 @@ impl ::re_types_core::AsComponents for DataframeQuery { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), - archetype_field_name: Some(("apply_latest_at").into()), - component_name: ("rerun.blueprint.components.ApplyLatestAt").into(), - }), + descriptor_override: Some(Self::descriptor_apply_latest_at()), }), (self .select @@ -297,11 +293,7 @@ impl ::re_types_core::AsComponents for DataframeQuery { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.DataframeQuery".into()), - archetype_field_name: Some(("select").into()), - component_name: ("rerun.blueprint.components.SelectedColumns").into(), - }), + descriptor_override: Some(Self::descriptor_select()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/force_center.rs b/crates/store/re_types/src/blueprint/archetypes/force_center.rs index c25fdd1babf4..b9250ac38e67 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_center.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_center.rs @@ -30,52 +30,58 @@ pub struct ForceCenter { pub strength: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl ForceCenter { + /// Returns the [`ComponentDescriptor`] for [`Self::enabled`]. + #[inline] + pub fn descriptor_enabled() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ForceCenter".into()), + component_name: "rerun.blueprint.components.Enabled".into(), + archetype_field_name: Some("enabled".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::strength`]. + #[inline] + pub fn descriptor_strength() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ForceCenter".into()), + component_name: "rerun.blueprint.components.ForceStrength".into(), + archetype_field_name: Some("strength".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.ForceCenter".into()), component_name: "rerun.blueprint.components.ForceCenterIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [ForceCenter::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCenter".into()), - component_name: "rerun.blueprint.components.Enabled".into(), - archetype_field_name: Some("enabled".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCenter".into()), - component_name: "rerun.blueprint.components.ForceStrength".into(), - archetype_field_name: Some("strength".into()), - }, + ForceCenter::descriptor_enabled(), + ForceCenter::descriptor_strength(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCenter".into()), - component_name: "rerun.blueprint.components.ForceCenterIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCenter".into()), - component_name: "rerun.blueprint.components.Enabled".into(), - archetype_field_name: Some("enabled".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCenter".into()), - component_name: "rerun.blueprint.components.ForceStrength".into(), - archetype_field_name: Some("strength".into()), - }, + ForceCenter::descriptor_indicator(), + ForceCenter::descriptor_enabled(), + ForceCenter::descriptor_strength(), ] }); @@ -172,11 +178,7 @@ impl ::re_types_core::AsComponents for ForceCenter { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCenter".into()), - archetype_field_name: Some(("enabled").into()), - component_name: ("rerun.blueprint.components.Enabled").into(), - }), + descriptor_override: Some(Self::descriptor_enabled()), }), (self .strength @@ -184,11 +186,7 @@ impl ::re_types_core::AsComponents for ForceCenter { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCenter".into()), - archetype_field_name: Some(("strength").into()), - component_name: ("rerun.blueprint.components.ForceStrength").into(), - }), + descriptor_override: Some(Self::descriptor_strength()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs b/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs index 0e8b3cf7f641..95eaccbeda11 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs @@ -35,62 +35,70 @@ pub struct ForceCollisionRadius { pub iterations: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl ForceCollisionRadius { + /// Returns the [`ComponentDescriptor`] for [`Self::enabled`]. + #[inline] + pub fn descriptor_enabled() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ForceCollisionRadius".into()), + component_name: "rerun.blueprint.components.Enabled".into(), + archetype_field_name: Some("enabled".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::strength`]. + #[inline] + pub fn descriptor_strength() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ForceCollisionRadius".into()), + component_name: "rerun.blueprint.components.ForceStrength".into(), + archetype_field_name: Some("strength".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::iterations`]. + #[inline] + pub fn descriptor_iterations() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ForceCollisionRadius".into()), + component_name: "rerun.blueprint.components.ForceIterations".into(), + archetype_field_name: Some("iterations".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.ForceCollisionRadius".into()), component_name: "rerun.blueprint.components.ForceCollisionRadiusIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [ForceCollisionRadius::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCollisionRadius".into()), - component_name: "rerun.blueprint.components.Enabled".into(), - archetype_field_name: Some("enabled".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCollisionRadius".into()), - component_name: "rerun.blueprint.components.ForceStrength".into(), - archetype_field_name: Some("strength".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCollisionRadius".into()), - component_name: "rerun.blueprint.components.ForceIterations".into(), - archetype_field_name: Some("iterations".into()), - }, + ForceCollisionRadius::descriptor_enabled(), + ForceCollisionRadius::descriptor_strength(), + ForceCollisionRadius::descriptor_iterations(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 4usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCollisionRadius".into()), - component_name: "rerun.blueprint.components.ForceCollisionRadiusIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCollisionRadius".into()), - component_name: "rerun.blueprint.components.Enabled".into(), - archetype_field_name: Some("enabled".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCollisionRadius".into()), - component_name: "rerun.blueprint.components.ForceStrength".into(), - archetype_field_name: Some("strength".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCollisionRadius".into()), - component_name: "rerun.blueprint.components.ForceIterations".into(), - archetype_field_name: Some("iterations".into()), - }, + ForceCollisionRadius::descriptor_indicator(), + ForceCollisionRadius::descriptor_enabled(), + ForceCollisionRadius::descriptor_strength(), + ForceCollisionRadius::descriptor_iterations(), ] }); @@ -202,11 +210,7 @@ impl ::re_types_core::AsComponents for ForceCollisionRadius { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCollisionRadius".into()), - archetype_field_name: Some(("enabled").into()), - component_name: ("rerun.blueprint.components.Enabled").into(), - }), + descriptor_override: Some(Self::descriptor_enabled()), }), (self .strength @@ -214,11 +218,7 @@ impl ::re_types_core::AsComponents for ForceCollisionRadius { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCollisionRadius".into()), - archetype_field_name: Some(("strength").into()), - component_name: ("rerun.blueprint.components.ForceStrength").into(), - }), + descriptor_override: Some(Self::descriptor_strength()), }), (self .iterations @@ -226,11 +226,7 @@ impl ::re_types_core::AsComponents for ForceCollisionRadius { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceCollisionRadius".into()), - archetype_field_name: Some(("iterations").into()), - component_name: ("rerun.blueprint.components.ForceIterations").into(), - }), + descriptor_override: Some(Self::descriptor_iterations()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/force_link.rs b/crates/store/re_types/src/blueprint/archetypes/force_link.rs index 3837ad3ec0a2..27fd69040f60 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_link.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_link.rs @@ -35,62 +35,70 @@ pub struct ForceLink { pub iterations: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl ForceLink { + /// Returns the [`ComponentDescriptor`] for [`Self::enabled`]. + #[inline] + pub fn descriptor_enabled() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ForceLink".into()), + component_name: "rerun.blueprint.components.Enabled".into(), + archetype_field_name: Some("enabled".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::distance`]. + #[inline] + pub fn descriptor_distance() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ForceLink".into()), + component_name: "rerun.blueprint.components.ForceDistance".into(), + archetype_field_name: Some("distance".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::iterations`]. + #[inline] + pub fn descriptor_iterations() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ForceLink".into()), + component_name: "rerun.blueprint.components.ForceIterations".into(), + archetype_field_name: Some("iterations".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.ForceLink".into()), component_name: "rerun.blueprint.components.ForceLinkIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [ForceLink::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceLink".into()), - component_name: "rerun.blueprint.components.Enabled".into(), - archetype_field_name: Some("enabled".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceLink".into()), - component_name: "rerun.blueprint.components.ForceDistance".into(), - archetype_field_name: Some("distance".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceLink".into()), - component_name: "rerun.blueprint.components.ForceIterations".into(), - archetype_field_name: Some("iterations".into()), - }, + ForceLink::descriptor_enabled(), + ForceLink::descriptor_distance(), + ForceLink::descriptor_iterations(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 4usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceLink".into()), - component_name: "rerun.blueprint.components.ForceLinkIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceLink".into()), - component_name: "rerun.blueprint.components.Enabled".into(), - archetype_field_name: Some("enabled".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceLink".into()), - component_name: "rerun.blueprint.components.ForceDistance".into(), - archetype_field_name: Some("distance".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceLink".into()), - component_name: "rerun.blueprint.components.ForceIterations".into(), - archetype_field_name: Some("iterations".into()), - }, + ForceLink::descriptor_indicator(), + ForceLink::descriptor_enabled(), + ForceLink::descriptor_distance(), + ForceLink::descriptor_iterations(), ] }); @@ -201,11 +209,7 @@ impl ::re_types_core::AsComponents for ForceLink { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceLink".into()), - archetype_field_name: Some(("enabled").into()), - component_name: ("rerun.blueprint.components.Enabled").into(), - }), + descriptor_override: Some(Self::descriptor_enabled()), }), (self .distance @@ -213,11 +217,7 @@ impl ::re_types_core::AsComponents for ForceLink { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceLink".into()), - archetype_field_name: Some(("distance").into()), - component_name: ("rerun.blueprint.components.ForceDistance").into(), - }), + descriptor_override: Some(Self::descriptor_distance()), }), (self .iterations @@ -225,11 +225,7 @@ impl ::re_types_core::AsComponents for ForceLink { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceLink".into()), - archetype_field_name: Some(("iterations").into()), - component_name: ("rerun.blueprint.components.ForceIterations").into(), - }), + descriptor_override: Some(Self::descriptor_iterations()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs b/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs index 6701b64a7079..13f305dd6117 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs @@ -35,52 +35,58 @@ pub struct ForceManyBody { pub strength: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl ForceManyBody { + /// Returns the [`ComponentDescriptor`] for [`Self::enabled`]. + #[inline] + pub fn descriptor_enabled() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ForceManyBody".into()), + component_name: "rerun.blueprint.components.Enabled".into(), + archetype_field_name: Some("enabled".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::strength`]. + #[inline] + pub fn descriptor_strength() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ForceManyBody".into()), + component_name: "rerun.blueprint.components.ForceStrength".into(), + archetype_field_name: Some("strength".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.ForceManyBody".into()), component_name: "rerun.blueprint.components.ForceManyBodyIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [ForceManyBody::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceManyBody".into()), - component_name: "rerun.blueprint.components.Enabled".into(), - archetype_field_name: Some("enabled".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceManyBody".into()), - component_name: "rerun.blueprint.components.ForceStrength".into(), - archetype_field_name: Some("strength".into()), - }, + ForceManyBody::descriptor_enabled(), + ForceManyBody::descriptor_strength(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceManyBody".into()), - component_name: "rerun.blueprint.components.ForceManyBodyIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceManyBody".into()), - component_name: "rerun.blueprint.components.Enabled".into(), - archetype_field_name: Some("enabled".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceManyBody".into()), - component_name: "rerun.blueprint.components.ForceStrength".into(), - archetype_field_name: Some("strength".into()), - }, + ForceManyBody::descriptor_indicator(), + ForceManyBody::descriptor_enabled(), + ForceManyBody::descriptor_strength(), ] }); @@ -177,11 +183,7 @@ impl ::re_types_core::AsComponents for ForceManyBody { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceManyBody".into()), - archetype_field_name: Some(("enabled").into()), - component_name: ("rerun.blueprint.components.Enabled").into(), - }), + descriptor_override: Some(Self::descriptor_enabled()), }), (self .strength @@ -189,11 +191,7 @@ impl ::re_types_core::AsComponents for ForceManyBody { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForceManyBody".into()), - archetype_field_name: Some(("strength").into()), - component_name: ("rerun.blueprint.components.ForceStrength").into(), - }), + descriptor_override: Some(Self::descriptor_strength()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/force_position.rs b/crates/store/re_types/src/blueprint/archetypes/force_position.rs index eb3f4bab7a0a..6483001f3a90 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_position.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_position.rs @@ -33,62 +33,70 @@ pub struct ForcePosition { pub position: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl ForcePosition { + /// Returns the [`ComponentDescriptor`] for [`Self::enabled`]. + #[inline] + pub fn descriptor_enabled() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ForcePosition".into()), + component_name: "rerun.blueprint.components.Enabled".into(), + archetype_field_name: Some("enabled".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::strength`]. + #[inline] + pub fn descriptor_strength() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ForcePosition".into()), + component_name: "rerun.blueprint.components.ForceStrength".into(), + archetype_field_name: Some("strength".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::position`]. + #[inline] + pub fn descriptor_position() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ForcePosition".into()), + component_name: "rerun.components.Position2D".into(), + archetype_field_name: Some("position".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.ForcePosition".into()), component_name: "rerun.blueprint.components.ForcePositionIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [ForcePosition::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForcePosition".into()), - component_name: "rerun.blueprint.components.Enabled".into(), - archetype_field_name: Some("enabled".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForcePosition".into()), - component_name: "rerun.blueprint.components.ForceStrength".into(), - archetype_field_name: Some("strength".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForcePosition".into()), - component_name: "rerun.components.Position2D".into(), - archetype_field_name: Some("position".into()), - }, + ForcePosition::descriptor_enabled(), + ForcePosition::descriptor_strength(), + ForcePosition::descriptor_position(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 4usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForcePosition".into()), - component_name: "rerun.blueprint.components.ForcePositionIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForcePosition".into()), - component_name: "rerun.blueprint.components.Enabled".into(), - archetype_field_name: Some("enabled".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForcePosition".into()), - component_name: "rerun.blueprint.components.ForceStrength".into(), - archetype_field_name: Some("strength".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForcePosition".into()), - component_name: "rerun.components.Position2D".into(), - archetype_field_name: Some("position".into()), - }, + ForcePosition::descriptor_indicator(), + ForcePosition::descriptor_enabled(), + ForcePosition::descriptor_strength(), + ForcePosition::descriptor_position(), ] }); @@ -198,11 +206,7 @@ impl ::re_types_core::AsComponents for ForcePosition { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForcePosition".into()), - archetype_field_name: Some(("enabled").into()), - component_name: ("rerun.blueprint.components.Enabled").into(), - }), + descriptor_override: Some(Self::descriptor_enabled()), }), (self .strength @@ -210,11 +214,7 @@ impl ::re_types_core::AsComponents for ForcePosition { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForcePosition".into()), - archetype_field_name: Some(("strength").into()), - component_name: ("rerun.blueprint.components.ForceStrength").into(), - }), + descriptor_override: Some(Self::descriptor_strength()), }), (self .position @@ -222,11 +222,7 @@ impl ::re_types_core::AsComponents for ForcePosition { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ForcePosition".into()), - archetype_field_name: Some(("position").into()), - component_name: ("rerun.components.Position2D").into(), - }), + descriptor_override: Some(Self::descriptor_position()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs index bbbd0918893e..c1f0781b50e6 100644 --- a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs +++ b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs @@ -49,82 +49,94 @@ pub struct LineGrid3D { pub color: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl LineGrid3D { + /// Returns the [`ComponentDescriptor`] for [`Self::visible`]. + #[inline] + pub fn descriptor_visible() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), + component_name: "rerun.blueprint.components.Visible".into(), + archetype_field_name: Some("visible".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::spacing`]. + #[inline] + pub fn descriptor_spacing() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), + component_name: "rerun.blueprint.components.GridSpacing".into(), + archetype_field_name: Some("spacing".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::plane`]. + #[inline] + pub fn descriptor_plane() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), + component_name: "rerun.components.Plane3D".into(), + archetype_field_name: Some("plane".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::stroke_width`]. + #[inline] + pub fn descriptor_stroke_width() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), + component_name: "rerun.components.StrokeWidth".into(), + archetype_field_name: Some("stroke_width".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::color`]. + #[inline] + pub fn descriptor_color() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), + component_name: "rerun.components.Color".into(), + archetype_field_name: Some("color".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), component_name: "rerun.blueprint.components.LineGrid3DIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [LineGrid3D::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), - component_name: "rerun.blueprint.components.Visible".into(), - archetype_field_name: Some("visible".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), - component_name: "rerun.blueprint.components.GridSpacing".into(), - archetype_field_name: Some("spacing".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), - component_name: "rerun.components.Plane3D".into(), - archetype_field_name: Some("plane".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), - component_name: "rerun.components.StrokeWidth".into(), - archetype_field_name: Some("stroke_width".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("color".into()), - }, + LineGrid3D::descriptor_visible(), + LineGrid3D::descriptor_spacing(), + LineGrid3D::descriptor_plane(), + LineGrid3D::descriptor_stroke_width(), + LineGrid3D::descriptor_color(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 6usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), - component_name: "rerun.blueprint.components.LineGrid3DIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), - component_name: "rerun.blueprint.components.Visible".into(), - archetype_field_name: Some("visible".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), - component_name: "rerun.blueprint.components.GridSpacing".into(), - archetype_field_name: Some("spacing".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), - component_name: "rerun.components.Plane3D".into(), - archetype_field_name: Some("plane".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), - component_name: "rerun.components.StrokeWidth".into(), - archetype_field_name: Some("stroke_width".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), - component_name: "rerun.components.Color".into(), - archetype_field_name: Some("color".into()), - }, + LineGrid3D::descriptor_indicator(), + LineGrid3D::descriptor_visible(), + LineGrid3D::descriptor_spacing(), + LineGrid3D::descriptor_plane(), + LineGrid3D::descriptor_stroke_width(), + LineGrid3D::descriptor_color(), ] }); @@ -254,11 +266,7 @@ impl ::re_types_core::AsComponents for LineGrid3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), - archetype_field_name: Some(("visible").into()), - component_name: ("rerun.blueprint.components.Visible").into(), - }), + descriptor_override: Some(Self::descriptor_visible()), }), (self .spacing @@ -266,11 +274,7 @@ impl ::re_types_core::AsComponents for LineGrid3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), - archetype_field_name: Some(("spacing").into()), - component_name: ("rerun.blueprint.components.GridSpacing").into(), - }), + descriptor_override: Some(Self::descriptor_spacing()), }), (self .plane @@ -278,11 +282,7 @@ impl ::re_types_core::AsComponents for LineGrid3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), - archetype_field_name: Some(("plane").into()), - component_name: ("rerun.components.Plane3D").into(), - }), + descriptor_override: Some(Self::descriptor_plane()), }), (self .stroke_width @@ -290,11 +290,7 @@ impl ::re_types_core::AsComponents for LineGrid3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), - archetype_field_name: Some(("stroke_width").into()), - component_name: ("rerun.components.StrokeWidth").into(), - }), + descriptor_override: Some(Self::descriptor_stroke_width()), }), (self .color @@ -302,11 +298,7 @@ impl ::re_types_core::AsComponents for LineGrid3D { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.LineGrid3D".into()), - archetype_field_name: Some(("color").into()), - component_name: ("rerun.components.Color").into(), - }), + descriptor_override: Some(Self::descriptor_color()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/map_background.rs b/crates/store/re_types/src/blueprint/archetypes/map_background.rs index ab06985eb6a4..72fecb09f980 100644 --- a/crates/store/re_types/src/blueprint/archetypes/map_background.rs +++ b/crates/store/re_types/src/blueprint/archetypes/map_background.rs @@ -27,40 +27,42 @@ pub struct MapBackground { pub provider: crate::blueprint::components::MapProvider, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl MapBackground { + /// Returns the [`ComponentDescriptor`] for [`Self::provider`]. + #[inline] + pub fn descriptor_provider() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.MapBackground".into()), + component_name: "rerun.blueprint.components.MapProvider".into(), + archetype_field_name: Some("provider".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.MapBackground".into()), component_name: "rerun.blueprint.components.MapBackgroundIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [MapBackground::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.MapBackground".into()), - component_name: "rerun.blueprint.components.MapProvider".into(), - archetype_field_name: Some("provider".into()), - }] - }); + once_cell::sync::Lazy::new(|| [MapBackground::descriptor_provider()]); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.MapBackground".into()), - component_name: "rerun.blueprint.components.MapBackgroundIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.MapBackground".into()), - component_name: "rerun.blueprint.components.MapProvider".into(), - archetype_field_name: Some("provider".into()), - }, + MapBackground::descriptor_indicator(), + MapBackground::descriptor_provider(), ] }); @@ -147,11 +149,7 @@ impl ::re_types_core::AsComponents for MapBackground { (Some(&self.provider as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.MapBackground".into()), - archetype_field_name: Some(("provider").into()), - component_name: ("rerun.blueprint.components.MapProvider").into(), - }), + descriptor_override: Some(Self::descriptor_provider()), } }), ] diff --git a/crates/store/re_types/src/blueprint/archetypes/map_zoom.rs b/crates/store/re_types/src/blueprint/archetypes/map_zoom.rs index 04f1cde2f6d6..44a9a07a539d 100644 --- a/crates/store/re_types/src/blueprint/archetypes/map_zoom.rs +++ b/crates/store/re_types/src/blueprint/archetypes/map_zoom.rs @@ -27,42 +27,39 @@ pub struct MapZoom { pub zoom: crate::blueprint::components::ZoomLevel, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl MapZoom { + /// Returns the [`ComponentDescriptor`] for [`Self::zoom`]. + #[inline] + pub fn descriptor_zoom() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.MapZoom".into()), + component_name: "rerun.blueprint.components.ZoomLevel".into(), + archetype_field_name: Some("zoom".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.MapZoom".into()), component_name: "rerun.blueprint.components.MapZoomIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [MapZoom::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.MapZoom".into()), - component_name: "rerun.blueprint.components.ZoomLevel".into(), - archetype_field_name: Some("zoom".into()), - }] - }); + once_cell::sync::Lazy::new(|| [MapZoom::descriptor_zoom()]); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = - once_cell::sync::Lazy::new(|| { - [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.MapZoom".into()), - component_name: "rerun.blueprint.components.MapZoomIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.MapZoom".into()), - component_name: "rerun.blueprint.components.ZoomLevel".into(), - archetype_field_name: Some("zoom".into()), - }, - ] - }); + once_cell::sync::Lazy::new(|| [MapZoom::descriptor_indicator(), MapZoom::descriptor_zoom()]); impl MapZoom { /// The total number of components in the archetype: 0 required, 1 recommended, 1 optional @@ -147,11 +144,7 @@ impl ::re_types_core::AsComponents for MapZoom { (Some(&self.zoom as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.MapZoom".into()), - archetype_field_name: Some(("zoom").into()), - component_name: ("rerun.blueprint.components.ZoomLevel").into(), - }), + descriptor_override: Some(Self::descriptor_zoom()), } }), ] diff --git a/crates/store/re_types/src/blueprint/archetypes/near_clip_plane.rs b/crates/store/re_types/src/blueprint/archetypes/near_clip_plane.rs index 03f39a34cbb1..05723fd95ae5 100644 --- a/crates/store/re_types/src/blueprint/archetypes/near_clip_plane.rs +++ b/crates/store/re_types/src/blueprint/archetypes/near_clip_plane.rs @@ -27,40 +27,42 @@ pub struct NearClipPlane { pub near_clip_plane: crate::blueprint::components::NearClipPlane, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl NearClipPlane { + /// Returns the [`ComponentDescriptor`] for [`Self::near_clip_plane`]. + #[inline] + pub fn descriptor_near_clip_plane() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.NearClipPlane".into()), + component_name: "rerun.blueprint.components.NearClipPlane".into(), + archetype_field_name: Some("near_clip_plane".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.NearClipPlane".into()), component_name: "rerun.blueprint.components.NearClipPlaneIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [NearClipPlane::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.NearClipPlane".into()), - component_name: "rerun.blueprint.components.NearClipPlane".into(), - archetype_field_name: Some("near_clip_plane".into()), - }] - }); + once_cell::sync::Lazy::new(|| [NearClipPlane::descriptor_near_clip_plane()]); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.NearClipPlane".into()), - component_name: "rerun.blueprint.components.NearClipPlaneIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.NearClipPlane".into()), - component_name: "rerun.blueprint.components.NearClipPlane".into(), - archetype_field_name: Some("near_clip_plane".into()), - }, + NearClipPlane::descriptor_indicator(), + NearClipPlane::descriptor_near_clip_plane(), ] }); @@ -147,11 +149,7 @@ impl ::re_types_core::AsComponents for NearClipPlane { (Some(&self.near_clip_plane as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.NearClipPlane".into()), - archetype_field_name: Some(("near_clip_plane").into()), - component_name: ("rerun.blueprint.components.NearClipPlane").into(), - }), + descriptor_override: Some(Self::descriptor_near_clip_plane()), } }), ] diff --git a/crates/store/re_types/src/blueprint/archetypes/panel_blueprint.rs b/crates/store/re_types/src/blueprint/archetypes/panel_blueprint.rs index 2ce1e0a5b425..c4c35c395864 100644 --- a/crates/store/re_types/src/blueprint/archetypes/panel_blueprint.rs +++ b/crates/store/re_types/src/blueprint/archetypes/panel_blueprint.rs @@ -25,40 +25,42 @@ pub struct PanelBlueprint { pub state: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl PanelBlueprint { + /// Returns the [`ComponentDescriptor`] for [`Self::state`]. + #[inline] + pub fn descriptor_state() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.PanelBlueprint".into()), + component_name: "rerun.blueprint.components.PanelState".into(), + archetype_field_name: Some("state".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.PanelBlueprint".into()), component_name: "rerun.blueprint.components.PanelBlueprintIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [PanelBlueprint::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.PanelBlueprint".into()), - component_name: "rerun.blueprint.components.PanelState".into(), - archetype_field_name: Some("state".into()), - }] - }); + once_cell::sync::Lazy::new(|| [PanelBlueprint::descriptor_state()]); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.PanelBlueprint".into()), - component_name: "rerun.blueprint.components.PanelBlueprintIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.PanelBlueprint".into()), - component_name: "rerun.blueprint.components.PanelState".into(), - archetype_field_name: Some("state".into()), - }, + PanelBlueprint::descriptor_indicator(), + PanelBlueprint::descriptor_state(), ] }); @@ -145,11 +147,7 @@ impl ::re_types_core::AsComponents for PanelBlueprint { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.PanelBlueprint".into()), - archetype_field_name: Some(("state").into()), - component_name: ("rerun.blueprint.components.PanelState").into(), - }), + descriptor_override: Some(Self::descriptor_state()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/plot_legend.rs b/crates/store/re_types/src/blueprint/archetypes/plot_legend.rs index 3bc0e6dd283f..80fc8b5264ec 100644 --- a/crates/store/re_types/src/blueprint/archetypes/plot_legend.rs +++ b/crates/store/re_types/src/blueprint/archetypes/plot_legend.rs @@ -32,52 +32,58 @@ pub struct PlotLegend { pub visible: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl PlotLegend { + /// Returns the [`ComponentDescriptor`] for [`Self::corner`]. + #[inline] + pub fn descriptor_corner() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.PlotLegend".into()), + component_name: "rerun.blueprint.components.Corner2D".into(), + archetype_field_name: Some("corner".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::visible`]. + #[inline] + pub fn descriptor_visible() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.PlotLegend".into()), + component_name: "rerun.blueprint.components.Visible".into(), + archetype_field_name: Some("visible".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.PlotLegend".into()), component_name: "rerun.blueprint.components.PlotLegendIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [PlotLegend::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.PlotLegend".into()), - component_name: "rerun.blueprint.components.Corner2D".into(), - archetype_field_name: Some("corner".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.PlotLegend".into()), - component_name: "rerun.blueprint.components.Visible".into(), - archetype_field_name: Some("visible".into()), - }, + PlotLegend::descriptor_corner(), + PlotLegend::descriptor_visible(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.PlotLegend".into()), - component_name: "rerun.blueprint.components.PlotLegendIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.PlotLegend".into()), - component_name: "rerun.blueprint.components.Corner2D".into(), - archetype_field_name: Some("corner".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.PlotLegend".into()), - component_name: "rerun.blueprint.components.Visible".into(), - archetype_field_name: Some("visible".into()), - }, + PlotLegend::descriptor_indicator(), + PlotLegend::descriptor_corner(), + PlotLegend::descriptor_visible(), ] }); @@ -174,11 +180,7 @@ impl ::re_types_core::AsComponents for PlotLegend { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.PlotLegend".into()), - archetype_field_name: Some(("corner").into()), - component_name: ("rerun.blueprint.components.Corner2D").into(), - }), + descriptor_override: Some(Self::descriptor_corner()), }), (self .visible @@ -186,11 +188,7 @@ impl ::re_types_core::AsComponents for PlotLegend { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.PlotLegend".into()), - archetype_field_name: Some(("visible").into()), - component_name: ("rerun.blueprint.components.Visible").into(), - }), + descriptor_override: Some(Self::descriptor_visible()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/scalar_axis.rs b/crates/store/re_types/src/blueprint/archetypes/scalar_axis.rs index 34d1df5363e7..01c01dac3cf0 100644 --- a/crates/store/re_types/src/blueprint/archetypes/scalar_axis.rs +++ b/crates/store/re_types/src/blueprint/archetypes/scalar_axis.rs @@ -30,52 +30,58 @@ pub struct ScalarAxis { pub zoom_lock: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl ScalarAxis { + /// Returns the [`ComponentDescriptor`] for [`Self::range`]. + #[inline] + pub fn descriptor_range() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ScalarAxis".into()), + component_name: "rerun.components.Range1D".into(), + archetype_field_name: Some("range".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::zoom_lock`]. + #[inline] + pub fn descriptor_zoom_lock() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ScalarAxis".into()), + component_name: "rerun.blueprint.components.LockRangeDuringZoom".into(), + archetype_field_name: Some("zoom_lock".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.ScalarAxis".into()), component_name: "rerun.blueprint.components.ScalarAxisIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [ScalarAxis::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ScalarAxis".into()), - component_name: "rerun.components.Range1D".into(), - archetype_field_name: Some("range".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ScalarAxis".into()), - component_name: "rerun.blueprint.components.LockRangeDuringZoom".into(), - archetype_field_name: Some("zoom_lock".into()), - }, + ScalarAxis::descriptor_range(), + ScalarAxis::descriptor_zoom_lock(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ScalarAxis".into()), - component_name: "rerun.blueprint.components.ScalarAxisIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ScalarAxis".into()), - component_name: "rerun.components.Range1D".into(), - archetype_field_name: Some("range".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ScalarAxis".into()), - component_name: "rerun.blueprint.components.LockRangeDuringZoom".into(), - archetype_field_name: Some("zoom_lock".into()), - }, + ScalarAxis::descriptor_indicator(), + ScalarAxis::descriptor_range(), + ScalarAxis::descriptor_zoom_lock(), ] }); @@ -172,11 +178,7 @@ impl ::re_types_core::AsComponents for ScalarAxis { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ScalarAxis".into()), - archetype_field_name: Some(("range").into()), - component_name: ("rerun.components.Range1D").into(), - }), + descriptor_override: Some(Self::descriptor_range()), }), (self .zoom_lock @@ -184,11 +186,7 @@ impl ::re_types_core::AsComponents for ScalarAxis { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ScalarAxis".into()), - archetype_field_name: Some(("zoom_lock").into()), - component_name: ("rerun.blueprint.components.LockRangeDuringZoom").into(), - }), + descriptor_override: Some(Self::descriptor_zoom_lock()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs b/crates/store/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs index 00b364f35a53..a1f0184f682b 100644 --- a/crates/store/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs +++ b/crates/store/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs @@ -39,62 +39,70 @@ pub struct TensorScalarMapping { pub gamma: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl TensorScalarMapping { + /// Returns the [`ComponentDescriptor`] for [`Self::mag_filter`]. + #[inline] + pub fn descriptor_mag_filter() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.TensorScalarMapping".into()), + component_name: "rerun.components.MagnificationFilter".into(), + archetype_field_name: Some("mag_filter".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::colormap`]. + #[inline] + pub fn descriptor_colormap() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.TensorScalarMapping".into()), + component_name: "rerun.components.Colormap".into(), + archetype_field_name: Some("colormap".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::gamma`]. + #[inline] + pub fn descriptor_gamma() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.TensorScalarMapping".into()), + component_name: "rerun.components.GammaCorrection".into(), + archetype_field_name: Some("gamma".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.TensorScalarMapping".into()), component_name: "rerun.blueprint.components.TensorScalarMappingIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [TensorScalarMapping::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorScalarMapping".into()), - component_name: "rerun.components.MagnificationFilter".into(), - archetype_field_name: Some("mag_filter".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorScalarMapping".into()), - component_name: "rerun.components.Colormap".into(), - archetype_field_name: Some("colormap".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorScalarMapping".into()), - component_name: "rerun.components.GammaCorrection".into(), - archetype_field_name: Some("gamma".into()), - }, + TensorScalarMapping::descriptor_mag_filter(), + TensorScalarMapping::descriptor_colormap(), + TensorScalarMapping::descriptor_gamma(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 4usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorScalarMapping".into()), - component_name: "rerun.blueprint.components.TensorScalarMappingIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorScalarMapping".into()), - component_name: "rerun.components.MagnificationFilter".into(), - archetype_field_name: Some("mag_filter".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorScalarMapping".into()), - component_name: "rerun.components.Colormap".into(), - archetype_field_name: Some("colormap".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorScalarMapping".into()), - component_name: "rerun.components.GammaCorrection".into(), - archetype_field_name: Some("gamma".into()), - }, + TensorScalarMapping::descriptor_indicator(), + TensorScalarMapping::descriptor_mag_filter(), + TensorScalarMapping::descriptor_colormap(), + TensorScalarMapping::descriptor_gamma(), ] }); @@ -204,11 +212,7 @@ impl ::re_types_core::AsComponents for TensorScalarMapping { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorScalarMapping".into()), - archetype_field_name: Some(("mag_filter").into()), - component_name: ("rerun.components.MagnificationFilter").into(), - }), + descriptor_override: Some(Self::descriptor_mag_filter()), }), (self .colormap @@ -216,11 +220,7 @@ impl ::re_types_core::AsComponents for TensorScalarMapping { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorScalarMapping".into()), - archetype_field_name: Some(("colormap").into()), - component_name: ("rerun.components.Colormap").into(), - }), + descriptor_override: Some(Self::descriptor_colormap()), }), (self .gamma @@ -228,11 +228,7 @@ impl ::re_types_core::AsComponents for TensorScalarMapping { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorScalarMapping".into()), - archetype_field_name: Some(("gamma").into()), - component_name: ("rerun.components.GammaCorrection").into(), - }), + descriptor_override: Some(Self::descriptor_gamma()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/tensor_slice_selection.rs b/crates/store/re_types/src/blueprint/archetypes/tensor_slice_selection.rs index 1ce28f62acb2..bca8e2b67533 100644 --- a/crates/store/re_types/src/blueprint/archetypes/tensor_slice_selection.rs +++ b/crates/store/re_types/src/blueprint/archetypes/tensor_slice_selection.rs @@ -44,72 +44,82 @@ pub struct TensorSliceSelection { pub slider: Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl TensorSliceSelection { + /// Returns the [`ComponentDescriptor`] for [`Self::width`]. + #[inline] + pub fn descriptor_width() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), + component_name: "rerun.components.TensorWidthDimension".into(), + archetype_field_name: Some("width".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::height`]. + #[inline] + pub fn descriptor_height() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), + component_name: "rerun.components.TensorHeightDimension".into(), + archetype_field_name: Some("height".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::indices`]. + #[inline] + pub fn descriptor_indices() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), + component_name: "rerun.components.TensorDimensionIndexSelection".into(), + archetype_field_name: Some("indices".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::slider`]. + #[inline] + pub fn descriptor_slider() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), + component_name: "rerun.blueprint.components.TensorDimensionIndexSlider".into(), + archetype_field_name: Some("slider".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), component_name: "rerun.blueprint.components.TensorSliceSelectionIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [TensorSliceSelection::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 4usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), - component_name: "rerun.components.TensorWidthDimension".into(), - archetype_field_name: Some("width".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), - component_name: "rerun.components.TensorHeightDimension".into(), - archetype_field_name: Some("height".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), - component_name: "rerun.components.TensorDimensionIndexSelection".into(), - archetype_field_name: Some("indices".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), - component_name: "rerun.blueprint.components.TensorDimensionIndexSlider".into(), - archetype_field_name: Some("slider".into()), - }, + TensorSliceSelection::descriptor_width(), + TensorSliceSelection::descriptor_height(), + TensorSliceSelection::descriptor_indices(), + TensorSliceSelection::descriptor_slider(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), - component_name: "rerun.blueprint.components.TensorSliceSelectionIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), - component_name: "rerun.components.TensorWidthDimension".into(), - archetype_field_name: Some("width".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), - component_name: "rerun.components.TensorHeightDimension".into(), - archetype_field_name: Some("height".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), - component_name: "rerun.components.TensorDimensionIndexSelection".into(), - archetype_field_name: Some("indices".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), - component_name: "rerun.blueprint.components.TensorDimensionIndexSlider".into(), - archetype_field_name: Some("slider".into()), - }, + TensorSliceSelection::descriptor_indicator(), + TensorSliceSelection::descriptor_width(), + TensorSliceSelection::descriptor_height(), + TensorSliceSelection::descriptor_indices(), + TensorSliceSelection::descriptor_slider(), ] }); @@ -240,11 +250,7 @@ impl ::re_types_core::AsComponents for TensorSliceSelection { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), - archetype_field_name: Some(("width").into()), - component_name: ("rerun.components.TensorWidthDimension").into(), - }), + descriptor_override: Some(Self::descriptor_width()), }), (self .height @@ -252,11 +258,7 @@ impl ::re_types_core::AsComponents for TensorSliceSelection { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), - archetype_field_name: Some(("height").into()), - component_name: ("rerun.components.TensorHeightDimension").into(), - }), + descriptor_override: Some(Self::descriptor_height()), }), (self .indices @@ -264,11 +266,7 @@ impl ::re_types_core::AsComponents for TensorSliceSelection { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), - archetype_field_name: Some(("indices").into()), - component_name: ("rerun.components.TensorDimensionIndexSelection").into(), - }), + descriptor_override: Some(Self::descriptor_indices()), }), (self .slider @@ -276,12 +274,7 @@ impl ::re_types_core::AsComponents for TensorSliceSelection { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorSliceSelection".into()), - archetype_field_name: Some(("slider").into()), - component_name: ("rerun.blueprint.components.TensorDimensionIndexSlider") - .into(), - }), + descriptor_override: Some(Self::descriptor_slider()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/tensor_view_fit.rs b/crates/store/re_types/src/blueprint/archetypes/tensor_view_fit.rs index 49bb6a637775..3919fefdcab0 100644 --- a/crates/store/re_types/src/blueprint/archetypes/tensor_view_fit.rs +++ b/crates/store/re_types/src/blueprint/archetypes/tensor_view_fit.rs @@ -25,40 +25,42 @@ pub struct TensorViewFit { pub scaling: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl TensorViewFit { + /// Returns the [`ComponentDescriptor`] for [`Self::scaling`]. + #[inline] + pub fn descriptor_scaling() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.TensorViewFit".into()), + component_name: "rerun.blueprint.components.ViewFit".into(), + archetype_field_name: Some("scaling".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.TensorViewFit".into()), component_name: "rerun.blueprint.components.TensorViewFitIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [TensorViewFit::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorViewFit".into()), - component_name: "rerun.blueprint.components.ViewFit".into(), - archetype_field_name: Some("scaling".into()), - }] - }); + once_cell::sync::Lazy::new(|| [TensorViewFit::descriptor_scaling()]); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorViewFit".into()), - component_name: "rerun.blueprint.components.TensorViewFitIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorViewFit".into()), - component_name: "rerun.blueprint.components.ViewFit".into(), - archetype_field_name: Some("scaling".into()), - }, + TensorViewFit::descriptor_indicator(), + TensorViewFit::descriptor_scaling(), ] }); @@ -145,11 +147,7 @@ impl ::re_types_core::AsComponents for TensorViewFit { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.TensorViewFit".into()), - archetype_field_name: Some(("scaling").into()), - component_name: ("rerun.blueprint.components.ViewFit").into(), - }), + descriptor_override: Some(Self::descriptor_scaling()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/view_blueprint.rs b/crates/store/re_types/src/blueprint/archetypes/view_blueprint.rs index b359791c7180..53cbda7545e4 100644 --- a/crates/store/re_types/src/blueprint/archetypes/view_blueprint.rs +++ b/crates/store/re_types/src/blueprint/archetypes/view_blueprint.rs @@ -42,73 +42,81 @@ pub struct ViewBlueprint { pub visible: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl ViewBlueprint { + /// Returns the [`ComponentDescriptor`] for [`Self::class_identifier`]. + #[inline] + pub fn descriptor_class_identifier() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), component_name: "rerun.blueprint.components.ViewClass".into(), archetype_field_name: Some("class_identifier".into()), - }] - }); + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::display_name`]. + #[inline] + pub fn descriptor_display_name() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), + component_name: "rerun.components.Name".into(), + archetype_field_name: Some("display_name".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::space_origin`]. + #[inline] + pub fn descriptor_space_origin() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), + component_name: "rerun.blueprint.components.ViewOrigin".into(), + archetype_field_name: Some("space_origin".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::visible`]. + #[inline] + pub fn descriptor_visible() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), + component_name: "rerun.blueprint.components.Visible".into(), + archetype_field_name: Some("visible".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), component_name: "rerun.blueprint.components.ViewBlueprintIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [ViewBlueprint::descriptor_class_identifier()]); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [ViewBlueprint::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 3usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), - component_name: "rerun.components.Name".into(), - archetype_field_name: Some("display_name".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), - component_name: "rerun.blueprint.components.ViewOrigin".into(), - archetype_field_name: Some("space_origin".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), - component_name: "rerun.blueprint.components.Visible".into(), - archetype_field_name: Some("visible".into()), - }, + ViewBlueprint::descriptor_display_name(), + ViewBlueprint::descriptor_space_origin(), + ViewBlueprint::descriptor_visible(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), - component_name: "rerun.blueprint.components.ViewClass".into(), - archetype_field_name: Some("class_identifier".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), - component_name: "rerun.blueprint.components.ViewBlueprintIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), - component_name: "rerun.components.Name".into(), - archetype_field_name: Some("display_name".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), - component_name: "rerun.blueprint.components.ViewOrigin".into(), - archetype_field_name: Some("space_origin".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), - component_name: "rerun.blueprint.components.Visible".into(), - archetype_field_name: Some("visible".into()), - }, + ViewBlueprint::descriptor_class_identifier(), + ViewBlueprint::descriptor_indicator(), + ViewBlueprint::descriptor_display_name(), + ViewBlueprint::descriptor_space_origin(), + ViewBlueprint::descriptor_visible(), ] }); @@ -229,11 +237,7 @@ impl ::re_types_core::AsComponents for ViewBlueprint { (Some(&self.class_identifier as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), - archetype_field_name: Some(("class_identifier").into()), - component_name: ("rerun.blueprint.components.ViewClass").into(), - }), + descriptor_override: Some(Self::descriptor_class_identifier()), } }), (self @@ -242,11 +246,7 @@ impl ::re_types_core::AsComponents for ViewBlueprint { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), - archetype_field_name: Some(("display_name").into()), - component_name: ("rerun.components.Name").into(), - }), + descriptor_override: Some(Self::descriptor_display_name()), }), (self .space_origin @@ -254,11 +254,7 @@ impl ::re_types_core::AsComponents for ViewBlueprint { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), - archetype_field_name: Some(("space_origin").into()), - component_name: ("rerun.blueprint.components.ViewOrigin").into(), - }), + descriptor_override: Some(Self::descriptor_space_origin()), }), (self .visible @@ -266,11 +262,7 @@ impl ::re_types_core::AsComponents for ViewBlueprint { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewBlueprint".into()), - archetype_field_name: Some(("visible").into()), - component_name: ("rerun.blueprint.components.Visible").into(), - }), + descriptor_override: Some(Self::descriptor_visible()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/view_contents.rs b/crates/store/re_types/src/blueprint/archetypes/view_contents.rs index bd31494581a6..265ac29c00a3 100644 --- a/crates/store/re_types/src/blueprint/archetypes/view_contents.rs +++ b/crates/store/re_types/src/blueprint/archetypes/view_contents.rs @@ -64,40 +64,42 @@ pub struct ViewContents { pub query: Vec, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl ViewContents { + /// Returns the [`ComponentDescriptor`] for [`Self::query`]. + #[inline] + pub fn descriptor_query() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ViewContents".into()), + component_name: "rerun.blueprint.components.QueryExpression".into(), + archetype_field_name: Some("query".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.ViewContents".into()), component_name: "rerun.blueprint.components.ViewContentsIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [ViewContents::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewContents".into()), - component_name: "rerun.blueprint.components.QueryExpression".into(), - archetype_field_name: Some("query".into()), - }] - }); + once_cell::sync::Lazy::new(|| [ViewContents::descriptor_query()]); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewContents".into()), - component_name: "rerun.blueprint.components.ViewContentsIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewContents".into()), - component_name: "rerun.blueprint.components.QueryExpression".into(), - archetype_field_name: Some("query".into()), - }, + ViewContents::descriptor_indicator(), + ViewContents::descriptor_query(), ] }); @@ -183,11 +185,7 @@ impl ::re_types_core::AsComponents for ViewContents { (Some(&self.query as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewContents".into()), - archetype_field_name: Some(("query").into()), - component_name: ("rerun.blueprint.components.QueryExpression").into(), - }), + descriptor_override: Some(Self::descriptor_query()), } }), ] diff --git a/crates/store/re_types/src/blueprint/archetypes/viewport_blueprint.rs b/crates/store/re_types/src/blueprint/archetypes/viewport_blueprint.rs index eb2ebf57770c..e200f3a6d3e6 100644 --- a/crates/store/re_types/src/blueprint/archetypes/viewport_blueprint.rs +++ b/crates/store/re_types/src/blueprint/archetypes/viewport_blueprint.rs @@ -50,82 +50,94 @@ pub struct ViewportBlueprint { Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl ViewportBlueprint { + /// Returns the [`ComponentDescriptor`] for [`Self::root_container`]. + #[inline] + pub fn descriptor_root_container() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), + component_name: "rerun.blueprint.components.RootContainer".into(), + archetype_field_name: Some("root_container".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::maximized`]. + #[inline] + pub fn descriptor_maximized() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), + component_name: "rerun.blueprint.components.ViewMaximized".into(), + archetype_field_name: Some("maximized".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::auto_layout`]. + #[inline] + pub fn descriptor_auto_layout() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), + component_name: "rerun.blueprint.components.AutoLayout".into(), + archetype_field_name: Some("auto_layout".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::auto_views`]. + #[inline] + pub fn descriptor_auto_views() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), + component_name: "rerun.blueprint.components.AutoViews".into(), + archetype_field_name: Some("auto_views".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::past_viewer_recommendations`]. + #[inline] + pub fn descriptor_past_viewer_recommendations() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), + component_name: "rerun.blueprint.components.ViewerRecommendationHash".into(), + archetype_field_name: Some("past_viewer_recommendations".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), component_name: "rerun.blueprint.components.ViewportBlueprintIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [ViewportBlueprint::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 5usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), - component_name: "rerun.blueprint.components.RootContainer".into(), - archetype_field_name: Some("root_container".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), - component_name: "rerun.blueprint.components.ViewMaximized".into(), - archetype_field_name: Some("maximized".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), - component_name: "rerun.blueprint.components.AutoLayout".into(), - archetype_field_name: Some("auto_layout".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), - component_name: "rerun.blueprint.components.AutoViews".into(), - archetype_field_name: Some("auto_views".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), - component_name: "rerun.blueprint.components.ViewerRecommendationHash".into(), - archetype_field_name: Some("past_viewer_recommendations".into()), - }, + ViewportBlueprint::descriptor_root_container(), + ViewportBlueprint::descriptor_maximized(), + ViewportBlueprint::descriptor_auto_layout(), + ViewportBlueprint::descriptor_auto_views(), + ViewportBlueprint::descriptor_past_viewer_recommendations(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 6usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), - component_name: "rerun.blueprint.components.ViewportBlueprintIndicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), - component_name: "rerun.blueprint.components.RootContainer".into(), - archetype_field_name: Some("root_container".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), - component_name: "rerun.blueprint.components.ViewMaximized".into(), - archetype_field_name: Some("maximized".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), - component_name: "rerun.blueprint.components.AutoLayout".into(), - archetype_field_name: Some("auto_layout".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), - component_name: "rerun.blueprint.components.AutoViews".into(), - archetype_field_name: Some("auto_views".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), - component_name: "rerun.blueprint.components.ViewerRecommendationHash".into(), - archetype_field_name: Some("past_viewer_recommendations".into()), - }, + ViewportBlueprint::descriptor_indicator(), + ViewportBlueprint::descriptor_root_container(), + ViewportBlueprint::descriptor_maximized(), + ViewportBlueprint::descriptor_auto_layout(), + ViewportBlueprint::descriptor_auto_views(), + ViewportBlueprint::descriptor_past_viewer_recommendations(), ] }); @@ -266,11 +278,7 @@ impl ::re_types_core::AsComponents for ViewportBlueprint { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), - archetype_field_name: Some(("root_container").into()), - component_name: ("rerun.blueprint.components.RootContainer").into(), - }), + descriptor_override: Some(Self::descriptor_root_container()), }), (self .maximized @@ -278,11 +286,7 @@ impl ::re_types_core::AsComponents for ViewportBlueprint { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), - archetype_field_name: Some(("maximized").into()), - component_name: ("rerun.blueprint.components.ViewMaximized").into(), - }), + descriptor_override: Some(Self::descriptor_maximized()), }), (self .auto_layout @@ -290,11 +294,7 @@ impl ::re_types_core::AsComponents for ViewportBlueprint { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), - archetype_field_name: Some(("auto_layout").into()), - component_name: ("rerun.blueprint.components.AutoLayout").into(), - }), + descriptor_override: Some(Self::descriptor_auto_layout()), }), (self .auto_views @@ -302,11 +302,7 @@ impl ::re_types_core::AsComponents for ViewportBlueprint { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), - archetype_field_name: Some(("auto_views").into()), - component_name: ("rerun.blueprint.components.AutoViews").into(), - }), + descriptor_override: Some(Self::descriptor_auto_views()), }), (self .past_viewer_recommendations @@ -314,11 +310,7 @@ impl ::re_types_core::AsComponents for ViewportBlueprint { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.ViewportBlueprint".into()), - archetype_field_name: Some(("past_viewer_recommendations").into()), - component_name: ("rerun.blueprint.components.ViewerRecommendationHash").into(), - }), + descriptor_override: Some(Self::descriptor_past_viewer_recommendations()), }), ] .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges.rs b/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges.rs index b3b3c570c8e8..49fb6c94bcb9 100644 --- a/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges.rs +++ b/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges.rs @@ -35,23 +35,33 @@ pub struct VisibleTimeRanges { pub ranges: Vec, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl VisibleTimeRanges { + /// Returns the [`ComponentDescriptor`] for [`Self::ranges`]. + #[inline] + pub fn descriptor_ranges() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.VisibleTimeRanges".into()), component_name: "rerun.blueprint.components.VisibleTimeRange".into(), archetype_field_name: Some("ranges".into()), - }] - }); + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.VisibleTimeRanges".into()), component_name: "rerun.blueprint.components.VisibleTimeRangesIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [VisibleTimeRanges::descriptor_ranges()]); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [VisibleTimeRanges::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = once_cell::sync::Lazy::new(|| []); @@ -59,16 +69,8 @@ static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.VisibleTimeRanges".into()), - component_name: "rerun.blueprint.components.VisibleTimeRange".into(), - archetype_field_name: Some("ranges".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.VisibleTimeRanges".into()), - component_name: "rerun.blueprint.components.VisibleTimeRangesIndicator".into(), - archetype_field_name: None, - }, + VisibleTimeRanges::descriptor_ranges(), + VisibleTimeRanges::descriptor_indicator(), ] }); @@ -154,11 +156,7 @@ impl ::re_types_core::AsComponents for VisibleTimeRanges { (Some(&self.ranges as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.VisibleTimeRanges".into()), - archetype_field_name: Some(("ranges").into()), - component_name: ("rerun.blueprint.components.VisibleTimeRange").into(), - }), + descriptor_override: Some(Self::descriptor_ranges()), } }), ] diff --git a/crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs b/crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs index 94139e2940aa..d89e5ca63cf2 100644 --- a/crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs +++ b/crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs @@ -33,23 +33,33 @@ pub struct VisualBounds2D { pub range: crate::blueprint::components::VisualBounds2D, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl VisualBounds2D { + /// Returns the [`ComponentDescriptor`] for [`Self::range`]. + #[inline] + pub fn descriptor_range() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.VisualBounds2D".into()), component_name: "rerun.blueprint.components.VisualBounds2D".into(), archetype_field_name: Some("range".into()), - }] - }); + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.blueprint.archetypes.VisualBounds2D".into()), component_name: "rerun.blueprint.components.VisualBounds2DIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [VisualBounds2D::descriptor_range()]); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [VisualBounds2D::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = once_cell::sync::Lazy::new(|| []); @@ -57,16 +67,8 @@ static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.VisualBounds2D".into()), - component_name: "rerun.blueprint.components.VisualBounds2D".into(), - archetype_field_name: Some("range".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.VisualBounds2D".into()), - component_name: "rerun.blueprint.components.VisualBounds2DIndicator".into(), - archetype_field_name: None, - }, + VisualBounds2D::descriptor_range(), + VisualBounds2D::descriptor_indicator(), ] }); @@ -153,11 +155,7 @@ impl ::re_types_core::AsComponents for VisualBounds2D { (Some(&self.range as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.blueprint.archetypes.VisualBounds2D".into()), - archetype_field_name: Some(("range").into()), - component_name: ("rerun.blueprint.components.VisualBounds2D").into(), - }), + descriptor_override: Some(Self::descriptor_range()), } }), ] diff --git a/crates/store/re_types/src/testing/archetypes/affix_fuzzer1.rs b/crates/store/re_types/src/testing/archetypes/affix_fuzzer1.rs index 118d5ec1408d..d0cce34b18ae 100644 --- a/crates/store/re_types/src/testing/archetypes/affix_fuzzer1.rs +++ b/crates/store/re_types/src/testing/archetypes/affix_fuzzer1.rs @@ -44,130 +44,268 @@ pub struct AffixFuzzer1 { pub fuzz1022: crate::testing::components::AffixFuzzer22, } +impl AffixFuzzer1 { + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1001`]. + #[inline] + pub fn descriptor_fuzz1001() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer1".into(), + archetype_field_name: Some("fuzz1001".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1002`]. + #[inline] + pub fn descriptor_fuzz1002() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer2".into(), + archetype_field_name: Some("fuzz1002".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1003`]. + #[inline] + pub fn descriptor_fuzz1003() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer3".into(), + archetype_field_name: Some("fuzz1003".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1004`]. + #[inline] + pub fn descriptor_fuzz1004() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer4".into(), + archetype_field_name: Some("fuzz1004".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1005`]. + #[inline] + pub fn descriptor_fuzz1005() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer5".into(), + archetype_field_name: Some("fuzz1005".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1006`]. + #[inline] + pub fn descriptor_fuzz1006() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer6".into(), + archetype_field_name: Some("fuzz1006".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1007`]. + #[inline] + pub fn descriptor_fuzz1007() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer7".into(), + archetype_field_name: Some("fuzz1007".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1008`]. + #[inline] + pub fn descriptor_fuzz1008() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer8".into(), + archetype_field_name: Some("fuzz1008".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1009`]. + #[inline] + pub fn descriptor_fuzz1009() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer9".into(), + archetype_field_name: Some("fuzz1009".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1010`]. + #[inline] + pub fn descriptor_fuzz1010() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer10".into(), + archetype_field_name: Some("fuzz1010".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1011`]. + #[inline] + pub fn descriptor_fuzz1011() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer11".into(), + archetype_field_name: Some("fuzz1011".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1012`]. + #[inline] + pub fn descriptor_fuzz1012() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer12".into(), + archetype_field_name: Some("fuzz1012".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1013`]. + #[inline] + pub fn descriptor_fuzz1013() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer13".into(), + archetype_field_name: Some("fuzz1013".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1014`]. + #[inline] + pub fn descriptor_fuzz1014() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer14".into(), + archetype_field_name: Some("fuzz1014".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1015`]. + #[inline] + pub fn descriptor_fuzz1015() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer15".into(), + archetype_field_name: Some("fuzz1015".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1016`]. + #[inline] + pub fn descriptor_fuzz1016() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer16".into(), + archetype_field_name: Some("fuzz1016".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1017`]. + #[inline] + pub fn descriptor_fuzz1017() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer17".into(), + archetype_field_name: Some("fuzz1017".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1018`]. + #[inline] + pub fn descriptor_fuzz1018() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer18".into(), + archetype_field_name: Some("fuzz1018".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1019`]. + #[inline] + pub fn descriptor_fuzz1019() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer19".into(), + archetype_field_name: Some("fuzz1019".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1020`]. + #[inline] + pub fn descriptor_fuzz1020() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer20".into(), + archetype_field_name: Some("fuzz1020".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1021`]. + #[inline] + pub fn descriptor_fuzz1021() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer21".into(), + archetype_field_name: Some("fuzz1021".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1022`]. + #[inline] + pub fn descriptor_fuzz1022() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer22".into(), + archetype_field_name: Some("fuzz1022".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), + component_name: "rerun.testing.components.AffixFuzzer1Indicator".into(), + archetype_field_name: None, + } + } +} + static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 22usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer1".into(), - archetype_field_name: Some("fuzz1001".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer2".into(), - archetype_field_name: Some("fuzz1002".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer3".into(), - archetype_field_name: Some("fuzz1003".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer4".into(), - archetype_field_name: Some("fuzz1004".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer5".into(), - archetype_field_name: Some("fuzz1005".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer6".into(), - archetype_field_name: Some("fuzz1006".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer7".into(), - archetype_field_name: Some("fuzz1007".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer8".into(), - archetype_field_name: Some("fuzz1008".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer9".into(), - archetype_field_name: Some("fuzz1009".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer10".into(), - archetype_field_name: Some("fuzz1010".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer11".into(), - archetype_field_name: Some("fuzz1011".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer12".into(), - archetype_field_name: Some("fuzz1012".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer13".into(), - archetype_field_name: Some("fuzz1013".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer14".into(), - archetype_field_name: Some("fuzz1014".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer15".into(), - archetype_field_name: Some("fuzz1015".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer16".into(), - archetype_field_name: Some("fuzz1016".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer17".into(), - archetype_field_name: Some("fuzz1017".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer18".into(), - archetype_field_name: Some("fuzz1018".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer19".into(), - archetype_field_name: Some("fuzz1019".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer20".into(), - archetype_field_name: Some("fuzz1020".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer21".into(), - archetype_field_name: Some("fuzz1021".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer22".into(), - archetype_field_name: Some("fuzz1022".into()), - }, + AffixFuzzer1::descriptor_fuzz1001(), + AffixFuzzer1::descriptor_fuzz1002(), + AffixFuzzer1::descriptor_fuzz1003(), + AffixFuzzer1::descriptor_fuzz1004(), + AffixFuzzer1::descriptor_fuzz1005(), + AffixFuzzer1::descriptor_fuzz1006(), + AffixFuzzer1::descriptor_fuzz1007(), + AffixFuzzer1::descriptor_fuzz1008(), + AffixFuzzer1::descriptor_fuzz1009(), + AffixFuzzer1::descriptor_fuzz1010(), + AffixFuzzer1::descriptor_fuzz1011(), + AffixFuzzer1::descriptor_fuzz1012(), + AffixFuzzer1::descriptor_fuzz1013(), + AffixFuzzer1::descriptor_fuzz1014(), + AffixFuzzer1::descriptor_fuzz1015(), + AffixFuzzer1::descriptor_fuzz1016(), + AffixFuzzer1::descriptor_fuzz1017(), + AffixFuzzer1::descriptor_fuzz1018(), + AffixFuzzer1::descriptor_fuzz1019(), + AffixFuzzer1::descriptor_fuzz1020(), + AffixFuzzer1::descriptor_fuzz1021(), + AffixFuzzer1::descriptor_fuzz1022(), ] }); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer1Indicator".into(), - archetype_field_name: None, - }] - }); + once_cell::sync::Lazy::new(|| [AffixFuzzer1::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = once_cell::sync::Lazy::new(|| []); @@ -175,121 +313,29 @@ static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 23usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer1".into(), - archetype_field_name: Some("fuzz1001".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer2".into(), - archetype_field_name: Some("fuzz1002".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer3".into(), - archetype_field_name: Some("fuzz1003".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer4".into(), - archetype_field_name: Some("fuzz1004".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer5".into(), - archetype_field_name: Some("fuzz1005".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer6".into(), - archetype_field_name: Some("fuzz1006".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer7".into(), - archetype_field_name: Some("fuzz1007".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer8".into(), - archetype_field_name: Some("fuzz1008".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer9".into(), - archetype_field_name: Some("fuzz1009".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer10".into(), - archetype_field_name: Some("fuzz1010".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer11".into(), - archetype_field_name: Some("fuzz1011".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer12".into(), - archetype_field_name: Some("fuzz1012".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer13".into(), - archetype_field_name: Some("fuzz1013".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer14".into(), - archetype_field_name: Some("fuzz1014".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer15".into(), - archetype_field_name: Some("fuzz1015".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer16".into(), - archetype_field_name: Some("fuzz1016".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer17".into(), - archetype_field_name: Some("fuzz1017".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer18".into(), - archetype_field_name: Some("fuzz1018".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer19".into(), - archetype_field_name: Some("fuzz1019".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer20".into(), - archetype_field_name: Some("fuzz1020".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer21".into(), - archetype_field_name: Some("fuzz1021".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer22".into(), - archetype_field_name: Some("fuzz1022".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - component_name: "rerun.testing.components.AffixFuzzer1Indicator".into(), - archetype_field_name: None, - }, + AffixFuzzer1::descriptor_fuzz1001(), + AffixFuzzer1::descriptor_fuzz1002(), + AffixFuzzer1::descriptor_fuzz1003(), + AffixFuzzer1::descriptor_fuzz1004(), + AffixFuzzer1::descriptor_fuzz1005(), + AffixFuzzer1::descriptor_fuzz1006(), + AffixFuzzer1::descriptor_fuzz1007(), + AffixFuzzer1::descriptor_fuzz1008(), + AffixFuzzer1::descriptor_fuzz1009(), + AffixFuzzer1::descriptor_fuzz1010(), + AffixFuzzer1::descriptor_fuzz1011(), + AffixFuzzer1::descriptor_fuzz1012(), + AffixFuzzer1::descriptor_fuzz1013(), + AffixFuzzer1::descriptor_fuzz1014(), + AffixFuzzer1::descriptor_fuzz1015(), + AffixFuzzer1::descriptor_fuzz1016(), + AffixFuzzer1::descriptor_fuzz1017(), + AffixFuzzer1::descriptor_fuzz1018(), + AffixFuzzer1::descriptor_fuzz1019(), + AffixFuzzer1::descriptor_fuzz1020(), + AffixFuzzer1::descriptor_fuzz1021(), + AffixFuzzer1::descriptor_fuzz1022(), + AffixFuzzer1::descriptor_indicator(), ] }); @@ -672,221 +718,133 @@ impl ::re_types_core::AsComponents for AffixFuzzer1 { (Some(&self.fuzz1001 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1001").into()), - component_name: ("rerun.testing.components.AffixFuzzer1").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1001()), } }), (Some(&self.fuzz1002 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1002").into()), - component_name: ("rerun.testing.components.AffixFuzzer2").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1002()), } }), (Some(&self.fuzz1003 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1003").into()), - component_name: ("rerun.testing.components.AffixFuzzer3").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1003()), } }), (Some(&self.fuzz1004 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1004").into()), - component_name: ("rerun.testing.components.AffixFuzzer4").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1004()), } }), (Some(&self.fuzz1005 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1005").into()), - component_name: ("rerun.testing.components.AffixFuzzer5").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1005()), } }), (Some(&self.fuzz1006 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1006").into()), - component_name: ("rerun.testing.components.AffixFuzzer6").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1006()), } }), (Some(&self.fuzz1007 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1007").into()), - component_name: ("rerun.testing.components.AffixFuzzer7").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1007()), } }), (Some(&self.fuzz1008 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1008").into()), - component_name: ("rerun.testing.components.AffixFuzzer8").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1008()), } }), (Some(&self.fuzz1009 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1009").into()), - component_name: ("rerun.testing.components.AffixFuzzer9").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1009()), } }), (Some(&self.fuzz1010 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1010").into()), - component_name: ("rerun.testing.components.AffixFuzzer10").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1010()), } }), (Some(&self.fuzz1011 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1011").into()), - component_name: ("rerun.testing.components.AffixFuzzer11").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1011()), } }), (Some(&self.fuzz1012 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1012").into()), - component_name: ("rerun.testing.components.AffixFuzzer12").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1012()), } }), (Some(&self.fuzz1013 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1013").into()), - component_name: ("rerun.testing.components.AffixFuzzer13").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1013()), } }), (Some(&self.fuzz1014 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1014").into()), - component_name: ("rerun.testing.components.AffixFuzzer14").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1014()), } }), (Some(&self.fuzz1015 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1015").into()), - component_name: ("rerun.testing.components.AffixFuzzer15").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1015()), } }), (Some(&self.fuzz1016 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1016").into()), - component_name: ("rerun.testing.components.AffixFuzzer16").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1016()), } }), (Some(&self.fuzz1017 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1017").into()), - component_name: ("rerun.testing.components.AffixFuzzer17").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1017()), } }), (Some(&self.fuzz1018 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1018").into()), - component_name: ("rerun.testing.components.AffixFuzzer18").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1018()), } }), (Some(&self.fuzz1019 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1019").into()), - component_name: ("rerun.testing.components.AffixFuzzer19").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1019()), } }), (Some(&self.fuzz1020 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1020").into()), - component_name: ("rerun.testing.components.AffixFuzzer20").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1020()), } }), (Some(&self.fuzz1021 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1021").into()), - component_name: ("rerun.testing.components.AffixFuzzer21").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1021()), } }), (Some(&self.fuzz1022 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer1".into()), - archetype_field_name: Some(("fuzz1022").into()), - component_name: ("rerun.testing.components.AffixFuzzer22").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1022()), } }), ] diff --git a/crates/store/re_types/src/testing/archetypes/affix_fuzzer2.rs b/crates/store/re_types/src/testing/archetypes/affix_fuzzer2.rs index 334c84d1d3cf..7fea451d8505 100644 --- a/crates/store/re_types/src/testing/archetypes/affix_fuzzer2.rs +++ b/crates/store/re_types/src/testing/archetypes/affix_fuzzer2.rs @@ -41,115 +41,235 @@ pub struct AffixFuzzer2 { pub fuzz1122: Vec, } +impl AffixFuzzer2 { + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1101`]. + #[inline] + pub fn descriptor_fuzz1101() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer1".into(), + archetype_field_name: Some("fuzz1101".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1102`]. + #[inline] + pub fn descriptor_fuzz1102() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer2".into(), + archetype_field_name: Some("fuzz1102".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1103`]. + #[inline] + pub fn descriptor_fuzz1103() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer3".into(), + archetype_field_name: Some("fuzz1103".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1104`]. + #[inline] + pub fn descriptor_fuzz1104() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer4".into(), + archetype_field_name: Some("fuzz1104".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1105`]. + #[inline] + pub fn descriptor_fuzz1105() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer5".into(), + archetype_field_name: Some("fuzz1105".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1106`]. + #[inline] + pub fn descriptor_fuzz1106() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer6".into(), + archetype_field_name: Some("fuzz1106".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1107`]. + #[inline] + pub fn descriptor_fuzz1107() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer7".into(), + archetype_field_name: Some("fuzz1107".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1108`]. + #[inline] + pub fn descriptor_fuzz1108() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer8".into(), + archetype_field_name: Some("fuzz1108".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1109`]. + #[inline] + pub fn descriptor_fuzz1109() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer9".into(), + archetype_field_name: Some("fuzz1109".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1110`]. + #[inline] + pub fn descriptor_fuzz1110() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer10".into(), + archetype_field_name: Some("fuzz1110".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1111`]. + #[inline] + pub fn descriptor_fuzz1111() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer11".into(), + archetype_field_name: Some("fuzz1111".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1112`]. + #[inline] + pub fn descriptor_fuzz1112() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer12".into(), + archetype_field_name: Some("fuzz1112".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1113`]. + #[inline] + pub fn descriptor_fuzz1113() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer13".into(), + archetype_field_name: Some("fuzz1113".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1114`]. + #[inline] + pub fn descriptor_fuzz1114() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer14".into(), + archetype_field_name: Some("fuzz1114".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1115`]. + #[inline] + pub fn descriptor_fuzz1115() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer15".into(), + archetype_field_name: Some("fuzz1115".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1116`]. + #[inline] + pub fn descriptor_fuzz1116() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer16".into(), + archetype_field_name: Some("fuzz1116".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1117`]. + #[inline] + pub fn descriptor_fuzz1117() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer17".into(), + archetype_field_name: Some("fuzz1117".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1118`]. + #[inline] + pub fn descriptor_fuzz1118() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer18".into(), + archetype_field_name: Some("fuzz1118".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz1122`]. + #[inline] + pub fn descriptor_fuzz1122() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer22".into(), + archetype_field_name: Some("fuzz1122".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), + component_name: "rerun.testing.components.AffixFuzzer2Indicator".into(), + archetype_field_name: None, + } + } +} + static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 19usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer1".into(), - archetype_field_name: Some("fuzz1101".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer2".into(), - archetype_field_name: Some("fuzz1102".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer3".into(), - archetype_field_name: Some("fuzz1103".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer4".into(), - archetype_field_name: Some("fuzz1104".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer5".into(), - archetype_field_name: Some("fuzz1105".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer6".into(), - archetype_field_name: Some("fuzz1106".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer7".into(), - archetype_field_name: Some("fuzz1107".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer8".into(), - archetype_field_name: Some("fuzz1108".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer9".into(), - archetype_field_name: Some("fuzz1109".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer10".into(), - archetype_field_name: Some("fuzz1110".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer11".into(), - archetype_field_name: Some("fuzz1111".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer12".into(), - archetype_field_name: Some("fuzz1112".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer13".into(), - archetype_field_name: Some("fuzz1113".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer14".into(), - archetype_field_name: Some("fuzz1114".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer15".into(), - archetype_field_name: Some("fuzz1115".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer16".into(), - archetype_field_name: Some("fuzz1116".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer17".into(), - archetype_field_name: Some("fuzz1117".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer18".into(), - archetype_field_name: Some("fuzz1118".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer22".into(), - archetype_field_name: Some("fuzz1122".into()), - }, + AffixFuzzer2::descriptor_fuzz1101(), + AffixFuzzer2::descriptor_fuzz1102(), + AffixFuzzer2::descriptor_fuzz1103(), + AffixFuzzer2::descriptor_fuzz1104(), + AffixFuzzer2::descriptor_fuzz1105(), + AffixFuzzer2::descriptor_fuzz1106(), + AffixFuzzer2::descriptor_fuzz1107(), + AffixFuzzer2::descriptor_fuzz1108(), + AffixFuzzer2::descriptor_fuzz1109(), + AffixFuzzer2::descriptor_fuzz1110(), + AffixFuzzer2::descriptor_fuzz1111(), + AffixFuzzer2::descriptor_fuzz1112(), + AffixFuzzer2::descriptor_fuzz1113(), + AffixFuzzer2::descriptor_fuzz1114(), + AffixFuzzer2::descriptor_fuzz1115(), + AffixFuzzer2::descriptor_fuzz1116(), + AffixFuzzer2::descriptor_fuzz1117(), + AffixFuzzer2::descriptor_fuzz1118(), + AffixFuzzer2::descriptor_fuzz1122(), ] }); static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer2Indicator".into(), - archetype_field_name: None, - }] - }); + once_cell::sync::Lazy::new(|| [AffixFuzzer2::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = once_cell::sync::Lazy::new(|| []); @@ -157,106 +277,26 @@ static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 20usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer1".into(), - archetype_field_name: Some("fuzz1101".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer2".into(), - archetype_field_name: Some("fuzz1102".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer3".into(), - archetype_field_name: Some("fuzz1103".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer4".into(), - archetype_field_name: Some("fuzz1104".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer5".into(), - archetype_field_name: Some("fuzz1105".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer6".into(), - archetype_field_name: Some("fuzz1106".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer7".into(), - archetype_field_name: Some("fuzz1107".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer8".into(), - archetype_field_name: Some("fuzz1108".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer9".into(), - archetype_field_name: Some("fuzz1109".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer10".into(), - archetype_field_name: Some("fuzz1110".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer11".into(), - archetype_field_name: Some("fuzz1111".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer12".into(), - archetype_field_name: Some("fuzz1112".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer13".into(), - archetype_field_name: Some("fuzz1113".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer14".into(), - archetype_field_name: Some("fuzz1114".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer15".into(), - archetype_field_name: Some("fuzz1115".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer16".into(), - archetype_field_name: Some("fuzz1116".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer17".into(), - archetype_field_name: Some("fuzz1117".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer18".into(), - archetype_field_name: Some("fuzz1118".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer22".into(), - archetype_field_name: Some("fuzz1122".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - component_name: "rerun.testing.components.AffixFuzzer2Indicator".into(), - archetype_field_name: None, - }, + AffixFuzzer2::descriptor_fuzz1101(), + AffixFuzzer2::descriptor_fuzz1102(), + AffixFuzzer2::descriptor_fuzz1103(), + AffixFuzzer2::descriptor_fuzz1104(), + AffixFuzzer2::descriptor_fuzz1105(), + AffixFuzzer2::descriptor_fuzz1106(), + AffixFuzzer2::descriptor_fuzz1107(), + AffixFuzzer2::descriptor_fuzz1108(), + AffixFuzzer2::descriptor_fuzz1109(), + AffixFuzzer2::descriptor_fuzz1110(), + AffixFuzzer2::descriptor_fuzz1111(), + AffixFuzzer2::descriptor_fuzz1112(), + AffixFuzzer2::descriptor_fuzz1113(), + AffixFuzzer2::descriptor_fuzz1114(), + AffixFuzzer2::descriptor_fuzz1115(), + AffixFuzzer2::descriptor_fuzz1116(), + AffixFuzzer2::descriptor_fuzz1117(), + AffixFuzzer2::descriptor_fuzz1118(), + AffixFuzzer2::descriptor_fuzz1122(), + AffixFuzzer2::descriptor_indicator(), ] }); @@ -578,191 +618,115 @@ impl ::re_types_core::AsComponents for AffixFuzzer2 { (Some(&self.fuzz1101 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1101").into()), - component_name: ("rerun.testing.components.AffixFuzzer1").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1101()), } }), (Some(&self.fuzz1102 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1102").into()), - component_name: ("rerun.testing.components.AffixFuzzer2").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1102()), } }), (Some(&self.fuzz1103 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1103").into()), - component_name: ("rerun.testing.components.AffixFuzzer3").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1103()), } }), (Some(&self.fuzz1104 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1104").into()), - component_name: ("rerun.testing.components.AffixFuzzer4").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1104()), } }), (Some(&self.fuzz1105 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1105").into()), - component_name: ("rerun.testing.components.AffixFuzzer5").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1105()), } }), (Some(&self.fuzz1106 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1106").into()), - component_name: ("rerun.testing.components.AffixFuzzer6").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1106()), } }), (Some(&self.fuzz1107 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1107").into()), - component_name: ("rerun.testing.components.AffixFuzzer7").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1107()), } }), (Some(&self.fuzz1108 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1108").into()), - component_name: ("rerun.testing.components.AffixFuzzer8").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1108()), } }), (Some(&self.fuzz1109 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1109").into()), - component_name: ("rerun.testing.components.AffixFuzzer9").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1109()), } }), (Some(&self.fuzz1110 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1110").into()), - component_name: ("rerun.testing.components.AffixFuzzer10").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1110()), } }), (Some(&self.fuzz1111 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1111").into()), - component_name: ("rerun.testing.components.AffixFuzzer11").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1111()), } }), (Some(&self.fuzz1112 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1112").into()), - component_name: ("rerun.testing.components.AffixFuzzer12").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1112()), } }), (Some(&self.fuzz1113 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1113").into()), - component_name: ("rerun.testing.components.AffixFuzzer13").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1113()), } }), (Some(&self.fuzz1114 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1114").into()), - component_name: ("rerun.testing.components.AffixFuzzer14").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1114()), } }), (Some(&self.fuzz1115 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1115").into()), - component_name: ("rerun.testing.components.AffixFuzzer15").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1115()), } }), (Some(&self.fuzz1116 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1116").into()), - component_name: ("rerun.testing.components.AffixFuzzer16").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1116()), } }), (Some(&self.fuzz1117 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1117").into()), - component_name: ("rerun.testing.components.AffixFuzzer17").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1117()), } }), (Some(&self.fuzz1118 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1118").into()), - component_name: ("rerun.testing.components.AffixFuzzer18").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1118()), } }), (Some(&self.fuzz1122 as &dyn ComponentBatch)).map(|batch| { ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer2".into()), - archetype_field_name: Some(("fuzz1122").into()), - component_name: ("rerun.testing.components.AffixFuzzer22").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz1122()), } }), ] diff --git a/crates/store/re_types/src/testing/archetypes/affix_fuzzer3.rs b/crates/store/re_types/src/testing/archetypes/affix_fuzzer3.rs index 9310b66e73ce..edcc3108ecee 100644 --- a/crates/store/re_types/src/testing/archetypes/affix_fuzzer3.rs +++ b/crates/store/re_types/src/testing/archetypes/affix_fuzzer3.rs @@ -40,212 +40,250 @@ pub struct AffixFuzzer3 { pub fuzz2018: Option, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl AffixFuzzer3 { + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2001`]. + #[inline] + pub fn descriptor_fuzz2001() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer1".into(), + archetype_field_name: Some("fuzz2001".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2002`]. + #[inline] + pub fn descriptor_fuzz2002() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer2".into(), + archetype_field_name: Some("fuzz2002".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2003`]. + #[inline] + pub fn descriptor_fuzz2003() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer3".into(), + archetype_field_name: Some("fuzz2003".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2004`]. + #[inline] + pub fn descriptor_fuzz2004() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer4".into(), + archetype_field_name: Some("fuzz2004".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2005`]. + #[inline] + pub fn descriptor_fuzz2005() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer5".into(), + archetype_field_name: Some("fuzz2005".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2006`]. + #[inline] + pub fn descriptor_fuzz2006() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer6".into(), + archetype_field_name: Some("fuzz2006".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2007`]. + #[inline] + pub fn descriptor_fuzz2007() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer7".into(), + archetype_field_name: Some("fuzz2007".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2008`]. + #[inline] + pub fn descriptor_fuzz2008() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer8".into(), + archetype_field_name: Some("fuzz2008".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2009`]. + #[inline] + pub fn descriptor_fuzz2009() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer9".into(), + archetype_field_name: Some("fuzz2009".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2010`]. + #[inline] + pub fn descriptor_fuzz2010() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer10".into(), + archetype_field_name: Some("fuzz2010".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2011`]. + #[inline] + pub fn descriptor_fuzz2011() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer11".into(), + archetype_field_name: Some("fuzz2011".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2012`]. + #[inline] + pub fn descriptor_fuzz2012() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer12".into(), + archetype_field_name: Some("fuzz2012".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2013`]. + #[inline] + pub fn descriptor_fuzz2013() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer13".into(), + archetype_field_name: Some("fuzz2013".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2014`]. + #[inline] + pub fn descriptor_fuzz2014() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer14".into(), + archetype_field_name: Some("fuzz2014".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2015`]. + #[inline] + pub fn descriptor_fuzz2015() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer15".into(), + archetype_field_name: Some("fuzz2015".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2016`]. + #[inline] + pub fn descriptor_fuzz2016() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer16".into(), + archetype_field_name: Some("fuzz2016".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2017`]. + #[inline] + pub fn descriptor_fuzz2017() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer17".into(), + archetype_field_name: Some("fuzz2017".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2018`]. + #[inline] + pub fn descriptor_fuzz2018() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), + component_name: "rerun.testing.components.AffixFuzzer18".into(), + archetype_field_name: Some("fuzz2018".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), component_name: "rerun.testing.components.AffixFuzzer3Indicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [AffixFuzzer3::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 18usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer1".into(), - archetype_field_name: Some("fuzz2001".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer2".into(), - archetype_field_name: Some("fuzz2002".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer3".into(), - archetype_field_name: Some("fuzz2003".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer4".into(), - archetype_field_name: Some("fuzz2004".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer5".into(), - archetype_field_name: Some("fuzz2005".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer6".into(), - archetype_field_name: Some("fuzz2006".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer7".into(), - archetype_field_name: Some("fuzz2007".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer8".into(), - archetype_field_name: Some("fuzz2008".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer9".into(), - archetype_field_name: Some("fuzz2009".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer10".into(), - archetype_field_name: Some("fuzz2010".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer11".into(), - archetype_field_name: Some("fuzz2011".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer12".into(), - archetype_field_name: Some("fuzz2012".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer13".into(), - archetype_field_name: Some("fuzz2013".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer14".into(), - archetype_field_name: Some("fuzz2014".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer15".into(), - archetype_field_name: Some("fuzz2015".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer16".into(), - archetype_field_name: Some("fuzz2016".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer17".into(), - archetype_field_name: Some("fuzz2017".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer18".into(), - archetype_field_name: Some("fuzz2018".into()), - }, + AffixFuzzer3::descriptor_fuzz2001(), + AffixFuzzer3::descriptor_fuzz2002(), + AffixFuzzer3::descriptor_fuzz2003(), + AffixFuzzer3::descriptor_fuzz2004(), + AffixFuzzer3::descriptor_fuzz2005(), + AffixFuzzer3::descriptor_fuzz2006(), + AffixFuzzer3::descriptor_fuzz2007(), + AffixFuzzer3::descriptor_fuzz2008(), + AffixFuzzer3::descriptor_fuzz2009(), + AffixFuzzer3::descriptor_fuzz2010(), + AffixFuzzer3::descriptor_fuzz2011(), + AffixFuzzer3::descriptor_fuzz2012(), + AffixFuzzer3::descriptor_fuzz2013(), + AffixFuzzer3::descriptor_fuzz2014(), + AffixFuzzer3::descriptor_fuzz2015(), + AffixFuzzer3::descriptor_fuzz2016(), + AffixFuzzer3::descriptor_fuzz2017(), + AffixFuzzer3::descriptor_fuzz2018(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 19usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer3Indicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer1".into(), - archetype_field_name: Some("fuzz2001".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer2".into(), - archetype_field_name: Some("fuzz2002".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer3".into(), - archetype_field_name: Some("fuzz2003".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer4".into(), - archetype_field_name: Some("fuzz2004".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer5".into(), - archetype_field_name: Some("fuzz2005".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer6".into(), - archetype_field_name: Some("fuzz2006".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer7".into(), - archetype_field_name: Some("fuzz2007".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer8".into(), - archetype_field_name: Some("fuzz2008".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer9".into(), - archetype_field_name: Some("fuzz2009".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer10".into(), - archetype_field_name: Some("fuzz2010".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer11".into(), - archetype_field_name: Some("fuzz2011".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer12".into(), - archetype_field_name: Some("fuzz2012".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer13".into(), - archetype_field_name: Some("fuzz2013".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer14".into(), - archetype_field_name: Some("fuzz2014".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer15".into(), - archetype_field_name: Some("fuzz2015".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer16".into(), - archetype_field_name: Some("fuzz2016".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer17".into(), - archetype_field_name: Some("fuzz2017".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - component_name: "rerun.testing.components.AffixFuzzer18".into(), - archetype_field_name: Some("fuzz2018".into()), - }, + AffixFuzzer3::descriptor_indicator(), + AffixFuzzer3::descriptor_fuzz2001(), + AffixFuzzer3::descriptor_fuzz2002(), + AffixFuzzer3::descriptor_fuzz2003(), + AffixFuzzer3::descriptor_fuzz2004(), + AffixFuzzer3::descriptor_fuzz2005(), + AffixFuzzer3::descriptor_fuzz2006(), + AffixFuzzer3::descriptor_fuzz2007(), + AffixFuzzer3::descriptor_fuzz2008(), + AffixFuzzer3::descriptor_fuzz2009(), + AffixFuzzer3::descriptor_fuzz2010(), + AffixFuzzer3::descriptor_fuzz2011(), + AffixFuzzer3::descriptor_fuzz2012(), + AffixFuzzer3::descriptor_fuzz2013(), + AffixFuzzer3::descriptor_fuzz2014(), + AffixFuzzer3::descriptor_fuzz2015(), + AffixFuzzer3::descriptor_fuzz2016(), + AffixFuzzer3::descriptor_fuzz2017(), + AffixFuzzer3::descriptor_fuzz2018(), ] }); @@ -521,11 +559,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2001").into()), - component_name: ("rerun.testing.components.AffixFuzzer1").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2001()), }), (self .fuzz2002 @@ -533,11 +567,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2002").into()), - component_name: ("rerun.testing.components.AffixFuzzer2").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2002()), }), (self .fuzz2003 @@ -545,11 +575,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2003").into()), - component_name: ("rerun.testing.components.AffixFuzzer3").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2003()), }), (self .fuzz2004 @@ -557,11 +583,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2004").into()), - component_name: ("rerun.testing.components.AffixFuzzer4").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2004()), }), (self .fuzz2005 @@ -569,11 +591,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2005").into()), - component_name: ("rerun.testing.components.AffixFuzzer5").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2005()), }), (self .fuzz2006 @@ -581,11 +599,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2006").into()), - component_name: ("rerun.testing.components.AffixFuzzer6").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2006()), }), (self .fuzz2007 @@ -593,11 +607,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2007").into()), - component_name: ("rerun.testing.components.AffixFuzzer7").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2007()), }), (self .fuzz2008 @@ -605,11 +615,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2008").into()), - component_name: ("rerun.testing.components.AffixFuzzer8").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2008()), }), (self .fuzz2009 @@ -617,11 +623,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2009").into()), - component_name: ("rerun.testing.components.AffixFuzzer9").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2009()), }), (self .fuzz2010 @@ -629,11 +631,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2010").into()), - component_name: ("rerun.testing.components.AffixFuzzer10").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2010()), }), (self .fuzz2011 @@ -641,11 +639,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2011").into()), - component_name: ("rerun.testing.components.AffixFuzzer11").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2011()), }), (self .fuzz2012 @@ -653,11 +647,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2012").into()), - component_name: ("rerun.testing.components.AffixFuzzer12").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2012()), }), (self .fuzz2013 @@ -665,11 +655,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2013").into()), - component_name: ("rerun.testing.components.AffixFuzzer13").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2013()), }), (self .fuzz2014 @@ -677,11 +663,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2014").into()), - component_name: ("rerun.testing.components.AffixFuzzer14").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2014()), }), (self .fuzz2015 @@ -689,11 +671,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2015").into()), - component_name: ("rerun.testing.components.AffixFuzzer15").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2015()), }), (self .fuzz2016 @@ -701,11 +679,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2016").into()), - component_name: ("rerun.testing.components.AffixFuzzer16").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2016()), }), (self .fuzz2017 @@ -713,11 +687,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2017").into()), - component_name: ("rerun.testing.components.AffixFuzzer17").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2017()), }), (self .fuzz2018 @@ -725,11 +695,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer3 { .map(|comp| (comp as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer3".into()), - archetype_field_name: Some(("fuzz2018").into()), - component_name: ("rerun.testing.components.AffixFuzzer18").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2018()), }), ] .into_iter() diff --git a/crates/store/re_types/src/testing/archetypes/affix_fuzzer4.rs b/crates/store/re_types/src/testing/archetypes/affix_fuzzer4.rs index 1af1aaac23db..6cc8d615c80b 100644 --- a/crates/store/re_types/src/testing/archetypes/affix_fuzzer4.rs +++ b/crates/store/re_types/src/testing/archetypes/affix_fuzzer4.rs @@ -40,212 +40,250 @@ pub struct AffixFuzzer4 { pub fuzz2118: Option>, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = - once_cell::sync::Lazy::new(|| []); +impl AffixFuzzer4 { + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2101`]. + #[inline] + pub fn descriptor_fuzz2101() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer1".into(), + archetype_field_name: Some("fuzz2101".into()), + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2102`]. + #[inline] + pub fn descriptor_fuzz2102() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer2".into(), + archetype_field_name: Some("fuzz2102".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2103`]. + #[inline] + pub fn descriptor_fuzz2103() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer3".into(), + archetype_field_name: Some("fuzz2103".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2104`]. + #[inline] + pub fn descriptor_fuzz2104() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer4".into(), + archetype_field_name: Some("fuzz2104".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2105`]. + #[inline] + pub fn descriptor_fuzz2105() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer5".into(), + archetype_field_name: Some("fuzz2105".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2106`]. + #[inline] + pub fn descriptor_fuzz2106() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer6".into(), + archetype_field_name: Some("fuzz2106".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2107`]. + #[inline] + pub fn descriptor_fuzz2107() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer7".into(), + archetype_field_name: Some("fuzz2107".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2108`]. + #[inline] + pub fn descriptor_fuzz2108() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer8".into(), + archetype_field_name: Some("fuzz2108".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2109`]. + #[inline] + pub fn descriptor_fuzz2109() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer9".into(), + archetype_field_name: Some("fuzz2109".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2110`]. + #[inline] + pub fn descriptor_fuzz2110() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer10".into(), + archetype_field_name: Some("fuzz2110".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2111`]. + #[inline] + pub fn descriptor_fuzz2111() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer11".into(), + archetype_field_name: Some("fuzz2111".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2112`]. + #[inline] + pub fn descriptor_fuzz2112() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer12".into(), + archetype_field_name: Some("fuzz2112".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2113`]. + #[inline] + pub fn descriptor_fuzz2113() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer13".into(), + archetype_field_name: Some("fuzz2113".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2114`]. + #[inline] + pub fn descriptor_fuzz2114() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer14".into(), + archetype_field_name: Some("fuzz2114".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2115`]. + #[inline] + pub fn descriptor_fuzz2115() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer15".into(), + archetype_field_name: Some("fuzz2115".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2116`]. + #[inline] + pub fn descriptor_fuzz2116() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer16".into(), + archetype_field_name: Some("fuzz2116".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2117`]. + #[inline] + pub fn descriptor_fuzz2117() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer17".into(), + archetype_field_name: Some("fuzz2117".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for [`Self::fuzz2118`]. + #[inline] + pub fn descriptor_fuzz2118() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), + component_name: "rerun.testing.components.AffixFuzzer18".into(), + archetype_field_name: Some("fuzz2118".into()), + } + } + + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), component_name: "rerun.testing.components.AffixFuzzer4Indicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = + once_cell::sync::Lazy::new(|| []); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [AffixFuzzer4::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 18usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer1".into(), - archetype_field_name: Some("fuzz2101".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer2".into(), - archetype_field_name: Some("fuzz2102".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer3".into(), - archetype_field_name: Some("fuzz2103".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer4".into(), - archetype_field_name: Some("fuzz2104".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer5".into(), - archetype_field_name: Some("fuzz2105".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer6".into(), - archetype_field_name: Some("fuzz2106".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer7".into(), - archetype_field_name: Some("fuzz2107".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer8".into(), - archetype_field_name: Some("fuzz2108".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer9".into(), - archetype_field_name: Some("fuzz2109".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer10".into(), - archetype_field_name: Some("fuzz2110".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer11".into(), - archetype_field_name: Some("fuzz2111".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer12".into(), - archetype_field_name: Some("fuzz2112".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer13".into(), - archetype_field_name: Some("fuzz2113".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer14".into(), - archetype_field_name: Some("fuzz2114".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer15".into(), - archetype_field_name: Some("fuzz2115".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer16".into(), - archetype_field_name: Some("fuzz2116".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer17".into(), - archetype_field_name: Some("fuzz2117".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer18".into(), - archetype_field_name: Some("fuzz2118".into()), - }, + AffixFuzzer4::descriptor_fuzz2101(), + AffixFuzzer4::descriptor_fuzz2102(), + AffixFuzzer4::descriptor_fuzz2103(), + AffixFuzzer4::descriptor_fuzz2104(), + AffixFuzzer4::descriptor_fuzz2105(), + AffixFuzzer4::descriptor_fuzz2106(), + AffixFuzzer4::descriptor_fuzz2107(), + AffixFuzzer4::descriptor_fuzz2108(), + AffixFuzzer4::descriptor_fuzz2109(), + AffixFuzzer4::descriptor_fuzz2110(), + AffixFuzzer4::descriptor_fuzz2111(), + AffixFuzzer4::descriptor_fuzz2112(), + AffixFuzzer4::descriptor_fuzz2113(), + AffixFuzzer4::descriptor_fuzz2114(), + AffixFuzzer4::descriptor_fuzz2115(), + AffixFuzzer4::descriptor_fuzz2116(), + AffixFuzzer4::descriptor_fuzz2117(), + AffixFuzzer4::descriptor_fuzz2118(), ] }); static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 19usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer4Indicator".into(), - archetype_field_name: None, - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer1".into(), - archetype_field_name: Some("fuzz2101".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer2".into(), - archetype_field_name: Some("fuzz2102".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer3".into(), - archetype_field_name: Some("fuzz2103".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer4".into(), - archetype_field_name: Some("fuzz2104".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer5".into(), - archetype_field_name: Some("fuzz2105".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer6".into(), - archetype_field_name: Some("fuzz2106".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer7".into(), - archetype_field_name: Some("fuzz2107".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer8".into(), - archetype_field_name: Some("fuzz2108".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer9".into(), - archetype_field_name: Some("fuzz2109".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer10".into(), - archetype_field_name: Some("fuzz2110".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer11".into(), - archetype_field_name: Some("fuzz2111".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer12".into(), - archetype_field_name: Some("fuzz2112".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer13".into(), - archetype_field_name: Some("fuzz2113".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer14".into(), - archetype_field_name: Some("fuzz2114".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer15".into(), - archetype_field_name: Some("fuzz2115".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer16".into(), - archetype_field_name: Some("fuzz2116".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer17".into(), - archetype_field_name: Some("fuzz2117".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - component_name: "rerun.testing.components.AffixFuzzer18".into(), - archetype_field_name: Some("fuzz2118".into()), - }, + AffixFuzzer4::descriptor_indicator(), + AffixFuzzer4::descriptor_fuzz2101(), + AffixFuzzer4::descriptor_fuzz2102(), + AffixFuzzer4::descriptor_fuzz2103(), + AffixFuzzer4::descriptor_fuzz2104(), + AffixFuzzer4::descriptor_fuzz2105(), + AffixFuzzer4::descriptor_fuzz2106(), + AffixFuzzer4::descriptor_fuzz2107(), + AffixFuzzer4::descriptor_fuzz2108(), + AffixFuzzer4::descriptor_fuzz2109(), + AffixFuzzer4::descriptor_fuzz2110(), + AffixFuzzer4::descriptor_fuzz2111(), + AffixFuzzer4::descriptor_fuzz2112(), + AffixFuzzer4::descriptor_fuzz2113(), + AffixFuzzer4::descriptor_fuzz2114(), + AffixFuzzer4::descriptor_fuzz2115(), + AffixFuzzer4::descriptor_fuzz2116(), + AffixFuzzer4::descriptor_fuzz2117(), + AffixFuzzer4::descriptor_fuzz2118(), ] }); @@ -575,11 +613,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2101").into()), - component_name: ("rerun.testing.components.AffixFuzzer1").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2101()), }), (self .fuzz2102 @@ -587,11 +621,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2102").into()), - component_name: ("rerun.testing.components.AffixFuzzer2").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2102()), }), (self .fuzz2103 @@ -599,11 +629,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2103").into()), - component_name: ("rerun.testing.components.AffixFuzzer3").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2103()), }), (self .fuzz2104 @@ -611,11 +637,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2104").into()), - component_name: ("rerun.testing.components.AffixFuzzer4").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2104()), }), (self .fuzz2105 @@ -623,11 +645,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2105").into()), - component_name: ("rerun.testing.components.AffixFuzzer5").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2105()), }), (self .fuzz2106 @@ -635,11 +653,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2106").into()), - component_name: ("rerun.testing.components.AffixFuzzer6").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2106()), }), (self .fuzz2107 @@ -647,11 +661,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2107").into()), - component_name: ("rerun.testing.components.AffixFuzzer7").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2107()), }), (self .fuzz2108 @@ -659,11 +669,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2108").into()), - component_name: ("rerun.testing.components.AffixFuzzer8").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2108()), }), (self .fuzz2109 @@ -671,11 +677,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2109").into()), - component_name: ("rerun.testing.components.AffixFuzzer9").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2109()), }), (self .fuzz2110 @@ -683,11 +685,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2110").into()), - component_name: ("rerun.testing.components.AffixFuzzer10").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2110()), }), (self .fuzz2111 @@ -695,11 +693,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2111").into()), - component_name: ("rerun.testing.components.AffixFuzzer11").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2111()), }), (self .fuzz2112 @@ -707,11 +701,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2112").into()), - component_name: ("rerun.testing.components.AffixFuzzer12").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2112()), }), (self .fuzz2113 @@ -719,11 +709,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2113").into()), - component_name: ("rerun.testing.components.AffixFuzzer13").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2113()), }), (self .fuzz2114 @@ -731,11 +717,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2114").into()), - component_name: ("rerun.testing.components.AffixFuzzer14").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2114()), }), (self .fuzz2115 @@ -743,11 +725,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2115").into()), - component_name: ("rerun.testing.components.AffixFuzzer15").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2115()), }), (self .fuzz2116 @@ -755,11 +733,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2116").into()), - component_name: ("rerun.testing.components.AffixFuzzer16").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2116()), }), (self .fuzz2117 @@ -767,11 +741,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2117").into()), - component_name: ("rerun.testing.components.AffixFuzzer17").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2117()), }), (self .fuzz2118 @@ -779,11 +749,7 @@ impl ::re_types_core::AsComponents for AffixFuzzer4 { .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.testing.archetypes.AffixFuzzer4".into()), - archetype_field_name: Some(("fuzz2118").into()), - component_name: ("rerun.testing.components.AffixFuzzer18").into(), - }), + descriptor_override: Some(Self::descriptor_fuzz2118()), }), ] .into_iter() diff --git a/crates/store/re_types_core/src/archetypes/clear.rs b/crates/store/re_types_core/src/archetypes/clear.rs index 50e83e036419..5f3e932288c0 100644 --- a/crates/store/re_types_core/src/archetypes/clear.rs +++ b/crates/store/re_types_core/src/archetypes/clear.rs @@ -78,23 +78,33 @@ pub struct Clear { pub is_recursive: crate::components::ClearIsRecursive, } -static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { +impl Clear { + /// Returns the [`ComponentDescriptor`] for [`Self::is_recursive`]. + #[inline] + pub fn descriptor_is_recursive() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Clear".into()), component_name: "rerun.components.ClearIsRecursive".into(), archetype_field_name: Some("is_recursive".into()), - }] - }); + } + } -static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = - once_cell::sync::Lazy::new(|| { - [ComponentDescriptor { + /// Returns the [`ComponentDescriptor`] for the associated indicator component. + #[inline] + pub fn descriptor_indicator() -> ComponentDescriptor { + ComponentDescriptor { archetype_name: Some("rerun.archetypes.Clear".into()), component_name: "rerun.components.ClearIndicator".into(), archetype_field_name: None, - }] - }); + } + } +} + +static REQUIRED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Clear::descriptor_is_recursive()]); + +static RECOMMENDED_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 1usize]> = + once_cell::sync::Lazy::new(|| [Clear::descriptor_indicator()]); static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> = once_cell::sync::Lazy::new(|| []); @@ -102,16 +112,8 @@ static OPTIONAL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 0usize]> static ALL_COMPONENTS: once_cell::sync::Lazy<[ComponentDescriptor; 2usize]> = once_cell::sync::Lazy::new(|| { [ - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Clear".into()), - component_name: "rerun.components.ClearIsRecursive".into(), - archetype_field_name: Some("is_recursive".into()), - }, - ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Clear".into()), - component_name: "rerun.components.ClearIndicator".into(), - archetype_field_name: None, - }, + Clear::descriptor_is_recursive(), + Clear::descriptor_indicator(), ] }); @@ -198,11 +200,7 @@ impl crate::AsComponents for Clear { (Some(&self.is_recursive as &dyn ComponentBatch)).map(|batch| { crate::ComponentBatchCowWithDescriptor { batch: batch.into(), - descriptor_override: Some(ComponentDescriptor { - archetype_name: Some("rerun.archetypes.Clear".into()), - archetype_field_name: Some(("is_recursive").into()), - component_name: ("rerun.components.ClearIsRecursive").into(), - }), + descriptor_override: Some(Self::descriptor_is_recursive()), } }), ] From 07ca851fa4d1380b5bcdd1fdc0ef26ccc5e5e0e0 Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Mon, 13 Jan 2025 09:20:13 +0100 Subject: [PATCH 07/57] Make `Archetype::{from_arrow, to_arrow}` and friends tag compliant (#8644) These methods were still `ComponentName`-based, which just won't work as we start introducing archetypes with multiple instances of the same component. Note that these methods are very seldom used (only for tests, IIRC), so I went for the path of least resistance and took a few shortcuts. We can build something sturdier later on if need be (I highly doubt it... in fact I expect these methods don't have that much time left to live). * DNM: requires #8643 --- .../re_types_builder/src/codegen/rust/api.rs | 19 +- .../src/archetypes/annotation_context.rs | 11 +- .../store/re_types/src/archetypes/arrows2d.rs | 26 +- .../store/re_types/src/archetypes/arrows3d.rs | 24 +- .../store/re_types/src/archetypes/asset3d.rs | 33 +- .../re_types/src/archetypes/asset_video.rs | 13 +- .../re_types/src/archetypes/bar_chart.rs | 13 +- .../store/re_types/src/archetypes/boxes2d.rs | 26 +- .../store/re_types/src/archetypes/boxes3d.rs | 55 +-- .../re_types/src/archetypes/capsules3d.rs | 54 +-- .../re_types/src/archetypes/depth_image.rs | 44 +- .../re_types/src/archetypes/ellipsoids3d.rs | 55 +-- .../re_types/src/archetypes/encoded_image.rs | 17 +- .../src/archetypes/geo_line_strings.rs | 15 +- .../re_types/src/archetypes/geo_points.rs | 17 +- .../re_types/src/archetypes/graph_edges.rs | 13 +- .../re_types/src/archetypes/graph_nodes.rs | 22 +- crates/store/re_types/src/archetypes/image.rs | 19 +- .../src/archetypes/instance_poses3d.rs | 42 +- .../re_types/src/archetypes/line_strips2d.rs | 24 +- .../re_types/src/archetypes/line_strips3d.rs | 22 +- .../store/re_types/src/archetypes/mesh3d.rs | 91 ++-- .../store/re_types/src/archetypes/pinhole.rs | 18 +- .../store/re_types/src/archetypes/points2d.rs | 49 +- .../store/re_types/src/archetypes/points3d.rs | 47 +- .../store/re_types/src/archetypes/scalar.rs | 11 +- .../src/archetypes/segmentation_image.rs | 19 +- .../re_types/src/archetypes/series_line.rs | 15 +- .../re_types/src/archetypes/series_point.rs | 16 +- .../store/re_types/src/archetypes/tensor.rs | 14 +- .../re_types/src/archetypes/text_document.rs | 13 +- .../store/re_types/src/archetypes/text_log.rs | 15 +- .../re_types/src/archetypes/transform3d.rs | 23 +- .../src/archetypes/video_frame_reference.rs | 31 +- .../src/archetypes/view_coordinates.rs | 11 +- .../src/blueprint/archetypes/background.rs | 13 +- .../archetypes/container_blueprint.rs | 117 +++-- .../blueprint/archetypes/dataframe_query.rs | 51 +- .../src/blueprint/archetypes/force_center.rs | 29 +- .../archetypes/force_collision_radius.rs | 48 +- .../src/blueprint/archetypes/force_link.rs | 48 +- .../blueprint/archetypes/force_many_body.rs | 29 +- .../blueprint/archetypes/force_position.rs | 31 +- .../src/blueprint/archetypes/line_grid3d.rs | 44 +- .../blueprint/archetypes/map_background.rs | 11 +- .../src/blueprint/archetypes/map_zoom.rs | 11 +- .../blueprint/archetypes/near_clip_plane.rs | 11 +- .../blueprint/archetypes/panel_blueprint.rs | 10 +- .../src/blueprint/archetypes/plot_legend.rs | 13 +- .../src/blueprint/archetypes/scalar_axis.rs | 13 +- .../archetypes/tensor_scalar_mapping.rs | 30 +- .../archetypes/tensor_slice_selection.rs | 37 +- .../blueprint/archetypes/tensor_view_fit.rs | 10 +- .../blueprint/archetypes/view_blueprint.rs | 35 +- .../src/blueprint/archetypes/view_contents.rs | 11 +- .../archetypes/viewport_blueprint.rs | 69 ++- .../archetypes/visible_time_ranges.rs | 11 +- .../blueprint/archetypes/visual_bounds2d.rs | 11 +- .../src/testing/archetypes/affix_fuzzer1.rs | 95 ++-- .../src/testing/archetypes/affix_fuzzer2.rs | 83 ++-- .../src/testing/archetypes/affix_fuzzer3.rs | 349 +++++++------ .../src/testing/archetypes/affix_fuzzer4.rs | 457 +++++++++--------- crates/store/re_types/tests/types/points3d.rs | 6 +- crates/store/re_types_core/src/archetype.rs | 13 +- .../re_types_core/src/archetypes/clear.rs | 11 +- .../store/re_types_core/src/as_components.rs | 19 +- .../re_types_core/src/component_descriptor.rs | 33 ++ .../store/re_types_core/src/loggable_batch.rs | 76 +++ 68 files changed, 1313 insertions(+), 1459 deletions(-) diff --git a/crates/build/re_types_builder/src/codegen/rust/api.rs b/crates/build/re_types_builder/src/codegen/rust/api.rs index 89d887f62fa2..e4b5894f66b3 100644 --- a/crates/build/re_types_builder/src/codegen/rust/api.rs +++ b/crates/build/re_types_builder/src/codegen/rust/api.rs @@ -1216,8 +1216,8 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { let all_deserializers = { obj.fields.iter().map(|obj_field| { let obj_field_fqname = obj_field.fqname.as_str(); - let field_typ_fqname_str = obj_field.typ.fqname().unwrap(); let field_name = format_ident!("{}", obj_field.name); + let descr_fn_name = format_ident!("descriptor_{field_name}"); let is_plural = obj_field.typ.is_plural(); let is_nullable = obj_field.is_nullable; @@ -1256,7 +1256,7 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { }; quote! { - if let Some(array) = arrays_by_name.get(#field_typ_fqname_str) { + if let Some(array) = arrays_by_descr.get(&Self::#descr_fn_name()) { <#component>::from_arrow_opt(&**array) .with_context(#obj_field_fqname)? #quoted_collection @@ -1266,7 +1266,7 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { } } else if is_nullable { quote! { - if let Some(array) = arrays_by_name.get(#field_typ_fqname_str) { + if let Some(array) = arrays_by_descr.get(&Self::#descr_fn_name()) { Some({ <#component>::from_arrow_opt(&**array) .with_context(#obj_field_fqname)? @@ -1278,8 +1278,8 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { } } else { quote! {{ - let array = arrays_by_name - .get(#field_typ_fqname_str) + let array = arrays_by_descr + .get(&Self::#descr_fn_name()) .ok_or_else(DeserializationError::missing_data) .with_context(#obj_field_fqname)?; @@ -1359,7 +1359,7 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { #[inline] fn from_arrow_components( arrow_data: impl IntoIterator, ) -> DeserializationResult { @@ -1367,12 +1367,7 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { use ::re_types_core::{Loggable as _, ResultExt as _}; - // NOTE: Even though ComponentName is an InternedString, we must - // convert to &str here because the .get("component.name") accessors - // will fail otherwise. - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)).collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); #(#all_deserializers;)* diff --git a/crates/store/re_types/src/archetypes/annotation_context.rs b/crates/store/re_types/src/archetypes/annotation_context.rs index a53b871fbf21..46c624eed099 100644 --- a/crates/store/re_types/src/archetypes/annotation_context.rs +++ b/crates/store/re_types/src/archetypes/annotation_context.rs @@ -163,17 +163,14 @@ impl ::re_types_core::Archetype for AnnotationContext { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let context = { - let array = arrays_by_name - .get("rerun.components.AnnotationContext") + let array = arrays_by_descr + .get(&Self::descriptor_context()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.AnnotationContext#context")?; ::from_arrow_opt(&**array) diff --git a/crates/store/re_types/src/archetypes/arrows2d.rs b/crates/store/re_types/src/archetypes/arrows2d.rs index 39d9b66419da..8f5b6bd3bb0e 100644 --- a/crates/store/re_types/src/archetypes/arrows2d.rs +++ b/crates/store/re_types/src/archetypes/arrows2d.rs @@ -266,17 +266,14 @@ impl ::re_types_core::Archetype for Arrows2D { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let vectors = { - let array = arrays_by_name - .get("rerun.components.Vector2D") + let array = arrays_by_descr + .get(&Self::descriptor_vectors()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Arrows2D#vectors")?; ::from_arrow_opt(&**array) @@ -286,7 +283,7 @@ impl ::re_types_core::Archetype for Arrows2D { .collect::>>() .with_context("rerun.archetypes.Arrows2D#vectors")? }; - let origins = if let Some(array) = arrays_by_name.get("rerun.components.Position2D") { + let origins = if let Some(array) = arrays_by_descr.get(&Self::descriptor_origins()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Arrows2D#origins")? @@ -298,7 +295,7 @@ impl ::re_types_core::Archetype for Arrows2D { } else { None }; - let radii = if let Some(array) = arrays_by_name.get("rerun.components.Radius") { + let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Arrows2D#radii")? @@ -310,7 +307,7 @@ impl ::re_types_core::Archetype for Arrows2D { } else { None }; - let colors = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Arrows2D#colors")? @@ -322,7 +319,7 @@ impl ::re_types_core::Archetype for Arrows2D { } else { None }; - let labels = if let Some(array) = arrays_by_name.get("rerun.components.Text") { + let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Arrows2D#labels")? @@ -334,7 +331,8 @@ impl ::re_types_core::Archetype for Arrows2D { } else { None }; - let show_labels = if let Some(array) = arrays_by_name.get("rerun.components.ShowLabels") { + let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) + { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Arrows2D#show_labels")? .into_iter() @@ -343,7 +341,7 @@ impl ::re_types_core::Archetype for Arrows2D { } else { None }; - let draw_order = if let Some(array) = arrays_by_name.get("rerun.components.DrawOrder") { + let draw_order = if let Some(array) = arrays_by_descr.get(&Self::descriptor_draw_order()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Arrows2D#draw_order")? .into_iter() @@ -352,7 +350,7 @@ impl ::re_types_core::Archetype for Arrows2D { } else { None }; - let class_ids = if let Some(array) = arrays_by_name.get("rerun.components.ClassId") { + let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Arrows2D#class_ids")? diff --git a/crates/store/re_types/src/archetypes/arrows3d.rs b/crates/store/re_types/src/archetypes/arrows3d.rs index 6bb11ae968e1..9b5e0a42cf51 100644 --- a/crates/store/re_types/src/archetypes/arrows3d.rs +++ b/crates/store/re_types/src/archetypes/arrows3d.rs @@ -262,17 +262,14 @@ impl ::re_types_core::Archetype for Arrows3D { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let vectors = { - let array = arrays_by_name - .get("rerun.components.Vector3D") + let array = arrays_by_descr + .get(&Self::descriptor_vectors()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Arrows3D#vectors")?; ::from_arrow_opt(&**array) @@ -282,7 +279,7 @@ impl ::re_types_core::Archetype for Arrows3D { .collect::>>() .with_context("rerun.archetypes.Arrows3D#vectors")? }; - let origins = if let Some(array) = arrays_by_name.get("rerun.components.Position3D") { + let origins = if let Some(array) = arrays_by_descr.get(&Self::descriptor_origins()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Arrows3D#origins")? @@ -294,7 +291,7 @@ impl ::re_types_core::Archetype for Arrows3D { } else { None }; - let radii = if let Some(array) = arrays_by_name.get("rerun.components.Radius") { + let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Arrows3D#radii")? @@ -306,7 +303,7 @@ impl ::re_types_core::Archetype for Arrows3D { } else { None }; - let colors = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Arrows3D#colors")? @@ -318,7 +315,7 @@ impl ::re_types_core::Archetype for Arrows3D { } else { None }; - let labels = if let Some(array) = arrays_by_name.get("rerun.components.Text") { + let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Arrows3D#labels")? @@ -330,7 +327,8 @@ impl ::re_types_core::Archetype for Arrows3D { } else { None }; - let show_labels = if let Some(array) = arrays_by_name.get("rerun.components.ShowLabels") { + let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) + { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Arrows3D#show_labels")? .into_iter() @@ -339,7 +337,7 @@ impl ::re_types_core::Archetype for Arrows3D { } else { None }; - let class_ids = if let Some(array) = arrays_by_name.get("rerun.components.ClassId") { + let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Arrows3D#class_ids")? diff --git a/crates/store/re_types/src/archetypes/asset3d.rs b/crates/store/re_types/src/archetypes/asset3d.rs index 7521cd4d6134..f81cb11028e1 100644 --- a/crates/store/re_types/src/archetypes/asset3d.rs +++ b/crates/store/re_types/src/archetypes/asset3d.rs @@ -193,17 +193,14 @@ impl ::re_types_core::Archetype for Asset3D { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let blob = { - let array = arrays_by_name - .get("rerun.components.Blob") + let array = arrays_by_descr + .get(&Self::descriptor_blob()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Asset3D#blob")?; ::from_arrow_opt(&**array) @@ -214,7 +211,7 @@ impl ::re_types_core::Archetype for Asset3D { .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Asset3D#blob")? }; - let media_type = if let Some(array) = arrays_by_name.get("rerun.components.MediaType") { + let media_type = if let Some(array) = arrays_by_descr.get(&Self::descriptor_media_type()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Asset3D#media_type")? .into_iter() @@ -223,16 +220,16 @@ impl ::re_types_core::Archetype for Asset3D { } else { None }; - let albedo_factor = if let Some(array) = arrays_by_name.get("rerun.components.AlbedoFactor") - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Asset3D#albedo_factor")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let albedo_factor = + if let Some(array) = arrays_by_descr.get(&Self::descriptor_albedo_factor()) { + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.Asset3D#albedo_factor")? + .into_iter() + .next() + .flatten() + } else { + None + }; Ok(Self { blob, media_type, diff --git a/crates/store/re_types/src/archetypes/asset_video.rs b/crates/store/re_types/src/archetypes/asset_video.rs index 0b7a9a7b8b75..879a61910230 100644 --- a/crates/store/re_types/src/archetypes/asset_video.rs +++ b/crates/store/re_types/src/archetypes/asset_video.rs @@ -243,17 +243,14 @@ impl ::re_types_core::Archetype for AssetVideo { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let blob = { - let array = arrays_by_name - .get("rerun.components.Blob") + let array = arrays_by_descr + .get(&Self::descriptor_blob()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.AssetVideo#blob")?; ::from_arrow_opt(&**array) @@ -264,7 +261,7 @@ impl ::re_types_core::Archetype for AssetVideo { .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.AssetVideo#blob")? }; - let media_type = if let Some(array) = arrays_by_name.get("rerun.components.MediaType") { + let media_type = if let Some(array) = arrays_by_descr.get(&Self::descriptor_media_type()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.AssetVideo#media_type")? .into_iter() diff --git a/crates/store/re_types/src/archetypes/bar_chart.rs b/crates/store/re_types/src/archetypes/bar_chart.rs index 9266923588a8..ed1a5f6314d5 100644 --- a/crates/store/re_types/src/archetypes/bar_chart.rs +++ b/crates/store/re_types/src/archetypes/bar_chart.rs @@ -154,17 +154,14 @@ impl ::re_types_core::Archetype for BarChart { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let values = { - let array = arrays_by_name - .get("rerun.components.TensorData") + let array = arrays_by_descr + .get(&Self::descriptor_values()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.BarChart#values")?; ::from_arrow_opt(&**array) @@ -175,7 +172,7 @@ impl ::re_types_core::Archetype for BarChart { .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.BarChart#values")? }; - let color = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let color = if let Some(array) = arrays_by_descr.get(&Self::descriptor_color()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.BarChart#color")? .into_iter() diff --git a/crates/store/re_types/src/archetypes/boxes2d.rs b/crates/store/re_types/src/archetypes/boxes2d.rs index e63a642cf149..05434a880009 100644 --- a/crates/store/re_types/src/archetypes/boxes2d.rs +++ b/crates/store/re_types/src/archetypes/boxes2d.rs @@ -259,17 +259,14 @@ impl ::re_types_core::Archetype for Boxes2D { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let half_sizes = { - let array = arrays_by_name - .get("rerun.components.HalfSize2D") + let array = arrays_by_descr + .get(&Self::descriptor_half_sizes()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Boxes2D#half_sizes")?; ::from_arrow_opt(&**array) @@ -279,7 +276,7 @@ impl ::re_types_core::Archetype for Boxes2D { .collect::>>() .with_context("rerun.archetypes.Boxes2D#half_sizes")? }; - let centers = if let Some(array) = arrays_by_name.get("rerun.components.Position2D") { + let centers = if let Some(array) = arrays_by_descr.get(&Self::descriptor_centers()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Boxes2D#centers")? @@ -291,7 +288,7 @@ impl ::re_types_core::Archetype for Boxes2D { } else { None }; - let colors = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Boxes2D#colors")? @@ -303,7 +300,7 @@ impl ::re_types_core::Archetype for Boxes2D { } else { None }; - let radii = if let Some(array) = arrays_by_name.get("rerun.components.Radius") { + let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Boxes2D#radii")? @@ -315,7 +312,7 @@ impl ::re_types_core::Archetype for Boxes2D { } else { None }; - let labels = if let Some(array) = arrays_by_name.get("rerun.components.Text") { + let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Boxes2D#labels")? @@ -327,7 +324,8 @@ impl ::re_types_core::Archetype for Boxes2D { } else { None }; - let show_labels = if let Some(array) = arrays_by_name.get("rerun.components.ShowLabels") { + let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) + { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Boxes2D#show_labels")? .into_iter() @@ -336,7 +334,7 @@ impl ::re_types_core::Archetype for Boxes2D { } else { None }; - let draw_order = if let Some(array) = arrays_by_name.get("rerun.components.DrawOrder") { + let draw_order = if let Some(array) = arrays_by_descr.get(&Self::descriptor_draw_order()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Boxes2D#draw_order")? .into_iter() @@ -345,7 +343,7 @@ impl ::re_types_core::Archetype for Boxes2D { } else { None }; - let class_ids = if let Some(array) = arrays_by_name.get("rerun.components.ClassId") { + let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Boxes2D#class_ids")? diff --git a/crates/store/re_types/src/archetypes/boxes3d.rs b/crates/store/re_types/src/archetypes/boxes3d.rs index ff315f90f4f1..77081336ee7d 100644 --- a/crates/store/re_types/src/archetypes/boxes3d.rs +++ b/crates/store/re_types/src/archetypes/boxes3d.rs @@ -313,17 +313,14 @@ impl ::re_types_core::Archetype for Boxes3D { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let half_sizes = { - let array = arrays_by_name - .get("rerun.components.HalfSize3D") + let array = arrays_by_descr + .get(&Self::descriptor_half_sizes()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Boxes3D#half_sizes")?; ::from_arrow_opt(&**array) @@ -333,8 +330,7 @@ impl ::re_types_core::Archetype for Boxes3D { .collect::>>() .with_context("rerun.archetypes.Boxes3D#half_sizes")? }; - let centers = if let Some(array) = arrays_by_name.get("rerun.components.PoseTranslation3D") - { + let centers = if let Some(array) = arrays_by_descr.get(&Self::descriptor_centers()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Boxes3D#centers")? @@ -347,7 +343,7 @@ impl ::re_types_core::Archetype for Boxes3D { None }; let rotation_axis_angles = - if let Some(array) = arrays_by_name.get("rerun.components.PoseRotationAxisAngle") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_rotation_axis_angles()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Boxes3D#rotation_axis_angles")? @@ -359,20 +355,20 @@ impl ::re_types_core::Archetype for Boxes3D { } else { None }; - let quaternions = - if let Some(array) = arrays_by_name.get("rerun.components.PoseRotationQuat") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Boxes3D#quaternions")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Boxes3D#quaternions")? - }) - } else { - None - }; - let colors = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let quaternions = if let Some(array) = arrays_by_descr.get(&Self::descriptor_quaternions()) + { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.Boxes3D#quaternions")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.archetypes.Boxes3D#quaternions")? + }) + } else { + None + }; + let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Boxes3D#colors")? @@ -384,7 +380,7 @@ impl ::re_types_core::Archetype for Boxes3D { } else { None }; - let radii = if let Some(array) = arrays_by_name.get("rerun.components.Radius") { + let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Boxes3D#radii")? @@ -396,7 +392,7 @@ impl ::re_types_core::Archetype for Boxes3D { } else { None }; - let fill_mode = if let Some(array) = arrays_by_name.get("rerun.components.FillMode") { + let fill_mode = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fill_mode()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Boxes3D#fill_mode")? .into_iter() @@ -405,7 +401,7 @@ impl ::re_types_core::Archetype for Boxes3D { } else { None }; - let labels = if let Some(array) = arrays_by_name.get("rerun.components.Text") { + let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Boxes3D#labels")? @@ -417,7 +413,8 @@ impl ::re_types_core::Archetype for Boxes3D { } else { None }; - let show_labels = if let Some(array) = arrays_by_name.get("rerun.components.ShowLabels") { + let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) + { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Boxes3D#show_labels")? .into_iter() @@ -426,7 +423,7 @@ impl ::re_types_core::Archetype for Boxes3D { } else { None }; - let class_ids = if let Some(array) = arrays_by_name.get("rerun.components.ClassId") { + let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Boxes3D#class_ids")? diff --git a/crates/store/re_types/src/archetypes/capsules3d.rs b/crates/store/re_types/src/archetypes/capsules3d.rs index cde7146f436e..6cfdb3123738 100644 --- a/crates/store/re_types/src/archetypes/capsules3d.rs +++ b/crates/store/re_types/src/archetypes/capsules3d.rs @@ -307,17 +307,14 @@ impl ::re_types_core::Archetype for Capsules3D { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let lengths = { - let array = arrays_by_name - .get("rerun.components.Length") + let array = arrays_by_descr + .get(&Self::descriptor_lengths()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Capsules3D#lengths")?; ::from_arrow_opt(&**array) @@ -328,8 +325,8 @@ impl ::re_types_core::Archetype for Capsules3D { .with_context("rerun.archetypes.Capsules3D#lengths")? }; let radii = { - let array = arrays_by_name - .get("rerun.components.Radius") + let array = arrays_by_descr + .get(&Self::descriptor_radii()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Capsules3D#radii")?; ::from_arrow_opt(&**array) @@ -340,7 +337,7 @@ impl ::re_types_core::Archetype for Capsules3D { .with_context("rerun.archetypes.Capsules3D#radii")? }; let translations = - if let Some(array) = arrays_by_name.get("rerun.components.PoseTranslation3D") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_translations()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Capsules3D#translations")? @@ -353,7 +350,7 @@ impl ::re_types_core::Archetype for Capsules3D { None }; let rotation_axis_angles = - if let Some(array) = arrays_by_name.get("rerun.components.PoseRotationAxisAngle") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_rotation_axis_angles()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Capsules3D#rotation_axis_angles")? @@ -365,20 +362,20 @@ impl ::re_types_core::Archetype for Capsules3D { } else { None }; - let quaternions = - if let Some(array) = arrays_by_name.get("rerun.components.PoseRotationQuat") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Capsules3D#quaternions")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Capsules3D#quaternions")? - }) - } else { - None - }; - let colors = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let quaternions = if let Some(array) = arrays_by_descr.get(&Self::descriptor_quaternions()) + { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.Capsules3D#quaternions")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.archetypes.Capsules3D#quaternions")? + }) + } else { + None + }; + let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Capsules3D#colors")? @@ -390,7 +387,7 @@ impl ::re_types_core::Archetype for Capsules3D { } else { None }; - let labels = if let Some(array) = arrays_by_name.get("rerun.components.Text") { + let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Capsules3D#labels")? @@ -402,7 +399,8 @@ impl ::re_types_core::Archetype for Capsules3D { } else { None }; - let show_labels = if let Some(array) = arrays_by_name.get("rerun.components.ShowLabels") { + let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) + { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Capsules3D#show_labels")? .into_iter() @@ -411,7 +409,7 @@ impl ::re_types_core::Archetype for Capsules3D { } else { None }; - let class_ids = if let Some(array) = arrays_by_name.get("rerun.components.ClassId") { + let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Capsules3D#class_ids")? diff --git a/crates/store/re_types/src/archetypes/depth_image.rs b/crates/store/re_types/src/archetypes/depth_image.rs index 11beeea781fd..0ea59252fcee 100644 --- a/crates/store/re_types/src/archetypes/depth_image.rs +++ b/crates/store/re_types/src/archetypes/depth_image.rs @@ -281,17 +281,14 @@ impl ::re_types_core::Archetype for DepthImage { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let buffer = { - let array = arrays_by_name - .get("rerun.components.ImageBuffer") + let array = arrays_by_descr + .get(&Self::descriptor_buffer()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.DepthImage#buffer")?; ::from_arrow_opt(&**array) @@ -303,8 +300,8 @@ impl ::re_types_core::Archetype for DepthImage { .with_context("rerun.archetypes.DepthImage#buffer")? }; let format = { - let array = arrays_by_name - .get("rerun.components.ImageFormat") + let array = arrays_by_descr + .get(&Self::descriptor_format()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.DepthImage#format")?; ::from_arrow_opt(&**array) @@ -315,7 +312,7 @@ impl ::re_types_core::Archetype for DepthImage { .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.DepthImage#format")? }; - let meter = if let Some(array) = arrays_by_name.get("rerun.components.DepthMeter") { + let meter = if let Some(array) = arrays_by_descr.get(&Self::descriptor_meter()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.DepthImage#meter")? .into_iter() @@ -324,7 +321,7 @@ impl ::re_types_core::Archetype for DepthImage { } else { None }; - let colormap = if let Some(array) = arrays_by_name.get("rerun.components.Colormap") { + let colormap = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colormap()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.DepthImage#colormap")? .into_iter() @@ -333,7 +330,8 @@ impl ::re_types_core::Archetype for DepthImage { } else { None }; - let depth_range = if let Some(array) = arrays_by_name.get("rerun.components.ValueRange") { + let depth_range = if let Some(array) = arrays_by_descr.get(&Self::descriptor_depth_range()) + { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.DepthImage#depth_range")? .into_iter() @@ -342,17 +340,17 @@ impl ::re_types_core::Archetype for DepthImage { } else { None }; - let point_fill_ratio = if let Some(array) = arrays_by_name.get("rerun.components.FillRatio") - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.DepthImage#point_fill_ratio")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let draw_order = if let Some(array) = arrays_by_name.get("rerun.components.DrawOrder") { + let point_fill_ratio = + if let Some(array) = arrays_by_descr.get(&Self::descriptor_point_fill_ratio()) { + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.DepthImage#point_fill_ratio")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let draw_order = if let Some(array) = arrays_by_descr.get(&Self::descriptor_draw_order()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.DepthImage#draw_order")? .into_iter() diff --git a/crates/store/re_types/src/archetypes/ellipsoids3d.rs b/crates/store/re_types/src/archetypes/ellipsoids3d.rs index 298b0dc8c72f..ef5863d567b4 100644 --- a/crates/store/re_types/src/archetypes/ellipsoids3d.rs +++ b/crates/store/re_types/src/archetypes/ellipsoids3d.rs @@ -328,17 +328,14 @@ impl ::re_types_core::Archetype for Ellipsoids3D { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let half_sizes = { - let array = arrays_by_name - .get("rerun.components.HalfSize3D") + let array = arrays_by_descr + .get(&Self::descriptor_half_sizes()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Ellipsoids3D#half_sizes")?; ::from_arrow_opt(&**array) @@ -348,8 +345,7 @@ impl ::re_types_core::Archetype for Ellipsoids3D { .collect::>>() .with_context("rerun.archetypes.Ellipsoids3D#half_sizes")? }; - let centers = if let Some(array) = arrays_by_name.get("rerun.components.PoseTranslation3D") - { + let centers = if let Some(array) = arrays_by_descr.get(&Self::descriptor_centers()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Ellipsoids3D#centers")? @@ -362,7 +358,7 @@ impl ::re_types_core::Archetype for Ellipsoids3D { None }; let rotation_axis_angles = - if let Some(array) = arrays_by_name.get("rerun.components.PoseRotationAxisAngle") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_rotation_axis_angles()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Ellipsoids3D#rotation_axis_angles")? @@ -374,20 +370,20 @@ impl ::re_types_core::Archetype for Ellipsoids3D { } else { None }; - let quaternions = - if let Some(array) = arrays_by_name.get("rerun.components.PoseRotationQuat") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Ellipsoids3D#quaternions")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Ellipsoids3D#quaternions")? - }) - } else { - None - }; - let colors = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let quaternions = if let Some(array) = arrays_by_descr.get(&Self::descriptor_quaternions()) + { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.Ellipsoids3D#quaternions")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.archetypes.Ellipsoids3D#quaternions")? + }) + } else { + None + }; + let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Ellipsoids3D#colors")? @@ -399,7 +395,7 @@ impl ::re_types_core::Archetype for Ellipsoids3D { } else { None }; - let line_radii = if let Some(array) = arrays_by_name.get("rerun.components.Radius") { + let line_radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_line_radii()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Ellipsoids3D#line_radii")? @@ -411,7 +407,7 @@ impl ::re_types_core::Archetype for Ellipsoids3D { } else { None }; - let fill_mode = if let Some(array) = arrays_by_name.get("rerun.components.FillMode") { + let fill_mode = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fill_mode()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Ellipsoids3D#fill_mode")? .into_iter() @@ -420,7 +416,7 @@ impl ::re_types_core::Archetype for Ellipsoids3D { } else { None }; - let labels = if let Some(array) = arrays_by_name.get("rerun.components.Text") { + let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Ellipsoids3D#labels")? @@ -432,7 +428,8 @@ impl ::re_types_core::Archetype for Ellipsoids3D { } else { None }; - let show_labels = if let Some(array) = arrays_by_name.get("rerun.components.ShowLabels") { + let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) + { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Ellipsoids3D#show_labels")? .into_iter() @@ -441,7 +438,7 @@ impl ::re_types_core::Archetype for Ellipsoids3D { } else { None }; - let class_ids = if let Some(array) = arrays_by_name.get("rerun.components.ClassId") { + let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Ellipsoids3D#class_ids")? diff --git a/crates/store/re_types/src/archetypes/encoded_image.rs b/crates/store/re_types/src/archetypes/encoded_image.rs index 06cbdfc4fe80..795213edfd25 100644 --- a/crates/store/re_types/src/archetypes/encoded_image.rs +++ b/crates/store/re_types/src/archetypes/encoded_image.rs @@ -197,17 +197,14 @@ impl ::re_types_core::Archetype for EncodedImage { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let blob = { - let array = arrays_by_name - .get("rerun.components.Blob") + let array = arrays_by_descr + .get(&Self::descriptor_blob()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.EncodedImage#blob")?; ::from_arrow_opt(&**array) @@ -218,7 +215,7 @@ impl ::re_types_core::Archetype for EncodedImage { .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.EncodedImage#blob")? }; - let media_type = if let Some(array) = arrays_by_name.get("rerun.components.MediaType") { + let media_type = if let Some(array) = arrays_by_descr.get(&Self::descriptor_media_type()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.EncodedImage#media_type")? .into_iter() @@ -227,7 +224,7 @@ impl ::re_types_core::Archetype for EncodedImage { } else { None }; - let opacity = if let Some(array) = arrays_by_name.get("rerun.components.Opacity") { + let opacity = if let Some(array) = arrays_by_descr.get(&Self::descriptor_opacity()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.EncodedImage#opacity")? .into_iter() @@ -236,7 +233,7 @@ impl ::re_types_core::Archetype for EncodedImage { } else { None }; - let draw_order = if let Some(array) = arrays_by_name.get("rerun.components.DrawOrder") { + let draw_order = if let Some(array) = arrays_by_descr.get(&Self::descriptor_draw_order()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.EncodedImage#draw_order")? .into_iter() diff --git a/crates/store/re_types/src/archetypes/geo_line_strings.rs b/crates/store/re_types/src/archetypes/geo_line_strings.rs index 31b18ba53665..362e813bb0f7 100644 --- a/crates/store/re_types/src/archetypes/geo_line_strings.rs +++ b/crates/store/re_types/src/archetypes/geo_line_strings.rs @@ -185,17 +185,14 @@ impl ::re_types_core::Archetype for GeoLineStrings { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let line_strings = { - let array = arrays_by_name - .get("rerun.components.GeoLineString") + let array = arrays_by_descr + .get(&Self::descriptor_line_strings()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.GeoLineStrings#line_strings")?; ::from_arrow_opt(&**array) @@ -205,7 +202,7 @@ impl ::re_types_core::Archetype for GeoLineStrings { .collect::>>() .with_context("rerun.archetypes.GeoLineStrings#line_strings")? }; - let radii = if let Some(array) = arrays_by_name.get("rerun.components.Radius") { + let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.GeoLineStrings#radii")? @@ -217,7 +214,7 @@ impl ::re_types_core::Archetype for GeoLineStrings { } else { None }; - let colors = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.GeoLineStrings#colors")? diff --git a/crates/store/re_types/src/archetypes/geo_points.rs b/crates/store/re_types/src/archetypes/geo_points.rs index 80f8c1e41005..1934ade73f87 100644 --- a/crates/store/re_types/src/archetypes/geo_points.rs +++ b/crates/store/re_types/src/archetypes/geo_points.rs @@ -192,17 +192,14 @@ impl ::re_types_core::Archetype for GeoPoints { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let positions = { - let array = arrays_by_name - .get("rerun.components.LatLon") + let array = arrays_by_descr + .get(&Self::descriptor_positions()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.GeoPoints#positions")?; ::from_arrow_opt(&**array) @@ -212,7 +209,7 @@ impl ::re_types_core::Archetype for GeoPoints { .collect::>>() .with_context("rerun.archetypes.GeoPoints#positions")? }; - let radii = if let Some(array) = arrays_by_name.get("rerun.components.Radius") { + let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.GeoPoints#radii")? @@ -224,7 +221,7 @@ impl ::re_types_core::Archetype for GeoPoints { } else { None }; - let colors = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.GeoPoints#colors")? @@ -236,7 +233,7 @@ impl ::re_types_core::Archetype for GeoPoints { } else { None }; - let class_ids = if let Some(array) = arrays_by_name.get("rerun.components.ClassId") { + let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.GeoPoints#class_ids")? diff --git a/crates/store/re_types/src/archetypes/graph_edges.rs b/crates/store/re_types/src/archetypes/graph_edges.rs index 6371259a5cdf..10b9b0a24b66 100644 --- a/crates/store/re_types/src/archetypes/graph_edges.rs +++ b/crates/store/re_types/src/archetypes/graph_edges.rs @@ -166,17 +166,14 @@ impl ::re_types_core::Archetype for GraphEdges { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let edges = { - let array = arrays_by_name - .get("rerun.components.GraphEdge") + let array = arrays_by_descr + .get(&Self::descriptor_edges()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.GraphEdges#edges")?; ::from_arrow_opt(&**array) @@ -186,7 +183,7 @@ impl ::re_types_core::Archetype for GraphEdges { .collect::>>() .with_context("rerun.archetypes.GraphEdges#edges")? }; - let graph_type = if let Some(array) = arrays_by_name.get("rerun.components.GraphType") { + let graph_type = if let Some(array) = arrays_by_descr.get(&Self::descriptor_graph_type()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.GraphEdges#graph_type")? .into_iter() diff --git a/crates/store/re_types/src/archetypes/graph_nodes.rs b/crates/store/re_types/src/archetypes/graph_nodes.rs index 8186855da835..176e1bb55730 100644 --- a/crates/store/re_types/src/archetypes/graph_nodes.rs +++ b/crates/store/re_types/src/archetypes/graph_nodes.rs @@ -221,17 +221,14 @@ impl ::re_types_core::Archetype for GraphNodes { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let node_ids = { - let array = arrays_by_name - .get("rerun.components.GraphNode") + let array = arrays_by_descr + .get(&Self::descriptor_node_ids()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.GraphNodes#node_ids")?; ::from_arrow_opt(&**array) @@ -241,7 +238,7 @@ impl ::re_types_core::Archetype for GraphNodes { .collect::>>() .with_context("rerun.archetypes.GraphNodes#node_ids")? }; - let positions = if let Some(array) = arrays_by_name.get("rerun.components.Position2D") { + let positions = if let Some(array) = arrays_by_descr.get(&Self::descriptor_positions()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.GraphNodes#positions")? @@ -253,7 +250,7 @@ impl ::re_types_core::Archetype for GraphNodes { } else { None }; - let colors = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.GraphNodes#colors")? @@ -265,7 +262,7 @@ impl ::re_types_core::Archetype for GraphNodes { } else { None }; - let labels = if let Some(array) = arrays_by_name.get("rerun.components.Text") { + let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.GraphNodes#labels")? @@ -277,7 +274,8 @@ impl ::re_types_core::Archetype for GraphNodes { } else { None }; - let show_labels = if let Some(array) = arrays_by_name.get("rerun.components.ShowLabels") { + let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) + { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.GraphNodes#show_labels")? .into_iter() @@ -286,7 +284,7 @@ impl ::re_types_core::Archetype for GraphNodes { } else { None }; - let radii = if let Some(array) = arrays_by_name.get("rerun.components.Radius") { + let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.GraphNodes#radii")? diff --git a/crates/store/re_types/src/archetypes/image.rs b/crates/store/re_types/src/archetypes/image.rs index 25d6705fcbca..6e0ee68ab5c3 100644 --- a/crates/store/re_types/src/archetypes/image.rs +++ b/crates/store/re_types/src/archetypes/image.rs @@ -266,17 +266,14 @@ impl ::re_types_core::Archetype for Image { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let buffer = { - let array = arrays_by_name - .get("rerun.components.ImageBuffer") + let array = arrays_by_descr + .get(&Self::descriptor_buffer()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Image#buffer")?; ::from_arrow_opt(&**array) @@ -288,8 +285,8 @@ impl ::re_types_core::Archetype for Image { .with_context("rerun.archetypes.Image#buffer")? }; let format = { - let array = arrays_by_name - .get("rerun.components.ImageFormat") + let array = arrays_by_descr + .get(&Self::descriptor_format()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Image#format")?; ::from_arrow_opt(&**array) @@ -300,7 +297,7 @@ impl ::re_types_core::Archetype for Image { .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Image#format")? }; - let opacity = if let Some(array) = arrays_by_name.get("rerun.components.Opacity") { + let opacity = if let Some(array) = arrays_by_descr.get(&Self::descriptor_opacity()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Image#opacity")? .into_iter() @@ -309,7 +306,7 @@ impl ::re_types_core::Archetype for Image { } else { None }; - let draw_order = if let Some(array) = arrays_by_name.get("rerun.components.DrawOrder") { + let draw_order = if let Some(array) = arrays_by_descr.get(&Self::descriptor_draw_order()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Image#draw_order")? .into_iter() diff --git a/crates/store/re_types/src/archetypes/instance_poses3d.rs b/crates/store/re_types/src/archetypes/instance_poses3d.rs index b4bcf815c838..b1d4dd13f7a5 100644 --- a/crates/store/re_types/src/archetypes/instance_poses3d.rs +++ b/crates/store/re_types/src/archetypes/instance_poses3d.rs @@ -248,16 +248,13 @@ impl ::re_types_core::Archetype for InstancePoses3D { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let translations = - if let Some(array) = arrays_by_name.get("rerun.components.PoseTranslation3D") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_translations()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.InstancePoses3D#translations")? @@ -270,7 +267,7 @@ impl ::re_types_core::Archetype for InstancePoses3D { None }; let rotation_axis_angles = - if let Some(array) = arrays_by_name.get("rerun.components.PoseRotationAxisAngle") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_rotation_axis_angles()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.InstancePoses3D#rotation_axis_angles")? @@ -282,20 +279,20 @@ impl ::re_types_core::Archetype for InstancePoses3D { } else { None }; - let quaternions = - if let Some(array) = arrays_by_name.get("rerun.components.PoseRotationQuat") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.InstancePoses3D#quaternions")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.InstancePoses3D#quaternions")? - }) - } else { - None - }; - let scales = if let Some(array) = arrays_by_name.get("rerun.components.PoseScale3D") { + let quaternions = if let Some(array) = arrays_by_descr.get(&Self::descriptor_quaternions()) + { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.InstancePoses3D#quaternions")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.archetypes.InstancePoses3D#quaternions")? + }) + } else { + None + }; + let scales = if let Some(array) = arrays_by_descr.get(&Self::descriptor_scales()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.InstancePoses3D#scales")? @@ -307,8 +304,7 @@ impl ::re_types_core::Archetype for InstancePoses3D { } else { None }; - let mat3x3 = if let Some(array) = arrays_by_name.get("rerun.components.PoseTransformMat3x3") - { + let mat3x3 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_mat3x3()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.InstancePoses3D#mat3x3")? diff --git a/crates/store/re_types/src/archetypes/line_strips2d.rs b/crates/store/re_types/src/archetypes/line_strips2d.rs index f59c7b2fe77b..0280b098c209 100644 --- a/crates/store/re_types/src/archetypes/line_strips2d.rs +++ b/crates/store/re_types/src/archetypes/line_strips2d.rs @@ -283,17 +283,14 @@ impl ::re_types_core::Archetype for LineStrips2D { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let strips = { - let array = arrays_by_name - .get("rerun.components.LineStrip2D") + let array = arrays_by_descr + .get(&Self::descriptor_strips()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.LineStrips2D#strips")?; ::from_arrow_opt(&**array) @@ -303,7 +300,7 @@ impl ::re_types_core::Archetype for LineStrips2D { .collect::>>() .with_context("rerun.archetypes.LineStrips2D#strips")? }; - let radii = if let Some(array) = arrays_by_name.get("rerun.components.Radius") { + let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.LineStrips2D#radii")? @@ -315,7 +312,7 @@ impl ::re_types_core::Archetype for LineStrips2D { } else { None }; - let colors = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.LineStrips2D#colors")? @@ -327,7 +324,7 @@ impl ::re_types_core::Archetype for LineStrips2D { } else { None }; - let labels = if let Some(array) = arrays_by_name.get("rerun.components.Text") { + let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.LineStrips2D#labels")? @@ -339,7 +336,8 @@ impl ::re_types_core::Archetype for LineStrips2D { } else { None }; - let show_labels = if let Some(array) = arrays_by_name.get("rerun.components.ShowLabels") { + let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) + { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.LineStrips2D#show_labels")? .into_iter() @@ -348,7 +346,7 @@ impl ::re_types_core::Archetype for LineStrips2D { } else { None }; - let draw_order = if let Some(array) = arrays_by_name.get("rerun.components.DrawOrder") { + let draw_order = if let Some(array) = arrays_by_descr.get(&Self::descriptor_draw_order()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.LineStrips2D#draw_order")? .into_iter() @@ -357,7 +355,7 @@ impl ::re_types_core::Archetype for LineStrips2D { } else { None }; - let class_ids = if let Some(array) = arrays_by_name.get("rerun.components.ClassId") { + let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.LineStrips2D#class_ids")? diff --git a/crates/store/re_types/src/archetypes/line_strips3d.rs b/crates/store/re_types/src/archetypes/line_strips3d.rs index c9d3c89ed9b9..e7b70cd37243 100644 --- a/crates/store/re_types/src/archetypes/line_strips3d.rs +++ b/crates/store/re_types/src/archetypes/line_strips3d.rs @@ -279,17 +279,14 @@ impl ::re_types_core::Archetype for LineStrips3D { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let strips = { - let array = arrays_by_name - .get("rerun.components.LineStrip3D") + let array = arrays_by_descr + .get(&Self::descriptor_strips()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.LineStrips3D#strips")?; ::from_arrow_opt(&**array) @@ -299,7 +296,7 @@ impl ::re_types_core::Archetype for LineStrips3D { .collect::>>() .with_context("rerun.archetypes.LineStrips3D#strips")? }; - let radii = if let Some(array) = arrays_by_name.get("rerun.components.Radius") { + let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.LineStrips3D#radii")? @@ -311,7 +308,7 @@ impl ::re_types_core::Archetype for LineStrips3D { } else { None }; - let colors = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.LineStrips3D#colors")? @@ -323,7 +320,7 @@ impl ::re_types_core::Archetype for LineStrips3D { } else { None }; - let labels = if let Some(array) = arrays_by_name.get("rerun.components.Text") { + let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.LineStrips3D#labels")? @@ -335,7 +332,8 @@ impl ::re_types_core::Archetype for LineStrips3D { } else { None }; - let show_labels = if let Some(array) = arrays_by_name.get("rerun.components.ShowLabels") { + let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) + { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.LineStrips3D#show_labels")? .into_iter() @@ -344,7 +342,7 @@ impl ::re_types_core::Archetype for LineStrips3D { } else { None }; - let class_ids = if let Some(array) = arrays_by_name.get("rerun.components.ClassId") { + let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.LineStrips3D#class_ids")? diff --git a/crates/store/re_types/src/archetypes/mesh3d.rs b/crates/store/re_types/src/archetypes/mesh3d.rs index 5093db01c82e..c6cd40cb1b7c 100644 --- a/crates/store/re_types/src/archetypes/mesh3d.rs +++ b/crates/store/re_types/src/archetypes/mesh3d.rs @@ -336,17 +336,14 @@ impl ::re_types_core::Archetype for Mesh3D { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let vertex_positions = { - let array = arrays_by_name - .get("rerun.components.Position3D") + let array = arrays_by_descr + .get(&Self::descriptor_vertex_positions()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Mesh3D#vertex_positions")?; ::from_arrow_opt(&**array) @@ -357,7 +354,7 @@ impl ::re_types_core::Archetype for Mesh3D { .with_context("rerun.archetypes.Mesh3D#vertex_positions")? }; let triangle_indices = - if let Some(array) = arrays_by_name.get("rerun.components.TriangleIndices") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_triangle_indices()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Mesh3D#triangle_indices")? @@ -369,32 +366,34 @@ impl ::re_types_core::Archetype for Mesh3D { } else { None }; - let vertex_normals = if let Some(array) = arrays_by_name.get("rerun.components.Vector3D") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Mesh3D#vertex_normals")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Mesh3D#vertex_normals")? - }) - } else { - None - }; - let vertex_colors = if let Some(array) = arrays_by_name.get("rerun.components.Color") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Mesh3D#vertex_colors")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Mesh3D#vertex_colors")? - }) - } else { - None - }; + let vertex_normals = + if let Some(array) = arrays_by_descr.get(&Self::descriptor_vertex_normals()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.Mesh3D#vertex_normals")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.archetypes.Mesh3D#vertex_normals")? + }) + } else { + None + }; + let vertex_colors = + if let Some(array) = arrays_by_descr.get(&Self::descriptor_vertex_colors()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.Mesh3D#vertex_colors")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.archetypes.Mesh3D#vertex_colors")? + }) + } else { + None + }; let vertex_texcoords = - if let Some(array) = arrays_by_name.get("rerun.components.Texcoord2D") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_vertex_texcoords()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Mesh3D#vertex_texcoords")? @@ -406,18 +405,18 @@ impl ::re_types_core::Archetype for Mesh3D { } else { None }; - let albedo_factor = if let Some(array) = arrays_by_name.get("rerun.components.AlbedoFactor") - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Mesh3D#albedo_factor")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let albedo_factor = + if let Some(array) = arrays_by_descr.get(&Self::descriptor_albedo_factor()) { + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.Mesh3D#albedo_factor")? + .into_iter() + .next() + .flatten() + } else { + None + }; let albedo_texture_buffer = - if let Some(array) = arrays_by_name.get("rerun.components.ImageBuffer") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_albedo_texture_buffer()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Mesh3D#albedo_texture_buffer")? .into_iter() @@ -427,7 +426,7 @@ impl ::re_types_core::Archetype for Mesh3D { None }; let albedo_texture_format = - if let Some(array) = arrays_by_name.get("rerun.components.ImageFormat") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_albedo_texture_format()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Mesh3D#albedo_texture_format")? .into_iter() @@ -436,7 +435,7 @@ impl ::re_types_core::Archetype for Mesh3D { } else { None }; - let class_ids = if let Some(array) = arrays_by_name.get("rerun.components.ClassId") { + let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Mesh3D#class_ids")? diff --git a/crates/store/re_types/src/archetypes/pinhole.rs b/crates/store/re_types/src/archetypes/pinhole.rs index 75524c97e438..8e984d718c49 100644 --- a/crates/store/re_types/src/archetypes/pinhole.rs +++ b/crates/store/re_types/src/archetypes/pinhole.rs @@ -267,17 +267,14 @@ impl ::re_types_core::Archetype for Pinhole { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let image_from_camera = { - let array = arrays_by_name - .get("rerun.components.PinholeProjection") + let array = arrays_by_descr + .get(&Self::descriptor_image_from_camera()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Pinhole#image_from_camera")?; ::from_arrow_opt(&**array) @@ -288,7 +285,7 @@ impl ::re_types_core::Archetype for Pinhole { .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Pinhole#image_from_camera")? }; - let resolution = if let Some(array) = arrays_by_name.get("rerun.components.Resolution") { + let resolution = if let Some(array) = arrays_by_descr.get(&Self::descriptor_resolution()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Pinhole#resolution")? .into_iter() @@ -297,8 +294,7 @@ impl ::re_types_core::Archetype for Pinhole { } else { None }; - let camera_xyz = if let Some(array) = arrays_by_name.get("rerun.components.ViewCoordinates") - { + let camera_xyz = if let Some(array) = arrays_by_descr.get(&Self::descriptor_camera_xyz()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Pinhole#camera_xyz")? .into_iter() @@ -308,7 +304,7 @@ impl ::re_types_core::Archetype for Pinhole { None }; let image_plane_distance = - if let Some(array) = arrays_by_name.get("rerun.components.ImagePlaneDistance") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_image_plane_distance()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Pinhole#image_plane_distance")? .into_iter() diff --git a/crates/store/re_types/src/archetypes/points2d.rs b/crates/store/re_types/src/archetypes/points2d.rs index dbadf1148a63..3aaa10eb1946 100644 --- a/crates/store/re_types/src/archetypes/points2d.rs +++ b/crates/store/re_types/src/archetypes/points2d.rs @@ -316,17 +316,14 @@ impl ::re_types_core::Archetype for Points2D { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let positions = { - let array = arrays_by_name - .get("rerun.components.Position2D") + let array = arrays_by_descr + .get(&Self::descriptor_positions()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Points2D#positions")?; ::from_arrow_opt(&**array) @@ -336,7 +333,7 @@ impl ::re_types_core::Archetype for Points2D { .collect::>>() .with_context("rerun.archetypes.Points2D#positions")? }; - let radii = if let Some(array) = arrays_by_name.get("rerun.components.Radius") { + let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Points2D#radii")? @@ -348,7 +345,7 @@ impl ::re_types_core::Archetype for Points2D { } else { None }; - let colors = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Points2D#colors")? @@ -360,7 +357,7 @@ impl ::re_types_core::Archetype for Points2D { } else { None }; - let labels = if let Some(array) = arrays_by_name.get("rerun.components.Text") { + let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Points2D#labels")? @@ -372,7 +369,8 @@ impl ::re_types_core::Archetype for Points2D { } else { None }; - let show_labels = if let Some(array) = arrays_by_name.get("rerun.components.ShowLabels") { + let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) + { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Points2D#show_labels")? .into_iter() @@ -381,7 +379,7 @@ impl ::re_types_core::Archetype for Points2D { } else { None }; - let draw_order = if let Some(array) = arrays_by_name.get("rerun.components.DrawOrder") { + let draw_order = if let Some(array) = arrays_by_descr.get(&Self::descriptor_draw_order()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Points2D#draw_order")? .into_iter() @@ -390,7 +388,7 @@ impl ::re_types_core::Archetype for Points2D { } else { None }; - let class_ids = if let Some(array) = arrays_by_name.get("rerun.components.ClassId") { + let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Points2D#class_ids")? @@ -402,18 +400,19 @@ impl ::re_types_core::Archetype for Points2D { } else { None }; - let keypoint_ids = if let Some(array) = arrays_by_name.get("rerun.components.KeypointId") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points2D#keypoint_ids")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Points2D#keypoint_ids")? - }) - } else { - None - }; + let keypoint_ids = + if let Some(array) = arrays_by_descr.get(&Self::descriptor_keypoint_ids()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.Points2D#keypoint_ids")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.archetypes.Points2D#keypoint_ids")? + }) + } else { + None + }; Ok(Self { positions, radii, diff --git a/crates/store/re_types/src/archetypes/points3d.rs b/crates/store/re_types/src/archetypes/points3d.rs index 4e51d42badb5..33bd5bcaa3bc 100644 --- a/crates/store/re_types/src/archetypes/points3d.rs +++ b/crates/store/re_types/src/archetypes/points3d.rs @@ -297,17 +297,14 @@ impl ::re_types_core::Archetype for Points3D { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let positions = { - let array = arrays_by_name - .get("rerun.components.Position3D") + let array = arrays_by_descr + .get(&Self::descriptor_positions()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Points3D#positions")?; ::from_arrow_opt(&**array) @@ -317,7 +314,7 @@ impl ::re_types_core::Archetype for Points3D { .collect::>>() .with_context("rerun.archetypes.Points3D#positions")? }; - let radii = if let Some(array) = arrays_by_name.get("rerun.components.Radius") { + let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Points3D#radii")? @@ -329,7 +326,7 @@ impl ::re_types_core::Archetype for Points3D { } else { None }; - let colors = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Points3D#colors")? @@ -341,7 +338,7 @@ impl ::re_types_core::Archetype for Points3D { } else { None }; - let labels = if let Some(array) = arrays_by_name.get("rerun.components.Text") { + let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Points3D#labels")? @@ -353,7 +350,8 @@ impl ::re_types_core::Archetype for Points3D { } else { None }; - let show_labels = if let Some(array) = arrays_by_name.get("rerun.components.ShowLabels") { + let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) + { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Points3D#show_labels")? .into_iter() @@ -362,7 +360,7 @@ impl ::re_types_core::Archetype for Points3D { } else { None }; - let class_ids = if let Some(array) = arrays_by_name.get("rerun.components.ClassId") { + let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Points3D#class_ids")? @@ -374,18 +372,19 @@ impl ::re_types_core::Archetype for Points3D { } else { None }; - let keypoint_ids = if let Some(array) = arrays_by_name.get("rerun.components.KeypointId") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points3D#keypoint_ids")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Points3D#keypoint_ids")? - }) - } else { - None - }; + let keypoint_ids = + if let Some(array) = arrays_by_descr.get(&Self::descriptor_keypoint_ids()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.Points3D#keypoint_ids")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.archetypes.Points3D#keypoint_ids")? + }) + } else { + None + }; Ok(Self { positions, radii, diff --git a/crates/store/re_types/src/archetypes/scalar.rs b/crates/store/re_types/src/archetypes/scalar.rs index 24f92629f31f..32c439cdeba4 100644 --- a/crates/store/re_types/src/archetypes/scalar.rs +++ b/crates/store/re_types/src/archetypes/scalar.rs @@ -142,17 +142,14 @@ impl ::re_types_core::Archetype for Scalar { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let scalar = { - let array = arrays_by_name - .get("rerun.components.Scalar") + let array = arrays_by_descr + .get(&Self::descriptor_scalar()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Scalar#scalar")?; ::from_arrow_opt(&**array) diff --git a/crates/store/re_types/src/archetypes/segmentation_image.rs b/crates/store/re_types/src/archetypes/segmentation_image.rs index f852817c0175..139115f765d1 100644 --- a/crates/store/re_types/src/archetypes/segmentation_image.rs +++ b/crates/store/re_types/src/archetypes/segmentation_image.rs @@ -214,17 +214,14 @@ impl ::re_types_core::Archetype for SegmentationImage { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let buffer = { - let array = arrays_by_name - .get("rerun.components.ImageBuffer") + let array = arrays_by_descr + .get(&Self::descriptor_buffer()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.SegmentationImage#buffer")?; ::from_arrow_opt(&**array) @@ -236,8 +233,8 @@ impl ::re_types_core::Archetype for SegmentationImage { .with_context("rerun.archetypes.SegmentationImage#buffer")? }; let format = { - let array = arrays_by_name - .get("rerun.components.ImageFormat") + let array = arrays_by_descr + .get(&Self::descriptor_format()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.SegmentationImage#format")?; ::from_arrow_opt(&**array) @@ -248,7 +245,7 @@ impl ::re_types_core::Archetype for SegmentationImage { .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.SegmentationImage#format")? }; - let opacity = if let Some(array) = arrays_by_name.get("rerun.components.Opacity") { + let opacity = if let Some(array) = arrays_by_descr.get(&Self::descriptor_opacity()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.SegmentationImage#opacity")? .into_iter() @@ -257,7 +254,7 @@ impl ::re_types_core::Archetype for SegmentationImage { } else { None }; - let draw_order = if let Some(array) = arrays_by_name.get("rerun.components.DrawOrder") { + let draw_order = if let Some(array) = arrays_by_descr.get(&Self::descriptor_draw_order()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.SegmentationImage#draw_order")? .into_iter() diff --git a/crates/store/re_types/src/archetypes/series_line.rs b/crates/store/re_types/src/archetypes/series_line.rs index 0f6407314bdb..a19722217d34 100644 --- a/crates/store/re_types/src/archetypes/series_line.rs +++ b/crates/store/re_types/src/archetypes/series_line.rs @@ -218,15 +218,12 @@ impl ::re_types_core::Archetype for SeriesLine { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let color = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let color = if let Some(array) = arrays_by_descr.get(&Self::descriptor_color()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.SeriesLine#color")? .into_iter() @@ -235,7 +232,7 @@ impl ::re_types_core::Archetype for SeriesLine { } else { None }; - let width = if let Some(array) = arrays_by_name.get("rerun.components.StrokeWidth") { + let width = if let Some(array) = arrays_by_descr.get(&Self::descriptor_width()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.SeriesLine#width")? .into_iter() @@ -244,7 +241,7 @@ impl ::re_types_core::Archetype for SeriesLine { } else { None }; - let name = if let Some(array) = arrays_by_name.get("rerun.components.Name") { + let name = if let Some(array) = arrays_by_descr.get(&Self::descriptor_name()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.SeriesLine#name")? .into_iter() @@ -254,7 +251,7 @@ impl ::re_types_core::Archetype for SeriesLine { None }; let aggregation_policy = - if let Some(array) = arrays_by_name.get("rerun.components.AggregationPolicy") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_aggregation_policy()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.SeriesLine#aggregation_policy")? .into_iter() diff --git a/crates/store/re_types/src/archetypes/series_point.rs b/crates/store/re_types/src/archetypes/series_point.rs index 4639279ce0ab..28c4924b984a 100644 --- a/crates/store/re_types/src/archetypes/series_point.rs +++ b/crates/store/re_types/src/archetypes/series_point.rs @@ -216,15 +216,12 @@ impl ::re_types_core::Archetype for SeriesPoint { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let color = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let color = if let Some(array) = arrays_by_descr.get(&Self::descriptor_color()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.SeriesPoint#color")? .into_iter() @@ -233,7 +230,7 @@ impl ::re_types_core::Archetype for SeriesPoint { } else { None }; - let marker = if let Some(array) = arrays_by_name.get("rerun.components.MarkerShape") { + let marker = if let Some(array) = arrays_by_descr.get(&Self::descriptor_marker()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.SeriesPoint#marker")? .into_iter() @@ -242,7 +239,7 @@ impl ::re_types_core::Archetype for SeriesPoint { } else { None }; - let name = if let Some(array) = arrays_by_name.get("rerun.components.Name") { + let name = if let Some(array) = arrays_by_descr.get(&Self::descriptor_name()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.SeriesPoint#name")? .into_iter() @@ -251,7 +248,8 @@ impl ::re_types_core::Archetype for SeriesPoint { } else { None }; - let marker_size = if let Some(array) = arrays_by_name.get("rerun.components.MarkerSize") { + let marker_size = if let Some(array) = arrays_by_descr.get(&Self::descriptor_marker_size()) + { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.SeriesPoint#marker_size")? .into_iter() diff --git a/crates/store/re_types/src/archetypes/tensor.rs b/crates/store/re_types/src/archetypes/tensor.rs index a3e6ab751271..b0a430afa7e3 100644 --- a/crates/store/re_types/src/archetypes/tensor.rs +++ b/crates/store/re_types/src/archetypes/tensor.rs @@ -166,17 +166,14 @@ impl ::re_types_core::Archetype for Tensor { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let data = { - let array = arrays_by_name - .get("rerun.components.TensorData") + let array = arrays_by_descr + .get(&Self::descriptor_data()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Tensor#data")?; ::from_arrow_opt(&**array) @@ -187,7 +184,8 @@ impl ::re_types_core::Archetype for Tensor { .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Tensor#data")? }; - let value_range = if let Some(array) = arrays_by_name.get("rerun.components.ValueRange") { + let value_range = if let Some(array) = arrays_by_descr.get(&Self::descriptor_value_range()) + { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Tensor#value_range")? .into_iter() diff --git a/crates/store/re_types/src/archetypes/text_document.rs b/crates/store/re_types/src/archetypes/text_document.rs index db9e3dbf4dfe..c0163e38bfed 100644 --- a/crates/store/re_types/src/archetypes/text_document.rs +++ b/crates/store/re_types/src/archetypes/text_document.rs @@ -201,17 +201,14 @@ impl ::re_types_core::Archetype for TextDocument { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let text = { - let array = arrays_by_name - .get("rerun.components.Text") + let array = arrays_by_descr + .get(&Self::descriptor_text()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.TextDocument#text")?; ::from_arrow_opt(&**array) @@ -222,7 +219,7 @@ impl ::re_types_core::Archetype for TextDocument { .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.TextDocument#text")? }; - let media_type = if let Some(array) = arrays_by_name.get("rerun.components.MediaType") { + let media_type = if let Some(array) = arrays_by_descr.get(&Self::descriptor_media_type()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.TextDocument#media_type")? .into_iter() diff --git a/crates/store/re_types/src/archetypes/text_log.rs b/crates/store/re_types/src/archetypes/text_log.rs index cd24949847ec..f793585d0764 100644 --- a/crates/store/re_types/src/archetypes/text_log.rs +++ b/crates/store/re_types/src/archetypes/text_log.rs @@ -182,17 +182,14 @@ impl ::re_types_core::Archetype for TextLog { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let text = { - let array = arrays_by_name - .get("rerun.components.Text") + let array = arrays_by_descr + .get(&Self::descriptor_text()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.TextLog#text")?; ::from_arrow_opt(&**array) @@ -203,7 +200,7 @@ impl ::re_types_core::Archetype for TextLog { .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.TextLog#text")? }; - let level = if let Some(array) = arrays_by_name.get("rerun.components.TextLogLevel") { + let level = if let Some(array) = arrays_by_descr.get(&Self::descriptor_level()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.TextLog#level")? .into_iter() @@ -212,7 +209,7 @@ impl ::re_types_core::Archetype for TextLog { } else { None }; - let color = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let color = if let Some(array) = arrays_by_descr.get(&Self::descriptor_color()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.TextLog#color")? .into_iter() diff --git a/crates/store/re_types/src/archetypes/transform3d.rs b/crates/store/re_types/src/archetypes/transform3d.rs index 7314c2e5d726..956b11b83fc4 100644 --- a/crates/store/re_types/src/archetypes/transform3d.rs +++ b/crates/store/re_types/src/archetypes/transform3d.rs @@ -357,15 +357,12 @@ impl ::re_types_core::Archetype for Transform3D { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let translation = if let Some(array) = arrays_by_name.get("rerun.components.Translation3D") + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let translation = if let Some(array) = arrays_by_descr.get(&Self::descriptor_translation()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Transform3D#translation")? @@ -376,7 +373,7 @@ impl ::re_types_core::Archetype for Transform3D { None }; let rotation_axis_angle = - if let Some(array) = arrays_by_name.get("rerun.components.RotationAxisAngle") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_rotation_axis_angle()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Transform3D#rotation_axis_angle")? .into_iter() @@ -385,7 +382,7 @@ impl ::re_types_core::Archetype for Transform3D { } else { None }; - let quaternion = if let Some(array) = arrays_by_name.get("rerun.components.RotationQuat") { + let quaternion = if let Some(array) = arrays_by_descr.get(&Self::descriptor_quaternion()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Transform3D#quaternion")? .into_iter() @@ -394,7 +391,7 @@ impl ::re_types_core::Archetype for Transform3D { } else { None }; - let scale = if let Some(array) = arrays_by_name.get("rerun.components.Scale3D") { + let scale = if let Some(array) = arrays_by_descr.get(&Self::descriptor_scale()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Transform3D#scale")? .into_iter() @@ -403,7 +400,7 @@ impl ::re_types_core::Archetype for Transform3D { } else { None }; - let mat3x3 = if let Some(array) = arrays_by_name.get("rerun.components.TransformMat3x3") { + let mat3x3 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_mat3x3()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Transform3D#mat3x3")? .into_iter() @@ -412,8 +409,7 @@ impl ::re_types_core::Archetype for Transform3D { } else { None }; - let relation = if let Some(array) = arrays_by_name.get("rerun.components.TransformRelation") - { + let relation = if let Some(array) = arrays_by_descr.get(&Self::descriptor_relation()) { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Transform3D#relation")? .into_iter() @@ -422,7 +418,8 @@ impl ::re_types_core::Archetype for Transform3D { } else { None }; - let axis_length = if let Some(array) = arrays_by_name.get("rerun.components.AxisLength") { + let axis_length = if let Some(array) = arrays_by_descr.get(&Self::descriptor_axis_length()) + { ::from_arrow_opt(&**array) .with_context("rerun.archetypes.Transform3D#axis_length")? .into_iter() diff --git a/crates/store/re_types/src/archetypes/video_frame_reference.rs b/crates/store/re_types/src/archetypes/video_frame_reference.rs index c8b97239b437..2afacca0e0cb 100644 --- a/crates/store/re_types/src/archetypes/video_frame_reference.rs +++ b/crates/store/re_types/src/archetypes/video_frame_reference.rs @@ -246,17 +246,14 @@ impl ::re_types_core::Archetype for VideoFrameReference { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let timestamp = { - let array = arrays_by_name - .get("rerun.components.VideoTimestamp") + let array = arrays_by_descr + .get(&Self::descriptor_timestamp()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.VideoFrameReference#timestamp")?; ::from_arrow_opt(&**array) @@ -267,16 +264,16 @@ impl ::re_types_core::Archetype for VideoFrameReference { .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.VideoFrameReference#timestamp")? }; - let video_reference = if let Some(array) = arrays_by_name.get("rerun.components.EntityPath") - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.VideoFrameReference#video_reference")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let video_reference = + if let Some(array) = arrays_by_descr.get(&Self::descriptor_video_reference()) { + ::from_arrow_opt(&**array) + .with_context("rerun.archetypes.VideoFrameReference#video_reference")? + .into_iter() + .next() + .flatten() + } else { + None + }; Ok(Self { timestamp, video_reference, diff --git a/crates/store/re_types/src/archetypes/view_coordinates.rs b/crates/store/re_types/src/archetypes/view_coordinates.rs index b5a7d875c087..f81be2c5a02a 100644 --- a/crates/store/re_types/src/archetypes/view_coordinates.rs +++ b/crates/store/re_types/src/archetypes/view_coordinates.rs @@ -154,17 +154,14 @@ impl ::re_types_core::Archetype for ViewCoordinates { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let xyz = { - let array = arrays_by_name - .get("rerun.components.ViewCoordinates") + let array = arrays_by_descr + .get(&Self::descriptor_xyz()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.ViewCoordinates#xyz")?; ::from_arrow_opt(&**array) diff --git a/crates/store/re_types/src/blueprint/archetypes/background.rs b/crates/store/re_types/src/blueprint/archetypes/background.rs index 57443643507b..7ab89ed7bbbe 100644 --- a/crates/store/re_types/src/blueprint/archetypes/background.rs +++ b/crates/store/re_types/src/blueprint/archetypes/background.rs @@ -127,17 +127,14 @@ impl ::re_types_core::Archetype for Background { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let kind = { - let array = arrays_by_name - .get("rerun.blueprint.components.BackgroundKind") + let array = arrays_by_descr + .get(&Self::descriptor_kind()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.blueprint.archetypes.Background#kind")?; ::from_arrow_opt(&**array) @@ -148,7 +145,7 @@ impl ::re_types_core::Archetype for Background { .ok_or_else(DeserializationError::missing_data) .with_context("rerun.blueprint.archetypes.Background#kind")? }; - let color = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let color = if let Some(array) = arrays_by_descr.get(&Self::descriptor_color()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.Background#color")? .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/container_blueprint.rs b/crates/store/re_types/src/blueprint/archetypes/container_blueprint.rs index 06d88ac97c4d..cf38f7676d7f 100644 --- a/crates/store/re_types/src/blueprint/archetypes/container_blueprint.rs +++ b/crates/store/re_types/src/blueprint/archetypes/container_blueprint.rs @@ -238,17 +238,14 @@ impl ::re_types_core::Archetype for ContainerBlueprint { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let container_kind = { - let array = arrays_by_name - .get("rerun.blueprint.components.ContainerKind") + let array = arrays_by_descr + .get(&Self::descriptor_container_kind()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.blueprint.archetypes.ContainerBlueprint#container_kind")?; ::from_arrow_opt(&**array) @@ -259,66 +256,62 @@ impl ::re_types_core::Archetype for ContainerBlueprint { .ok_or_else(DeserializationError::missing_data) .with_context("rerun.blueprint.archetypes.ContainerBlueprint#container_kind")? }; - let display_name = if let Some(array) = arrays_by_name.get("rerun.components.Name") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ContainerBlueprint#display_name")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let contents = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.IncludedContent") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ContainerBlueprint#contents")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.blueprint.archetypes.ContainerBlueprint#contents")? - }) - } else { - None - }; - let col_shares = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.ColumnShare") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ContainerBlueprint#col_shares")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.blueprint.archetypes.ContainerBlueprint#col_shares")? - }) - } else { - None - }; - let row_shares = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.RowShare") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ContainerBlueprint#row_shares")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.blueprint.archetypes.ContainerBlueprint#row_shares")? - }) - } else { - None - }; - let active_tab = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.ActiveTab") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ContainerBlueprint#active_tab")? + let display_name = + if let Some(array) = arrays_by_descr.get(&Self::descriptor_display_name()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ContainerBlueprint#display_name")? .into_iter() .next() .flatten() } else { None }; - let visible = if let Some(array) = arrays_by_name.get("rerun.blueprint.components.Visible") - { + let contents = if let Some(array) = arrays_by_descr.get(&Self::descriptor_contents()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ContainerBlueprint#contents")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.blueprint.archetypes.ContainerBlueprint#contents")? + }) + } else { + None + }; + let col_shares = if let Some(array) = arrays_by_descr.get(&Self::descriptor_col_shares()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ContainerBlueprint#col_shares")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.blueprint.archetypes.ContainerBlueprint#col_shares")? + }) + } else { + None + }; + let row_shares = if let Some(array) = arrays_by_descr.get(&Self::descriptor_row_shares()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ContainerBlueprint#row_shares")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.blueprint.archetypes.ContainerBlueprint#row_shares")? + }) + } else { + None + }; + let active_tab = if let Some(array) = arrays_by_descr.get(&Self::descriptor_active_tab()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ContainerBlueprint#active_tab")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let visible = if let Some(array) = arrays_by_descr.get(&Self::descriptor_visible()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.ContainerBlueprint#visible")? .into_iter() @@ -328,7 +321,7 @@ impl ::re_types_core::Archetype for ContainerBlueprint { None }; let grid_columns = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.GridColumns") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_grid_columns()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.ContainerBlueprint#grid_columns")? .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/dataframe_query.rs b/crates/store/re_types/src/blueprint/archetypes/dataframe_query.rs index 29d28f4c521b..ffe0a6c419f3 100644 --- a/crates/store/re_types/src/blueprint/archetypes/dataframe_query.rs +++ b/crates/store/re_types/src/blueprint/archetypes/dataframe_query.rs @@ -181,26 +181,22 @@ impl ::re_types_core::Archetype for DataframeQuery { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let timeline = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.TimelineName") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.DataframeQuery#timeline")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let timeline = if let Some(array) = arrays_by_descr.get(&Self::descriptor_timeline()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.DataframeQuery#timeline")? + .into_iter() + .next() + .flatten() + } else { + None + }; let filter_by_range = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.FilterByRange") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_filter_by_range()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.DataframeQuery#filter_by_range")? .into_iter() @@ -210,7 +206,7 @@ impl ::re_types_core::Archetype for DataframeQuery { None }; let filter_is_not_null = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.FilterIsNotNull") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_filter_is_not_null()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.DataframeQuery#filter_is_not_null")? .into_iter() @@ -220,7 +216,7 @@ impl ::re_types_core::Archetype for DataframeQuery { None }; let apply_latest_at = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.ApplyLatestAt") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_apply_latest_at()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.DataframeQuery#apply_latest_at")? .into_iter() @@ -229,16 +225,15 @@ impl ::re_types_core::Archetype for DataframeQuery { } else { None }; - let select = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.SelectedColumns") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.DataframeQuery#select")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let select = if let Some(array) = arrays_by_descr.get(&Self::descriptor_select()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.DataframeQuery#select")? + .into_iter() + .next() + .flatten() + } else { + None + }; Ok(Self { timeline, filter_by_range, diff --git a/crates/store/re_types/src/blueprint/archetypes/force_center.rs b/crates/store/re_types/src/blueprint/archetypes/force_center.rs index b9250ac38e67..0f97a4bb4345 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_center.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_center.rs @@ -134,16 +134,12 @@ impl ::re_types_core::Archetype for ForceCenter { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let enabled = if let Some(array) = arrays_by_name.get("rerun.blueprint.components.Enabled") - { + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let enabled = if let Some(array) = arrays_by_descr.get(&Self::descriptor_enabled()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.ForceCenter#enabled")? .into_iter() @@ -152,16 +148,15 @@ impl ::re_types_core::Archetype for ForceCenter { } else { None }; - let strength = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.ForceStrength") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForceCenter#strength")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let strength = if let Some(array) = arrays_by_descr.get(&Self::descriptor_strength()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ForceCenter#strength")? + .into_iter() + .next() + .flatten() + } else { + None + }; Ok(Self { enabled, strength }) } } diff --git a/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs b/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs index 95eaccbeda11..44cb5548da8f 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs @@ -152,16 +152,12 @@ impl ::re_types_core::Archetype for ForceCollisionRadius { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let enabled = if let Some(array) = arrays_by_name.get("rerun.blueprint.components.Enabled") - { + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let enabled = if let Some(array) = arrays_by_descr.get(&Self::descriptor_enabled()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.ForceCollisionRadius#enabled")? .into_iter() @@ -170,26 +166,24 @@ impl ::re_types_core::Archetype for ForceCollisionRadius { } else { None }; - let strength = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.ForceStrength") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForceCollisionRadius#strength")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let iterations = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.ForceIterations") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForceCollisionRadius#iterations")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let strength = if let Some(array) = arrays_by_descr.get(&Self::descriptor_strength()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ForceCollisionRadius#strength")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let iterations = if let Some(array) = arrays_by_descr.get(&Self::descriptor_iterations()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ForceCollisionRadius#iterations")? + .into_iter() + .next() + .flatten() + } else { + None + }; Ok(Self { enabled, strength, diff --git a/crates/store/re_types/src/blueprint/archetypes/force_link.rs b/crates/store/re_types/src/blueprint/archetypes/force_link.rs index 27fd69040f60..8e1b0e3e8372 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_link.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_link.rs @@ -151,16 +151,12 @@ impl ::re_types_core::Archetype for ForceLink { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let enabled = if let Some(array) = arrays_by_name.get("rerun.blueprint.components.Enabled") - { + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let enabled = if let Some(array) = arrays_by_descr.get(&Self::descriptor_enabled()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.ForceLink#enabled")? .into_iter() @@ -169,26 +165,24 @@ impl ::re_types_core::Archetype for ForceLink { } else { None }; - let distance = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.ForceDistance") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForceLink#distance")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let iterations = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.ForceIterations") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForceLink#iterations")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let distance = if let Some(array) = arrays_by_descr.get(&Self::descriptor_distance()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ForceLink#distance")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let iterations = if let Some(array) = arrays_by_descr.get(&Self::descriptor_iterations()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ForceLink#iterations")? + .into_iter() + .next() + .flatten() + } else { + None + }; Ok(Self { enabled, distance, diff --git a/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs b/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs index 13f305dd6117..ec364a91cea9 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs @@ -139,16 +139,12 @@ impl ::re_types_core::Archetype for ForceManyBody { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let enabled = if let Some(array) = arrays_by_name.get("rerun.blueprint.components.Enabled") - { + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let enabled = if let Some(array) = arrays_by_descr.get(&Self::descriptor_enabled()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.ForceManyBody#enabled")? .into_iter() @@ -157,16 +153,15 @@ impl ::re_types_core::Archetype for ForceManyBody { } else { None }; - let strength = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.ForceStrength") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForceManyBody#strength")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let strength = if let Some(array) = arrays_by_descr.get(&Self::descriptor_strength()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ForceManyBody#strength")? + .into_iter() + .next() + .flatten() + } else { + None + }; Ok(Self { enabled, strength }) } } diff --git a/crates/store/re_types/src/blueprint/archetypes/force_position.rs b/crates/store/re_types/src/blueprint/archetypes/force_position.rs index 6483001f3a90..b2412e4b617b 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_position.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_position.rs @@ -149,16 +149,12 @@ impl ::re_types_core::Archetype for ForcePosition { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let enabled = if let Some(array) = arrays_by_name.get("rerun.blueprint.components.Enabled") - { + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let enabled = if let Some(array) = arrays_by_descr.get(&Self::descriptor_enabled()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.ForcePosition#enabled")? .into_iter() @@ -167,17 +163,16 @@ impl ::re_types_core::Archetype for ForcePosition { } else { None }; - let strength = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.ForceStrength") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForcePosition#strength")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let position = if let Some(array) = arrays_by_name.get("rerun.components.Position2D") { + let strength = if let Some(array) = arrays_by_descr.get(&Self::descriptor_strength()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ForcePosition#strength")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let position = if let Some(array) = arrays_by_descr.get(&Self::descriptor_position()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.ForcePosition#position")? .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs index c1f0781b50e6..496ed5cf92dc 100644 --- a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs +++ b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs @@ -189,16 +189,12 @@ impl ::re_types_core::Archetype for LineGrid3D { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let visible = if let Some(array) = arrays_by_name.get("rerun.blueprint.components.Visible") - { + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let visible = if let Some(array) = arrays_by_descr.get(&Self::descriptor_visible()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.LineGrid3D#visible")? .into_iter() @@ -207,35 +203,35 @@ impl ::re_types_core::Archetype for LineGrid3D { } else { None }; - let spacing = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.GridSpacing") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.LineGrid3D#spacing")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let plane = if let Some(array) = arrays_by_name.get("rerun.components.Plane3D") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.LineGrid3D#plane")? + let spacing = if let Some(array) = arrays_by_descr.get(&Self::descriptor_spacing()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.LineGrid3D#spacing")? .into_iter() .next() .flatten() } else { None }; - let stroke_width = if let Some(array) = arrays_by_name.get("rerun.components.StrokeWidth") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.LineGrid3D#stroke_width")? + let plane = if let Some(array) = arrays_by_descr.get(&Self::descriptor_plane()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.LineGrid3D#plane")? .into_iter() .next() .flatten() } else { None }; - let color = if let Some(array) = arrays_by_name.get("rerun.components.Color") { + let stroke_width = + if let Some(array) = arrays_by_descr.get(&Self::descriptor_stroke_width()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.LineGrid3D#stroke_width")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let color = if let Some(array) = arrays_by_descr.get(&Self::descriptor_color()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.LineGrid3D#color")? .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/map_background.rs b/crates/store/re_types/src/blueprint/archetypes/map_background.rs index 72fecb09f980..cfbd868dfbf6 100644 --- a/crates/store/re_types/src/blueprint/archetypes/map_background.rs +++ b/crates/store/re_types/src/blueprint/archetypes/map_background.rs @@ -115,17 +115,14 @@ impl ::re_types_core::Archetype for MapBackground { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let provider = { - let array = arrays_by_name - .get("rerun.blueprint.components.MapProvider") + let array = arrays_by_descr + .get(&Self::descriptor_provider()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.blueprint.archetypes.MapBackground#provider")?; ::from_arrow_opt(&**array) diff --git a/crates/store/re_types/src/blueprint/archetypes/map_zoom.rs b/crates/store/re_types/src/blueprint/archetypes/map_zoom.rs index 44a9a07a539d..c251ed93accf 100644 --- a/crates/store/re_types/src/blueprint/archetypes/map_zoom.rs +++ b/crates/store/re_types/src/blueprint/archetypes/map_zoom.rs @@ -110,17 +110,14 @@ impl ::re_types_core::Archetype for MapZoom { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let zoom = { - let array = arrays_by_name - .get("rerun.blueprint.components.ZoomLevel") + let array = arrays_by_descr + .get(&Self::descriptor_zoom()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.blueprint.archetypes.MapZoom#zoom")?; ::from_arrow_opt(&**array) diff --git a/crates/store/re_types/src/blueprint/archetypes/near_clip_plane.rs b/crates/store/re_types/src/blueprint/archetypes/near_clip_plane.rs index 05723fd95ae5..821e600f05a2 100644 --- a/crates/store/re_types/src/blueprint/archetypes/near_clip_plane.rs +++ b/crates/store/re_types/src/blueprint/archetypes/near_clip_plane.rs @@ -115,17 +115,14 @@ impl ::re_types_core::Archetype for NearClipPlane { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let near_clip_plane = { - let array = arrays_by_name - .get("rerun.blueprint.components.NearClipPlane") + let array = arrays_by_descr + .get(&Self::descriptor_near_clip_plane()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.blueprint.archetypes.NearClipPlane#near_clip_plane")?; ::from_arrow_opt(&**array) diff --git a/crates/store/re_types/src/blueprint/archetypes/panel_blueprint.rs b/crates/store/re_types/src/blueprint/archetypes/panel_blueprint.rs index c4c35c395864..fa197eae2c1a 100644 --- a/crates/store/re_types/src/blueprint/archetypes/panel_blueprint.rs +++ b/crates/store/re_types/src/blueprint/archetypes/panel_blueprint.rs @@ -113,16 +113,12 @@ impl ::re_types_core::Archetype for PanelBlueprint { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let state = if let Some(array) = arrays_by_name.get("rerun.blueprint.components.PanelState") - { + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let state = if let Some(array) = arrays_by_descr.get(&Self::descriptor_state()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.PanelBlueprint#state")? .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/plot_legend.rs b/crates/store/re_types/src/blueprint/archetypes/plot_legend.rs index 80fc8b5264ec..93536284ed46 100644 --- a/crates/store/re_types/src/blueprint/archetypes/plot_legend.rs +++ b/crates/store/re_types/src/blueprint/archetypes/plot_legend.rs @@ -136,16 +136,12 @@ impl ::re_types_core::Archetype for PlotLegend { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let corner = if let Some(array) = arrays_by_name.get("rerun.blueprint.components.Corner2D") - { + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let corner = if let Some(array) = arrays_by_descr.get(&Self::descriptor_corner()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.PlotLegend#corner")? .into_iter() @@ -154,8 +150,7 @@ impl ::re_types_core::Archetype for PlotLegend { } else { None }; - let visible = if let Some(array) = arrays_by_name.get("rerun.blueprint.components.Visible") - { + let visible = if let Some(array) = arrays_by_descr.get(&Self::descriptor_visible()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.PlotLegend#visible")? .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/scalar_axis.rs b/crates/store/re_types/src/blueprint/archetypes/scalar_axis.rs index 01c01dac3cf0..368a0b90efcb 100644 --- a/crates/store/re_types/src/blueprint/archetypes/scalar_axis.rs +++ b/crates/store/re_types/src/blueprint/archetypes/scalar_axis.rs @@ -134,15 +134,12 @@ impl ::re_types_core::Archetype for ScalarAxis { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let range = if let Some(array) = arrays_by_name.get("rerun.components.Range1D") { + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let range = if let Some(array) = arrays_by_descr.get(&Self::descriptor_range()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.ScalarAxis#range")? .into_iter() @@ -151,9 +148,7 @@ impl ::re_types_core::Archetype for ScalarAxis { } else { None }; - let zoom_lock = if let Some(array) = - arrays_by_name.get("rerun.blueprint.components.LockRangeDuringZoom") - { + let zoom_lock = if let Some(array) = arrays_by_descr.get(&Self::descriptor_zoom_lock()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.ScalarAxis#zoom_lock")? .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs b/crates/store/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs index a1f0184f682b..d030c8614c23 100644 --- a/crates/store/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs +++ b/crates/store/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs @@ -156,25 +156,21 @@ impl ::re_types_core::Archetype for TensorScalarMapping { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let mag_filter = - if let Some(array) = arrays_by_name.get("rerun.components.MagnificationFilter") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.TensorScalarMapping#mag_filter")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let colormap = if let Some(array) = arrays_by_name.get("rerun.components.Colormap") { + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let mag_filter = if let Some(array) = arrays_by_descr.get(&Self::descriptor_mag_filter()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.TensorScalarMapping#mag_filter")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let colormap = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colormap()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.TensorScalarMapping#colormap")? .into_iter() @@ -183,7 +179,7 @@ impl ::re_types_core::Archetype for TensorScalarMapping { } else { None }; - let gamma = if let Some(array) = arrays_by_name.get("rerun.components.GammaCorrection") { + let gamma = if let Some(array) = arrays_by_descr.get(&Self::descriptor_gamma()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.TensorScalarMapping#gamma")? .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/tensor_slice_selection.rs b/crates/store/re_types/src/blueprint/archetypes/tensor_slice_selection.rs index bca8e2b67533..ccb227899752 100644 --- a/crates/store/re_types/src/blueprint/archetypes/tensor_slice_selection.rs +++ b/crates/store/re_types/src/blueprint/archetypes/tensor_slice_selection.rs @@ -173,16 +173,12 @@ impl ::re_types_core::Archetype for TensorSliceSelection { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let width = if let Some(array) = arrays_by_name.get("rerun.components.TensorWidthDimension") - { + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let width = if let Some(array) = arrays_by_descr.get(&Self::descriptor_width()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.TensorSliceSelection#width")? .into_iter() @@ -191,19 +187,16 @@ impl ::re_types_core::Archetype for TensorSliceSelection { } else { None }; - let height = - if let Some(array) = arrays_by_name.get("rerun.components.TensorHeightDimension") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.TensorSliceSelection#height")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let indices = if let Some(array) = - arrays_by_name.get("rerun.components.TensorDimensionIndexSelection") - { + let height = if let Some(array) = arrays_by_descr.get(&Self::descriptor_height()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.TensorSliceSelection#height")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let indices = if let Some(array) = arrays_by_descr.get(&Self::descriptor_indices()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.TensorSliceSelection#indices")? @@ -215,9 +208,7 @@ impl ::re_types_core::Archetype for TensorSliceSelection { } else { None }; - let slider = if let Some(array) = - arrays_by_name.get("rerun.blueprint.components.TensorDimensionIndexSlider") - { + let slider = if let Some(array) = arrays_by_descr.get(&Self::descriptor_slider()) { Some({ ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.TensorSliceSelection#slider")? diff --git a/crates/store/re_types/src/blueprint/archetypes/tensor_view_fit.rs b/crates/store/re_types/src/blueprint/archetypes/tensor_view_fit.rs index 3919fefdcab0..2e82f018aa1b 100644 --- a/crates/store/re_types/src/blueprint/archetypes/tensor_view_fit.rs +++ b/crates/store/re_types/src/blueprint/archetypes/tensor_view_fit.rs @@ -113,16 +113,12 @@ impl ::re_types_core::Archetype for TensorViewFit { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let scaling = if let Some(array) = arrays_by_name.get("rerun.blueprint.components.ViewFit") - { + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let scaling = if let Some(array) = arrays_by_descr.get(&Self::descriptor_scaling()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.TensorViewFit#scaling")? .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/view_blueprint.rs b/crates/store/re_types/src/blueprint/archetypes/view_blueprint.rs index 53cbda7545e4..0ae6e1fbbf1b 100644 --- a/crates/store/re_types/src/blueprint/archetypes/view_blueprint.rs +++ b/crates/store/re_types/src/blueprint/archetypes/view_blueprint.rs @@ -169,17 +169,14 @@ impl ::re_types_core::Archetype for ViewBlueprint { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let class_identifier = { - let array = arrays_by_name - .get("rerun.blueprint.components.ViewClass") + let array = arrays_by_descr + .get(&Self::descriptor_class_identifier()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.blueprint.archetypes.ViewBlueprint#class_identifier")?; ::from_arrow_opt(&**array) @@ -190,17 +187,18 @@ impl ::re_types_core::Archetype for ViewBlueprint { .ok_or_else(DeserializationError::missing_data) .with_context("rerun.blueprint.archetypes.ViewBlueprint#class_identifier")? }; - let display_name = if let Some(array) = arrays_by_name.get("rerun.components.Name") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ViewBlueprint#display_name")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let display_name = + if let Some(array) = arrays_by_descr.get(&Self::descriptor_display_name()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ViewBlueprint#display_name")? + .into_iter() + .next() + .flatten() + } else { + None + }; let space_origin = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.ViewOrigin") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_space_origin()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.ViewBlueprint#space_origin")? .into_iter() @@ -209,8 +207,7 @@ impl ::re_types_core::Archetype for ViewBlueprint { } else { None }; - let visible = if let Some(array) = arrays_by_name.get("rerun.blueprint.components.Visible") - { + let visible = if let Some(array) = arrays_by_descr.get(&Self::descriptor_visible()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.ViewBlueprint#visible")? .into_iter() diff --git a/crates/store/re_types/src/blueprint/archetypes/view_contents.rs b/crates/store/re_types/src/blueprint/archetypes/view_contents.rs index 265ac29c00a3..1739475c1e29 100644 --- a/crates/store/re_types/src/blueprint/archetypes/view_contents.rs +++ b/crates/store/re_types/src/blueprint/archetypes/view_contents.rs @@ -152,17 +152,14 @@ impl ::re_types_core::Archetype for ViewContents { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let query = { - let array = arrays_by_name - .get("rerun.blueprint.components.QueryExpression") + let array = arrays_by_descr + .get(&Self::descriptor_query()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.blueprint.archetypes.ViewContents#query")?; ::from_arrow_opt(&**array) diff --git a/crates/store/re_types/src/blueprint/archetypes/viewport_blueprint.rs b/crates/store/re_types/src/blueprint/archetypes/viewport_blueprint.rs index e200f3a6d3e6..bca398edba82 100644 --- a/crates/store/re_types/src/blueprint/archetypes/viewport_blueprint.rs +++ b/crates/store/re_types/src/blueprint/archetypes/viewport_blueprint.rs @@ -190,16 +190,13 @@ impl ::re_types_core::Archetype for ViewportBlueprint { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let root_container = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.RootContainer") { + if let Some(array) = arrays_by_descr.get(&Self::descriptor_root_container()) { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.ViewportBlueprint#root_container")? .into_iter() @@ -208,38 +205,36 @@ impl ::re_types_core::Archetype for ViewportBlueprint { } else { None }; - let maximized = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.ViewMaximized") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ViewportBlueprint#maximized")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let auto_layout = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.AutoLayout") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ViewportBlueprint#auto_layout")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let auto_views = - if let Some(array) = arrays_by_name.get("rerun.blueprint.components.AutoViews") { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ViewportBlueprint#auto_views")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let maximized = if let Some(array) = arrays_by_descr.get(&Self::descriptor_maximized()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ViewportBlueprint#maximized")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let auto_layout = if let Some(array) = arrays_by_descr.get(&Self::descriptor_auto_layout()) + { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ViewportBlueprint#auto_layout")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let auto_views = if let Some(array) = arrays_by_descr.get(&Self::descriptor_auto_views()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ViewportBlueprint#auto_views")? + .into_iter() + .next() + .flatten() + } else { + None + }; let past_viewer_recommendations = if let Some(array) = - arrays_by_name.get("rerun.blueprint.components.ViewerRecommendationHash") + arrays_by_descr.get(&Self::descriptor_past_viewer_recommendations()) { Some({ ::from_arrow_opt(&**array) diff --git a/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges.rs b/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges.rs index 49fb6c94bcb9..b32ea79b1926 100644 --- a/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges.rs +++ b/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges.rs @@ -123,17 +123,14 @@ impl ::re_types_core::Archetype for VisibleTimeRanges { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let ranges = { - let array = arrays_by_name - .get("rerun.blueprint.components.VisibleTimeRange") + let array = arrays_by_descr + .get(&Self::descriptor_ranges()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.blueprint.archetypes.VisibleTimeRanges#ranges")?; ::from_arrow_opt(&**array) diff --git a/crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs b/crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs index d89e5ca63cf2..abacfe530fea 100644 --- a/crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs +++ b/crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs @@ -121,17 +121,14 @@ impl ::re_types_core::Archetype for VisualBounds2D { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let range = { - let array = arrays_by_name - .get("rerun.blueprint.components.VisualBounds2D") + let array = arrays_by_descr + .get(&Self::descriptor_range()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.blueprint.archetypes.VisualBounds2D#range")?; ::from_arrow_opt(&**array) diff --git a/crates/store/re_types/src/testing/archetypes/affix_fuzzer1.rs b/crates/store/re_types/src/testing/archetypes/affix_fuzzer1.rs index d0cce34b18ae..482b2ea77fdc 100644 --- a/crates/store/re_types/src/testing/archetypes/affix_fuzzer1.rs +++ b/crates/store/re_types/src/testing/archetypes/affix_fuzzer1.rs @@ -388,17 +388,14 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let fuzz1001 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer1") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1001()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1001")?; ::from_arrow_opt(&**array) @@ -410,8 +407,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1001")? }; let fuzz1002 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer2") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1002()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1002")?; ::from_arrow_opt(&**array) @@ -423,8 +420,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1002")? }; let fuzz1003 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer3") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1003()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1003")?; ::from_arrow_opt(&**array) @@ -436,8 +433,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1003")? }; let fuzz1004 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer4") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1004()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1004")?; ::from_arrow_opt(&**array) @@ -449,8 +446,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1004")? }; let fuzz1005 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer5") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1005()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1005")?; ::from_arrow_opt(&**array) @@ -462,8 +459,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1005")? }; let fuzz1006 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer6") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1006()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1006")?; ::from_arrow_opt(&**array) @@ -475,8 +472,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1006")? }; let fuzz1007 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer7") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1007()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1007")?; ::from_arrow_opt(&**array) @@ -488,8 +485,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1007")? }; let fuzz1008 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer8") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1008()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1008")?; ::from_arrow_opt(&**array) @@ -501,8 +498,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1008")? }; let fuzz1009 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer9") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1009()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1009")?; ::from_arrow_opt(&**array) @@ -514,8 +511,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1009")? }; let fuzz1010 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer10") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1010()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1010")?; ::from_arrow_opt(&**array) @@ -527,8 +524,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1010")? }; let fuzz1011 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer11") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1011()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1011")?; ::from_arrow_opt(&**array) @@ -540,8 +537,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1011")? }; let fuzz1012 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer12") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1012()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1012")?; ::from_arrow_opt(&**array) @@ -553,8 +550,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1012")? }; let fuzz1013 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer13") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1013()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1013")?; ::from_arrow_opt(&**array) @@ -566,8 +563,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1013")? }; let fuzz1014 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer14") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1014()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1014")?; ::from_arrow_opt(&**array) @@ -579,8 +576,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1014")? }; let fuzz1015 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer15") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1015()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1015")?; ::from_arrow_opt(&**array) @@ -592,8 +589,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1015")? }; let fuzz1016 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer16") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1016()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1016")?; ::from_arrow_opt(&**array) @@ -605,8 +602,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1016")? }; let fuzz1017 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer17") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1017()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1017")?; ::from_arrow_opt(&**array) @@ -618,8 +615,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1017")? }; let fuzz1018 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer18") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1018()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1018")?; ::from_arrow_opt(&**array) @@ -631,8 +628,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1018")? }; let fuzz1019 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer19") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1019()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1019")?; ::from_arrow_opt(&**array) @@ -644,8 +641,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1019")? }; let fuzz1020 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer20") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1020()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1020")?; ::from_arrow_opt(&**array) @@ -657,8 +654,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1020")? }; let fuzz1021 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer21") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1021()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1021")?; ::from_arrow_opt(&**array) @@ -670,8 +667,8 @@ impl ::re_types_core::Archetype for AffixFuzzer1 { .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1021")? }; let fuzz1022 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer22") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1022()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer1#fuzz1022")?; ::from_arrow_opt(&**array) diff --git a/crates/store/re_types/src/testing/archetypes/affix_fuzzer2.rs b/crates/store/re_types/src/testing/archetypes/affix_fuzzer2.rs index 7fea451d8505..6cbf0a642ec3 100644 --- a/crates/store/re_types/src/testing/archetypes/affix_fuzzer2.rs +++ b/crates/store/re_types/src/testing/archetypes/affix_fuzzer2.rs @@ -349,17 +349,14 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let fuzz1101 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer1") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1101()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1101")?; ::from_arrow_opt(&**array) @@ -370,8 +367,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1101")? }; let fuzz1102 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer2") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1102()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1102")?; ::from_arrow_opt(&**array) @@ -382,8 +379,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1102")? }; let fuzz1103 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer3") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1103()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1103")?; ::from_arrow_opt(&**array) @@ -394,8 +391,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1103")? }; let fuzz1104 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer4") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1104()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1104")?; ::from_arrow_opt(&**array) @@ -406,8 +403,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1104")? }; let fuzz1105 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer5") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1105()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1105")?; ::from_arrow_opt(&**array) @@ -418,8 +415,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1105")? }; let fuzz1106 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer6") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1106()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1106")?; ::from_arrow_opt(&**array) @@ -430,8 +427,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1106")? }; let fuzz1107 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer7") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1107()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1107")?; ::from_arrow_opt(&**array) @@ -442,8 +439,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1107")? }; let fuzz1108 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer8") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1108()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1108")?; ::from_arrow_opt(&**array) @@ -454,8 +451,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1108")? }; let fuzz1109 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer9") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1109()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1109")?; ::from_arrow_opt(&**array) @@ -466,8 +463,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1109")? }; let fuzz1110 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer10") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1110()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1110")?; ::from_arrow_opt(&**array) @@ -478,8 +475,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1110")? }; let fuzz1111 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer11") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1111()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1111")?; ::from_arrow_opt(&**array) @@ -490,8 +487,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1111")? }; let fuzz1112 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer12") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1112()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1112")?; ::from_arrow_opt(&**array) @@ -502,8 +499,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1112")? }; let fuzz1113 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer13") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1113()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1113")?; ::from_arrow_opt(&**array) @@ -514,8 +511,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1113")? }; let fuzz1114 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer14") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1114()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1114")?; ::from_arrow_opt(&**array) @@ -526,8 +523,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1114")? }; let fuzz1115 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer15") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1115()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1115")?; ::from_arrow_opt(&**array) @@ -538,8 +535,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1115")? }; let fuzz1116 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer16") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1116()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1116")?; ::from_arrow_opt(&**array) @@ -550,8 +547,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1116")? }; let fuzz1117 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer17") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1117()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1117")?; ::from_arrow_opt(&**array) @@ -562,8 +559,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1117")? }; let fuzz1118 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer18") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1118()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1118")?; ::from_arrow_opt(&**array) @@ -574,8 +571,8 @@ impl ::re_types_core::Archetype for AffixFuzzer2 { .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1118")? }; let fuzz1122 = { - let array = arrays_by_name - .get("rerun.testing.components.AffixFuzzer22") + let array = arrays_by_descr + .get(&Self::descriptor_fuzz1122()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.testing.archetypes.AffixFuzzer2#fuzz1122")?; ::from_arrow_opt(&**array) diff --git a/crates/store/re_types/src/testing/archetypes/affix_fuzzer3.rs b/crates/store/re_types/src/testing/archetypes/affix_fuzzer3.rs index edcc3108ecee..b8d68b503664 100644 --- a/crates/store/re_types/src/testing/archetypes/affix_fuzzer3.rs +++ b/crates/store/re_types/src/testing/archetypes/affix_fuzzer3.rs @@ -336,194 +336,173 @@ impl ::re_types_core::Archetype for AffixFuzzer3 { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let fuzz2001 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer1") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2001")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2002 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer2") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2002")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2003 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer3") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2003")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2004 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer4") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2004")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2005 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer5") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2005")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2006 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer6") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2006")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2007 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer7") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2007")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2008 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer8") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2008")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2009 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer9") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2009")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2010 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer10") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2010")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2011 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer11") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2011")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2012 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer12") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2012")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2013 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer13") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2013")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2014 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer14") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2014")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2015 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer15") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2015")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2016 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer16") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2016")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2017 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer17") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2017")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let fuzz2018 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer18") { - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2018")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let fuzz2001 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2001()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2001")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2002 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2002()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2002")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2003 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2003()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2003")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2004 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2004()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2004")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2005 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2005()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2005")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2006 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2006()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2006")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2007 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2007()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2007")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2008 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2008()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2008")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2009 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2009()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2009")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2010 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2010()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2010")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2011 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2011()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2011")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2012 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2012()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2012")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2013 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2013()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2013")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2014 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2014()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2014")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2015 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2015()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2015")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2016 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2016()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2016")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2017 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2017()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2017")? + .into_iter() + .next() + .flatten() + } else { + None + }; + let fuzz2018 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2018()) { + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer3#fuzz2018")? + .into_iter() + .next() + .flatten() + } else { + None + }; Ok(Self { fuzz2001, fuzz2002, diff --git a/crates/store/re_types/src/testing/archetypes/affix_fuzzer4.rs b/crates/store/re_types/src/testing/archetypes/affix_fuzzer4.rs index 6cc8d615c80b..897a08968001 100644 --- a/crates/store/re_types/src/testing/archetypes/affix_fuzzer4.rs +++ b/crates/store/re_types/src/testing/archetypes/affix_fuzzer4.rs @@ -336,248 +336,227 @@ impl ::re_types_core::Archetype for AffixFuzzer4 { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); - let fuzz2101 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer1") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2101")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2101")? - }) - } else { - None - }; - let fuzz2102 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer2") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2102")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2102")? - }) - } else { - None - }; - let fuzz2103 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer3") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2103")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2103")? - }) - } else { - None - }; - let fuzz2104 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer4") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2104")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2104")? - }) - } else { - None - }; - let fuzz2105 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer5") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2105")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2105")? - }) - } else { - None - }; - let fuzz2106 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer6") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2106")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2106")? - }) - } else { - None - }; - let fuzz2107 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer7") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2107")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2107")? - }) - } else { - None - }; - let fuzz2108 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer8") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2108")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2108")? - }) - } else { - None - }; - let fuzz2109 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer9") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2109")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2109")? - }) - } else { - None - }; - let fuzz2110 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer10") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2110")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2110")? - }) - } else { - None - }; - let fuzz2111 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer11") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2111")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2111")? - }) - } else { - None - }; - let fuzz2112 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer12") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2112")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2112")? - }) - } else { - None - }; - let fuzz2113 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer13") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2113")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2113")? - }) - } else { - None - }; - let fuzz2114 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer14") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2114")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2114")? - }) - } else { - None - }; - let fuzz2115 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer15") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2115")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2115")? - }) - } else { - None - }; - let fuzz2116 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer16") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2116")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2116")? - }) - } else { - None - }; - let fuzz2117 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer17") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2117")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2117")? - }) - } else { - None - }; - let fuzz2118 = - if let Some(array) = arrays_by_name.get("rerun.testing.components.AffixFuzzer18") { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2118")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2118")? - }) - } else { - None - }; + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let fuzz2101 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2101()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2101")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2101")? + }) + } else { + None + }; + let fuzz2102 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2102()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2102")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2102")? + }) + } else { + None + }; + let fuzz2103 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2103()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2103")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2103")? + }) + } else { + None + }; + let fuzz2104 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2104()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2104")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2104")? + }) + } else { + None + }; + let fuzz2105 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2105()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2105")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2105")? + }) + } else { + None + }; + let fuzz2106 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2106()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2106")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2106")? + }) + } else { + None + }; + let fuzz2107 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2107()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2107")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2107")? + }) + } else { + None + }; + let fuzz2108 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2108()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2108")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2108")? + }) + } else { + None + }; + let fuzz2109 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2109()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2109")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2109")? + }) + } else { + None + }; + let fuzz2110 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2110()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2110")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2110")? + }) + } else { + None + }; + let fuzz2111 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2111()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2111")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2111")? + }) + } else { + None + }; + let fuzz2112 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2112()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2112")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2112")? + }) + } else { + None + }; + let fuzz2113 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2113()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2113")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2113")? + }) + } else { + None + }; + let fuzz2114 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2114()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2114")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2114")? + }) + } else { + None + }; + let fuzz2115 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2115()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2115")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2115")? + }) + } else { + None + }; + let fuzz2116 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2116()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2116")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2116")? + }) + } else { + None + }; + let fuzz2117 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2117()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2117")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2117")? + }) + } else { + None + }; + let fuzz2118 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fuzz2118()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2118")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.testing.archetypes.AffixFuzzer4#fuzz2118")? + }) + } else { + None + }; Ok(Self { fuzz2101, fuzz2102, diff --git a/crates/store/re_types/tests/types/points3d.rs b/crates/store/re_types/tests/types/points3d.rs index 98dadd595a7a..362d0b4a6110 100644 --- a/crates/store/re_types/tests/types/points3d.rs +++ b/crates/store/re_types/tests/types/points3d.rs @@ -43,9 +43,9 @@ fn roundtrip() { let serialized = arch.to_arrow().unwrap(); for (field, array) in &serialized { // NOTE: Keep those around please, very useful when debugging. - // eprintln!("field = {field:#?}"); - // eprintln!("array = {array:#?}"); - eprintln!("{} = {array:#?}", field.name()); + eprintln!("field = {field:#?}"); + eprintln!("array = {array:#?}"); + // eprintln!("{} = {array:#?}", field.name()); } let deserialized = Points3D::from_arrow(serialized).unwrap(); diff --git a/crates/store/re_types_core/src/archetype.rs b/crates/store/re_types_core/src/archetype.rs index 9c0bb82f733e..9f03dee6e7db 100644 --- a/crates/store/re_types_core/src/archetype.rs +++ b/crates/store/re_types_core/src/archetype.rs @@ -109,7 +109,7 @@ pub trait Archetype { { Self::from_arrow_components( data.into_iter() - .map(|(field, array)| (ComponentName::new(field.name()), array)), + .map(|(field, array)| (ComponentDescriptor::from(field), array)), ) } @@ -120,7 +120,7 @@ pub trait Archetype { /// logged to stderr. #[inline] fn from_arrow_components( - data: impl IntoIterator, + data: impl IntoIterator, ) -> DeserializationResult where Self: Sized, @@ -139,14 +139,15 @@ pub trait Archetype { /// logged to stderr. #[inline] fn from_arrow2_components( - data: impl IntoIterator)>, + data: impl IntoIterator)>, ) -> DeserializationResult where Self: Sized, { - Self::from_arrow_components(data.into_iter().map(|(component, arrow2_array)| { - (component, arrow::array::ArrayRef::from(arrow2_array)) - })) + Self::from_arrow_components( + data.into_iter() + .map(|(descr, arrow2_array)| (descr, arrow::array::ArrayRef::from(arrow2_array))), + ) } } diff --git a/crates/store/re_types_core/src/archetypes/clear.rs b/crates/store/re_types_core/src/archetypes/clear.rs index 5f3e932288c0..3f480bdb7a43 100644 --- a/crates/store/re_types_core/src/archetypes/clear.rs +++ b/crates/store/re_types_core/src/archetypes/clear.rs @@ -166,17 +166,14 @@ impl crate::Archetype for Clear { #[inline] fn from_arrow_components( - arrow_data: impl IntoIterator, + arrow_data: impl IntoIterator, ) -> DeserializationResult { re_tracing::profile_function!(); use crate::{Loggable as _, ResultExt as _}; - let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data - .into_iter() - .map(|(name, array)| (name.full_name(), array)) - .collect(); + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let is_recursive = { - let array = arrays_by_name - .get("rerun.components.ClearIsRecursive") + let array = arrays_by_descr + .get(&Self::descriptor_is_recursive()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.archetypes.Clear#is_recursive")?; ::from_arrow_opt(&**array) diff --git a/crates/store/re_types_core/src/as_components.rs b/crates/store/re_types_core/src/as_components.rs index 498d7c139221..388299a5a0ce 100644 --- a/crates/store/re_types_core/src/as_components.rs +++ b/crates/store/re_types_core/src/as_components.rs @@ -81,14 +81,7 @@ pub trait AsComponents { ) -> SerializationResult> { self.as_serialized_batches() .into_iter() - .map(|comp_batch| { - let field = arrow::datatypes::Field::new( - comp_batch.descriptor.component_name.to_string(), - comp_batch.array.data_type().clone(), - false, - ); - Ok((field, comp_batch.array)) - }) + .map(|comp_batch| Ok((arrow::datatypes::Field::from(&comp_batch), comp_batch.array))) .collect() } @@ -106,12 +99,10 @@ pub trait AsComponents { self.as_serialized_batches() .into_iter() .map(|comp_batch| { - let field = arrow2::datatypes::Field::new( - comp_batch.descriptor.component_name.to_string(), - comp_batch.array.data_type().clone().into(), - false, - ); - Ok((field, comp_batch.array.into())) + Ok(( + arrow2::datatypes::Field::from(&comp_batch), + comp_batch.array.into(), + )) }) .collect() } diff --git a/crates/store/re_types_core/src/component_descriptor.rs b/crates/store/re_types_core/src/component_descriptor.rs index cf19c2d437e4..a5908e3a1e39 100644 --- a/crates/store/re_types_core/src/component_descriptor.rs +++ b/crates/store/re_types_core/src/component_descriptor.rs @@ -181,3 +181,36 @@ impl ComponentDescriptor { self } } + +// --- + +// TODO(cmc): This is far from ideal and feels very hackish, but for now the priority is getting +// all things related to tags up and running so we can gather learnings. +// This is only used on the archetype deserialization path, which isn't ever used outside of tests anyway. + +// TODO(cmc): we really shouldn't be duplicating these. + +/// The key used to identify the [`crate::ArchetypeName`] in field-level metadata. +const FIELD_METADATA_KEY_ARCHETYPE_NAME: &str = "rerun.archetype_name"; + +/// The key used to identify the [`crate::ArchetypeFieldName`] in field-level metadata. +const FIELD_METADATA_KEY_ARCHETYPE_FIELD_NAME: &str = "rerun.archetype_field_name"; + +impl From for ComponentDescriptor { + #[inline] + fn from(field: arrow::datatypes::Field) -> Self { + let md = field.metadata(); + + Self { + archetype_name: md + .get(FIELD_METADATA_KEY_ARCHETYPE_NAME) + .cloned() + .map(Into::into), + archetype_field_name: md + .get(FIELD_METADATA_KEY_ARCHETYPE_FIELD_NAME) + .cloned() + .map(Into::into), + component_name: field.name().clone().into(), + } + } +} diff --git a/crates/store/re_types_core/src/loggable_batch.rs b/crates/store/re_types_core/src/loggable_batch.rs index 6c1c3cd2110f..8d683d038eb5 100644 --- a/crates/store/re_types_core/src/loggable_batch.rs +++ b/crates/store/re_types_core/src/loggable_batch.rs @@ -234,6 +234,82 @@ impl SerializedComponentBatch { } } +// --- + +// TODO(cmc): This is far from ideal and feels very hackish, but for now the priority is getting +// all things related to tags up and running so we can gather learnings. +// This is only used on the archetype deserialization path, which isn't ever used outside of tests anyway. + +// TODO(cmc): we really shouldn't be duplicating these. + +/// The key used to identify the [`crate::ArchetypeName`] in field-level metadata. +const FIELD_METADATA_KEY_ARCHETYPE_NAME: &str = "rerun.archetype_name"; + +/// The key used to identify the [`crate::ArchetypeFieldName`] in field-level metadata. +const FIELD_METADATA_KEY_ARCHETYPE_FIELD_NAME: &str = "rerun.archetype_field_name"; + +impl From<&SerializedComponentBatch> for arrow::datatypes::Field { + #[inline] + fn from(batch: &SerializedComponentBatch) -> Self { + Self::new( + batch.descriptor.component_name.to_string(), + batch.array.data_type().clone(), + false, + ) + .with_metadata( + [ + batch.descriptor.archetype_name.map(|name| { + ( + FIELD_METADATA_KEY_ARCHETYPE_NAME.to_owned(), + name.to_string(), + ) + }), + batch.descriptor.archetype_field_name.map(|name| { + ( + FIELD_METADATA_KEY_ARCHETYPE_FIELD_NAME.to_owned(), + name.to_string(), + ) + }), + ] + .into_iter() + .flatten() + .collect(), + ) + } +} + +impl From<&SerializedComponentBatch> for arrow2::datatypes::Field { + #[inline] + fn from(batch: &SerializedComponentBatch) -> Self { + Self::new( + batch.descriptor.component_name.to_string(), + batch.array.data_type().clone().into(), + false, + ) + .with_metadata( + [ + batch.descriptor.archetype_name.map(|name| { + ( + FIELD_METADATA_KEY_ARCHETYPE_NAME.to_owned(), + name.to_string(), + ) + }), + batch.descriptor.archetype_field_name.map(|name| { + ( + FIELD_METADATA_KEY_ARCHETYPE_FIELD_NAME.to_owned(), + name.to_string(), + ) + }), + ] + .into_iter() + .flatten() + .collect(), + ) + } +} + +// --- + // TODO(cmc): All these crazy types are about to disappear. ComponentBatch should only live at the // edge, and therefore not require all these crazy kinds of derivatives (require eager serialization). From 9f738606c2e97169db1db41446094b8451dda1aa Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Mon, 13 Jan 2025 09:35:49 +0100 Subject: [PATCH 08/57] Implement support for opt-in eagerly-serialized archetypes (#8646) This introduces a new `attr.rust.archetype_eager` codegen attribute. When toggled, the associated archetype will now only carry raw Arrow data around, and go through the new eager logging APIs. The attribute has been set on `Points3D`: ![image](https://github.com/user-attachments/assets/cb520e0c-5160-4ff6-b6a3-4bf10b4ac045) Legacy and eagerly-serialized archetypes can co-exist, making it possible to migrate everything incrementally. * DNM: requires #8644 * Part of #7245 --- .../re_types_builder/src/codegen/rust/api.rs | 187 +++++++++++---- crates/build/re_types_builder/src/lib.rs | 6 +- crates/build/re_types_builder/src/objects.rs | 10 +- .../re_types/definitions/attributes/rust.fbs | 5 + .../definitions/rerun/archetypes/points3d.fbs | 1 + .../src/archetypes/annotation_context.rs | 4 +- .../store/re_types/src/archetypes/arrows2d.rs | 4 +- .../store/re_types/src/archetypes/arrows3d.rs | 4 +- .../store/re_types/src/archetypes/asset3d.rs | 4 +- .../re_types/src/archetypes/asset_video.rs | 4 +- .../re_types/src/archetypes/bar_chart.rs | 4 +- .../store/re_types/src/archetypes/boxes2d.rs | 4 +- .../store/re_types/src/archetypes/boxes3d.rs | 4 +- .../re_types/src/archetypes/capsules3d.rs | 4 +- .../re_types/src/archetypes/depth_image.rs | 4 +- .../re_types/src/archetypes/ellipsoids3d.rs | 4 +- .../re_types/src/archetypes/encoded_image.rs | 4 +- .../src/archetypes/geo_line_strings.rs | 4 +- .../re_types/src/archetypes/geo_points.rs | 4 +- .../re_types/src/archetypes/graph_edges.rs | 4 +- .../re_types/src/archetypes/graph_nodes.rs | 4 +- crates/store/re_types/src/archetypes/image.rs | 4 +- .../re_types/src/archetypes/image_ext.rs | 21 +- .../src/archetypes/instance_poses3d.rs | 4 +- .../re_types/src/archetypes/line_strips2d.rs | 4 +- .../re_types/src/archetypes/line_strips3d.rs | 4 +- .../store/re_types/src/archetypes/mesh3d.rs | 4 +- .../store/re_types/src/archetypes/pinhole.rs | 4 +- .../store/re_types/src/archetypes/points2d.rs | 4 +- .../store/re_types/src/archetypes/points3d.rs | 222 +++++------------- .../store/re_types/src/archetypes/scalar.rs | 4 +- .../src/archetypes/segmentation_image.rs | 4 +- .../re_types/src/archetypes/series_line.rs | 4 +- .../re_types/src/archetypes/series_point.rs | 4 +- .../store/re_types/src/archetypes/tensor.rs | 4 +- .../re_types/src/archetypes/text_document.rs | 4 +- .../store/re_types/src/archetypes/text_log.rs | 4 +- .../re_types/src/archetypes/transform3d.rs | 4 +- .../src/archetypes/video_frame_reference.rs | 4 +- .../src/archetypes/view_coordinates.rs | 4 +- .../src/blueprint/archetypes/background.rs | 4 +- .../archetypes/container_blueprint.rs | 4 +- .../blueprint/archetypes/dataframe_query.rs | 4 +- .../src/blueprint/archetypes/force_center.rs | 4 +- .../archetypes/force_collision_radius.rs | 4 +- .../src/blueprint/archetypes/force_link.rs | 4 +- .../blueprint/archetypes/force_many_body.rs | 4 +- .../blueprint/archetypes/force_position.rs | 4 +- .../src/blueprint/archetypes/line_grid3d.rs | 4 +- .../blueprint/archetypes/map_background.rs | 4 +- .../src/blueprint/archetypes/map_zoom.rs | 4 +- .../blueprint/archetypes/near_clip_plane.rs | 4 +- .../blueprint/archetypes/panel_blueprint.rs | 4 +- .../src/blueprint/archetypes/plot_legend.rs | 4 +- .../src/blueprint/archetypes/scalar_axis.rs | 4 +- .../archetypes/tensor_scalar_mapping.rs | 4 +- .../archetypes/tensor_slice_selection.rs | 4 +- .../blueprint/archetypes/tensor_view_fit.rs | 4 +- .../blueprint/archetypes/view_blueprint.rs | 4 +- .../src/blueprint/archetypes/view_contents.rs | 4 +- .../archetypes/viewport_blueprint.rs | 4 +- .../archetypes/visible_time_ranges.rs | 4 +- .../blueprint/archetypes/visual_bounds2d.rs | 4 +- .../src/blueprint/components/active_tab.rs | 4 +- .../blueprint/components/apply_latest_at.rs | 4 +- .../src/blueprint/components/auto_layout.rs | 4 +- .../src/blueprint/components/auto_views.rs | 4 +- .../blueprint/components/background_kind.rs | 4 +- .../src/blueprint/components/column_share.rs | 4 +- .../components/component_column_selector.rs | 4 +- .../blueprint/components/container_kind.rs | 4 +- .../src/blueprint/components/corner2d.rs | 4 +- .../src/blueprint/components/enabled.rs | 4 +- .../blueprint/components/filter_by_range.rs | 4 +- .../components/filter_is_not_null.rs | 4 +- .../blueprint/components/force_distance.rs | 4 +- .../blueprint/components/force_iterations.rs | 4 +- .../blueprint/components/force_strength.rs | 4 +- .../src/blueprint/components/grid_columns.rs | 4 +- .../src/blueprint/components/grid_spacing.rs | 4 +- .../blueprint/components/included_content.rs | 4 +- .../src/blueprint/components/interactive.rs | 4 +- .../components/lock_range_during_zoom.rs | 4 +- .../src/blueprint/components/map_provider.rs | 4 +- .../blueprint/components/near_clip_plane.rs | 4 +- .../src/blueprint/components/panel_state.rs | 4 +- .../blueprint/components/query_expression.rs | 4 +- .../blueprint/components/root_container.rs | 4 +- .../src/blueprint/components/row_share.rs | 4 +- .../blueprint/components/selected_columns.rs | 4 +- .../tensor_dimension_index_slider.rs | 4 +- .../src/blueprint/components/timeline_name.rs | 4 +- .../src/blueprint/components/view_class.rs | 4 +- .../src/blueprint/components/view_fit.rs | 4 +- .../blueprint/components/view_maximized.rs | 4 +- .../src/blueprint/components/view_origin.rs | 4 +- .../components/viewer_recommendation_hash.rs | 4 +- .../src/blueprint/components/visible.rs | 4 +- .../components/visible_time_range.rs | 4 +- .../blueprint/components/visual_bounds2d.rs | 4 +- .../components/visualizer_overrides.rs | 4 +- .../src/blueprint/components/zoom_level.rs | 4 +- .../datatypes/component_column_selector.rs | 4 +- .../blueprint/datatypes/filter_by_range.rs | 4 +- .../blueprint/datatypes/filter_is_not_null.rs | 4 +- .../blueprint/datatypes/selected_columns.rs | 4 +- .../tensor_dimension_index_slider.rs | 4 +- .../src/blueprint/datatypes/utf8list.rs | 4 +- .../src/blueprint/views/bar_chart_view.rs | 4 +- .../src/blueprint/views/dataframe_view.rs | 4 +- .../src/blueprint/views/graph_view.rs | 4 +- .../re_types/src/blueprint/views/map_view.rs | 4 +- .../src/blueprint/views/spatial2d_view.rs | 4 +- .../src/blueprint/views/spatial3d_view.rs | 4 +- .../src/blueprint/views/tensor_view.rs | 4 +- .../src/blueprint/views/text_document_view.rs | 4 +- .../src/blueprint/views/text_log_view.rs | 4 +- .../src/blueprint/views/time_series_view.rs | 4 +- .../src/components/aggregation_policy.rs | 4 +- .../re_types/src/components/albedo_factor.rs | 4 +- .../src/components/annotation_context.rs | 4 +- .../re_types/src/components/axis_length.rs | 4 +- crates/store/re_types/src/components/blob.rs | 4 +- .../store/re_types/src/components/class_id.rs | 4 +- crates/store/re_types/src/components/color.rs | 4 +- .../store/re_types/src/components/colormap.rs | 4 +- .../re_types/src/components/depth_meter.rs | 4 +- .../re_types/src/components/draw_order.rs | 4 +- .../re_types/src/components/entity_path.rs | 4 +- .../re_types/src/components/fill_mode.rs | 4 +- .../re_types/src/components/fill_ratio.rs | 4 +- .../src/components/gamma_correction.rs | 4 +- .../src/components/geo_line_string.rs | 4 +- .../re_types/src/components/graph_edge.rs | 4 +- .../re_types/src/components/graph_node.rs | 4 +- .../re_types/src/components/graph_type.rs | 4 +- .../re_types/src/components/half_size2d.rs | 4 +- .../re_types/src/components/half_size3d.rs | 4 +- .../re_types/src/components/image_buffer.rs | 4 +- .../re_types/src/components/image_format.rs | 4 +- .../src/components/image_plane_distance.rs | 4 +- .../re_types/src/components/keypoint_id.rs | 4 +- .../store/re_types/src/components/lat_lon.rs | 4 +- .../store/re_types/src/components/length.rs | 4 +- .../re_types/src/components/line_strip2d.rs | 4 +- .../re_types/src/components/line_strip3d.rs | 4 +- .../src/components/magnification_filter.rs | 4 +- .../re_types/src/components/marker_shape.rs | 4 +- .../re_types/src/components/marker_size.rs | 4 +- .../re_types/src/components/media_type.rs | 4 +- crates/store/re_types/src/components/name.rs | 4 +- .../store/re_types/src/components/opacity.rs | 4 +- .../src/components/pinhole_projection.rs | 4 +- .../store/re_types/src/components/plane3d.rs | 4 +- .../components/pose_rotation_axis_angle.rs | 4 +- .../src/components/pose_rotation_quat.rs | 4 +- .../re_types/src/components/pose_scale3d.rs | 4 +- .../src/components/pose_transform_mat3x3.rs | 4 +- .../src/components/pose_translation3d.rs | 4 +- .../re_types/src/components/position2d.rs | 4 +- .../re_types/src/components/position3d.rs | 4 +- .../store/re_types/src/components/radius.rs | 4 +- .../store/re_types/src/components/range1d.rs | 4 +- .../re_types/src/components/recording_uri.rs | 4 +- .../re_types/src/components/resolution.rs | 4 +- .../src/components/rotation_axis_angle.rs | 4 +- .../re_types/src/components/rotation_quat.rs | 4 +- .../store/re_types/src/components/scalar.rs | 4 +- .../store/re_types/src/components/scale3d.rs | 4 +- .../re_types/src/components/show_labels.rs | 4 +- .../re_types/src/components/stroke_width.rs | 4 +- .../re_types/src/components/tensor_data.rs | 4 +- .../tensor_dimension_index_selection.rs | 4 +- .../src/components/tensor_height_dimension.rs | 4 +- .../src/components/tensor_width_dimension.rs | 4 +- .../re_types/src/components/texcoord2d.rs | 4 +- crates/store/re_types/src/components/text.rs | 4 +- .../re_types/src/components/text_log_level.rs | 4 +- .../src/components/transform_mat3x3.rs | 4 +- .../src/components/transform_relation.rs | 4 +- .../re_types/src/components/translation3d.rs | 4 +- .../src/components/triangle_indices.rs | 4 +- .../re_types/src/components/value_range.rs | 4 +- .../store/re_types/src/components/vector2d.rs | 4 +- .../store/re_types/src/components/vector3d.rs | 4 +- .../src/components/video_timestamp.rs | 4 +- .../src/components/view_coordinates.rs | 4 +- crates/store/re_types/src/datatypes/angle.rs | 4 +- .../re_types/src/datatypes/annotation_info.rs | 4 +- crates/store/re_types/src/datatypes/blob.rs | 4 +- .../src/datatypes/channel_datatype.rs | 4 +- .../src/datatypes/class_description.rs | 4 +- .../datatypes/class_description_map_elem.rs | 4 +- .../store/re_types/src/datatypes/class_id.rs | 4 +- .../re_types/src/datatypes/color_model.rs | 4 +- crates/store/re_types/src/datatypes/dvec2d.rs | 4 +- .../re_types/src/datatypes/image_format.rs | 4 +- .../re_types/src/datatypes/keypoint_id.rs | 4 +- .../re_types/src/datatypes/keypoint_pair.rs | 4 +- crates/store/re_types/src/datatypes/mat3x3.rs | 4 +- crates/store/re_types/src/datatypes/mat4x4.rs | 4 +- .../re_types/src/datatypes/pixel_format.rs | 4 +- .../store/re_types/src/datatypes/plane3d.rs | 4 +- .../re_types/src/datatypes/quaternion.rs | 4 +- .../store/re_types/src/datatypes/range1d.rs | 4 +- .../store/re_types/src/datatypes/range2d.rs | 4 +- crates/store/re_types/src/datatypes/rgba32.rs | 4 +- .../src/datatypes/rotation_axis_angle.rs | 4 +- .../re_types/src/datatypes/tensor_buffer.rs | 4 +- .../re_types/src/datatypes/tensor_data.rs | 4 +- .../tensor_dimension_index_selection.rs | 4 +- .../datatypes/tensor_dimension_selection.rs | 4 +- .../store/re_types/src/datatypes/utf8pair.rs | 4 +- crates/store/re_types/src/datatypes/uuid.rs | 4 +- crates/store/re_types/src/datatypes/uvec2d.rs | 4 +- crates/store/re_types/src/datatypes/uvec3d.rs | 4 +- crates/store/re_types/src/datatypes/uvec4d.rs | 4 +- crates/store/re_types/src/datatypes/vec2d.rs | 4 +- crates/store/re_types/src/datatypes/vec3d.rs | 4 +- crates/store/re_types/src/datatypes/vec4d.rs | 4 +- .../re_types/src/datatypes/video_timestamp.rs | 4 +- .../src/datatypes/view_coordinates.rs | 4 +- .../src/testing/archetypes/affix_fuzzer1.rs | 4 +- .../src/testing/archetypes/affix_fuzzer2.rs | 4 +- .../src/testing/archetypes/affix_fuzzer3.rs | 4 +- .../src/testing/archetypes/affix_fuzzer4.rs | 4 +- .../src/testing/components/affix_fuzzer1.rs | 4 +- .../src/testing/components/affix_fuzzer10.rs | 4 +- .../src/testing/components/affix_fuzzer11.rs | 4 +- .../src/testing/components/affix_fuzzer12.rs | 4 +- .../src/testing/components/affix_fuzzer13.rs | 4 +- .../src/testing/components/affix_fuzzer14.rs | 4 +- .../src/testing/components/affix_fuzzer15.rs | 4 +- .../src/testing/components/affix_fuzzer16.rs | 4 +- .../src/testing/components/affix_fuzzer17.rs | 4 +- .../src/testing/components/affix_fuzzer18.rs | 4 +- .../src/testing/components/affix_fuzzer19.rs | 4 +- .../src/testing/components/affix_fuzzer2.rs | 4 +- .../src/testing/components/affix_fuzzer20.rs | 4 +- .../src/testing/components/affix_fuzzer21.rs | 4 +- .../src/testing/components/affix_fuzzer22.rs | 4 +- .../src/testing/components/affix_fuzzer23.rs | 4 +- .../src/testing/components/affix_fuzzer3.rs | 4 +- .../src/testing/components/affix_fuzzer4.rs | 4 +- .../src/testing/components/affix_fuzzer5.rs | 4 +- .../src/testing/components/affix_fuzzer6.rs | 4 +- .../src/testing/components/affix_fuzzer7.rs | 4 +- .../src/testing/components/affix_fuzzer8.rs | 4 +- .../src/testing/components/affix_fuzzer9.rs | 4 +- .../src/testing/datatypes/affix_fuzzer1.rs | 4 +- .../src/testing/datatypes/affix_fuzzer2.rs | 4 +- .../src/testing/datatypes/affix_fuzzer20.rs | 4 +- .../src/testing/datatypes/affix_fuzzer21.rs | 4 +- .../src/testing/datatypes/affix_fuzzer22.rs | 4 +- .../src/testing/datatypes/affix_fuzzer3.rs | 4 +- .../src/testing/datatypes/affix_fuzzer4.rs | 4 +- .../src/testing/datatypes/affix_fuzzer5.rs | 4 +- .../src/testing/datatypes/enum_test.rs | 4 +- .../src/testing/datatypes/flattened_scalar.rs | 4 +- .../src/testing/datatypes/multi_enum.rs | 4 +- .../testing/datatypes/primitive_component.rs | 4 +- .../src/testing/datatypes/string_component.rs | 4 +- .../src/testing/datatypes/valued_enum.rs | 4 +- crates/store/re_types/tests/types/points3d.rs | 43 ++-- .../re_types_core/src/archetypes/clear.rs | 4 +- .../re_types_core/src/archetypes/clear_ext.rs | 8 +- .../src/components/clear_is_recursive.rs | 4 +- .../store/re_types_core/src/datatypes/bool.rs | 4 +- .../src/datatypes/entity_path.rs | 4 +- .../re_types_core/src/datatypes/float32.rs | 4 +- .../re_types_core/src/datatypes/float64.rs | 4 +- .../re_types_core/src/datatypes/time_int.rs | 4 +- .../re_types_core/src/datatypes/time_range.rs | 4 +- .../src/datatypes/time_range_boundary.rs | 4 +- .../re_types_core/src/datatypes/uint16.rs | 4 +- .../re_types_core/src/datatypes/uint32.rs | 4 +- .../re_types_core/src/datatypes/uint64.rs | 4 +- .../store/re_types_core/src/datatypes/utf8.rs | 4 +- .../src/datatypes/visible_time_range.rs | 4 +- crates/store/re_types_core/src/lib.rs | 47 ++++ 280 files changed, 840 insertions(+), 790 deletions(-) diff --git a/crates/build/re_types_builder/src/codegen/rust/api.rs b/crates/build/re_types_builder/src/codegen/rust/api.rs index e4b5894f66b3..2880f8c00077 100644 --- a/crates/build/re_types_builder/src/codegen/rust/api.rs +++ b/crates/build/re_types_builder/src/codegen/rust/api.rs @@ -181,11 +181,11 @@ fn generate_object_file( code.push_str("\n\n"); - code.push_str("use ::re_types_core::external::arrow;\n"); + code.push_str("use ::re_types_core::try_serialize_field;\n"); code.push_str("use ::re_types_core::SerializationResult;\n"); code.push_str("use ::re_types_core::{DeserializationResult, DeserializationError};\n"); code.push_str("use ::re_types_core::{ComponentDescriptor, ComponentName};\n"); - code.push_str("use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor};\n"); + code.push_str("use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch};\n"); // NOTE: `TokenStream`s discard whitespacing information by definition, so we need to // inject some of our own when writing to file… while making sure that don't inject @@ -324,12 +324,19 @@ fn quote_struct( quote!(true) } else { let quoted_is_pods = obj.fields.iter().map(|obj_field| { - let quoted_field_type = quote_field_type_from_object_field(obj_field); + let quoted_field_type = quote_field_type_from_object_field(obj, obj_field); quote!(<#quoted_field_type>::is_pod()) }); quote!(#(#quoted_is_pods)&&*) }; + let quoted_is_pod = (!obj.is_eager_rust_archetype()).then_some(quote! { + #[inline] + fn is_pod() -> bool { + #is_pod_impl + } + }); + quote! { impl ::re_byte_size::SizeBytes for #name { #[inline] @@ -337,10 +344,7 @@ fn quote_struct( #heap_size_bytes_impl } - #[inline] - fn is_pod() -> bool { - #is_pod_impl - } + #quoted_is_pod } } }; @@ -397,7 +401,7 @@ fn quote_union( let name = format_ident!("{}", re_case::to_pascal_case(&obj_field.name)); let quoted_doc = quote_field_docs(reporter, objects, obj_field); - let quoted_type = quote_field_type_from_object_field(obj_field); + let quoted_type = quote_field_type_from_object_field(obj, obj_field); if obj_field.typ == Type::Unit { quote! { @@ -431,7 +435,7 @@ fn quote_union( .iter() .filter(|obj_field| obj_field.typ != Type::Unit) .map(|obj_field| { - let quoted_field_type = quote_field_type_from_object_field(obj_field); + let quoted_field_type = quote_field_type_from_object_field(obj, obj_field); quote!(<#quoted_field_type>::is_pod()) }) .collect(); @@ -655,7 +659,7 @@ impl ObjectFieldTokenizer<'_> { let Self(reporter, obj, obj_field) = self; let quoted_docs = quote_field_docs(reporter, objects, obj_field); let name = format_ident!("{}", &obj_field.name); - let quoted_type = quote_field_type_from_object_field(obj_field); + let quoted_type = quote_field_type_from_object_field(obj, obj_field); if is_tuple_struct_from_obj(obj) { quote! { @@ -722,13 +726,16 @@ fn quote_field_type_from_typ(typ: &Type, unwrap: bool) -> (TokenStream, bool) { (quote!(#obj_field_type), unwrapped) } -fn quote_field_type_from_object_field(obj_field: &ObjectField) -> TokenStream { - let (quoted_type, _) = quote_field_type_from_typ(&obj_field.typ, false); - - if obj_field.is_nullable { - quote!(Option<#quoted_type>) +fn quote_field_type_from_object_field(obj: &Object, obj_field: &ObjectField) -> TokenStream { + if obj.is_eager_rust_archetype() { + quote!(Option) } else { - quoted_type + let (quoted_type, _) = quote_field_type_from_typ(&obj_field.typ, false); + if obj_field.is_nullable { + quote!(Option<#quoted_type>) + } else { + quoted_type + } } } @@ -1153,7 +1160,8 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { .map(|field| format_ident!("{}", field.name)) .collect::>(); - let all_component_batches = { + // TODO(#7245): This goes away once all archetypes have been made eager. + let all_native_component_batches = { std::iter::once(quote! { Some(Self::indicator()) }).chain(obj.fields.iter().map(|obj_field| { @@ -1198,8 +1206,7 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { quote!{ Some(&self.#field_name as &dyn ComponentBatch) } }; - let archetype_field_name = obj_field.snake_case_name(); - let descr_fn_name = format_ident!("descriptor_{archetype_field_name}"); + let descr_fn_name = format_ident!("descriptor_{field_name}"); quote! { (#batch).map(|batch| { @@ -1213,7 +1220,37 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { })) }; - let all_deserializers = { + let all_eager_component_batches = { + std::iter::once(quote! { + Self::indicator().serialized() + }) + .chain(obj.fields.iter().map(|obj_field| { + let field_name = format_ident!("{}", obj_field.name); + quote!(self.#field_name.clone()) + })) + }; + + let as_components_impl = if obj.is_eager_rust_archetype() { + quote! { + #[inline] + fn as_serialized_batches(&self) -> Vec { + use ::re_types_core::Archetype as _; + [#(#all_eager_component_batches,)*].into_iter().flatten().collect() + } + } + } else { + quote! { + fn as_component_batches(&self) -> Vec> { + re_tracing::profile_function!(); + + use ::re_types_core::Archetype as _; + [#(#all_native_component_batches,)*].into_iter().flatten().collect() + } + } + }; + + // TODO(#7245): This goes away once all archetypes have been made eager. + let all_native_deserializers = { obj.fields.iter().map(|obj_field| { let obj_field_fqname = obj_field.fqname.as_str(); let field_name = format_ident!("{}", obj_field.name); @@ -1291,6 +1328,27 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { }) }; + let all_eager_deserializers = { + obj.fields.iter().map(|obj_field| { + let field_name = format_ident!("{}", obj_field.name); + let descr_fn_name = format_ident!("descriptor_{field_name}"); + + let quoted_deser = quote! { + arrays_by_descr + .get(&Self::#descr_fn_name()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::#descr_fn_name())) + }; + + quote!(let #field_name = #quoted_deser;) + }) + }; + + let all_deserializers = if obj.is_eager_rust_archetype() { + quote!(#(#all_eager_deserializers;)*) + } else { + quote!(#(#all_native_deserializers;)*) + }; + quote! { impl #name { #(#all_descriptor_methods)* @@ -1369,7 +1427,7 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - #(#all_deserializers;)* + #all_deserializers Ok(Self { #(#quoted_field_names,)* @@ -1378,12 +1436,7 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { } impl ::re_types_core::AsComponents for #name { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); - - use ::re_types_core::Archetype as _; - [#(#all_component_batches,)*].into_iter().flatten().collect() - } + #as_components_impl } impl ::re_types_core::ArchetypeReflectionMarker for #name { } @@ -1428,7 +1481,7 @@ fn quote_from_impl_from_obj(obj: &Object) -> TokenStream { let quoted_obj_name = format_ident!("{}", obj.name); let quoted_obj_field_name = format_ident!("{}", obj_field.name); - let quoted_type = quote_field_type_from_object_field(obj_field); + let quoted_type = quote_field_type_from_object_field(obj, obj_field); let self_field_access = if obj_is_tuple_struct { quote!(self.0) @@ -1571,26 +1624,43 @@ fn quote_builder_from_obj(reporter: &Reporter, objects: &Objects, obj: &Object) // fn new() let quoted_params = required.iter().map(|field| { let field_name = format_ident!("{}", field.name); - let (typ, unwrapped) = quote_field_type_from_typ(&field.typ, true); - if unwrapped { - // This was originally a vec/array! + let (typ, is_many_component) = quote_field_type_from_typ(&field.typ, true); + if is_many_component { quote!(#field_name: impl IntoIterator>) } else { quote!(#field_name: impl Into<#typ>) } }); - let quoted_required = required.iter().map(|field| { + // TODO(#7245): This goes away once all archetypes have been made eager. + let quoted_native_required = required.iter().map(|field| { let field_name = format_ident!("{}", field.name); - let (_, unwrapped) = quote_field_type_from_typ(&field.typ, true); - if unwrapped { - // This was originally a vec/array! + let (_, is_many_component) = quote_field_type_from_typ(&field.typ, true); + if is_many_component { quote!(#field_name: #field_name.into_iter().map(Into::into).collect()) } else { quote!(#field_name: #field_name.into()) } }); + let quoted_eager_required = required.iter().map(|field| { + let field_name = format_ident!("{}", field.name); + let descr_fn_name = format_ident!("descriptor_{field_name}"); + + let (_, is_many_component) = quote_field_type_from_typ(&field.typ, true); + if is_many_component { + quote!(#field_name: try_serialize_field(Self::#descr_fn_name(), #field_name)) + } else { + quote!(#field_name: try_serialize_field(Self::#descr_fn_name(), [#field_name])) + } + }); + + let quoted_required = if obj.is_eager_rust_archetype() { + quote!(#(#quoted_eager_required,)*) + } else { + quote!(#(#quoted_native_required,)*) + }; + let quoted_optional = optional.iter().map(|field| { let field_name = format_ident!("{}", field.name); quote!(#field_name: None) @@ -1624,7 +1694,7 @@ fn quote_builder_from_obj(reporter: &Reporter, objects: &Objects, obj: &Object) #[inline] #fn_new_pub fn new(#(#quoted_params,)*) -> Self { Self { - #(#quoted_required,)* + #quoted_required #(#quoted_optional,)* } } @@ -1632,15 +1702,15 @@ fn quote_builder_from_obj(reporter: &Reporter, objects: &Objects, obj: &Object) } }; - let with_methods = optional.iter().map(|field| { + // TODO(#7245): This goes away once all archetypes have been made eager. + let native_with_methods = optional.iter().map(|field| { // fn with_*() let field_name = format_ident!("{}", field.name); let method_name = format_ident!("with_{field_name}"); - let (typ, unwrapped) = quote_field_type_from_typ(&field.typ, true); + let (typ, is_many_component) = quote_field_type_from_typ(&field.typ, true); let docstring = quote_field_docs(reporter, objects, field); - if unwrapped { - // This was originally a vec/array! + if is_many_component { quote! { #docstring #[inline] @@ -1661,11 +1731,46 @@ fn quote_builder_from_obj(reporter: &Reporter, objects: &Objects, obj: &Object) } }); + let eager_with_methods = optional.iter().map(|field| { + // fn with_*() + let field_name = format_ident!("{}", field.name); + let descr_fn_name = format_ident!("descriptor_{field_name}"); + let method_name = format_ident!("with_{field_name}"); + let (typ, is_many_component) = quote_field_type_from_typ(&field.typ, true); + let docstring = quote_field_docs(reporter, objects, field); + + if is_many_component { + quote! { + #docstring + #[inline] + pub fn #method_name(mut self, #field_name: impl IntoIterator>) -> Self { + self.#field_name = try_serialize_field(Self::#descr_fn_name(), #field_name); + self + } + } + } else { + quote! { + #docstring + #[inline] + pub fn #method_name(mut self, #field_name: impl Into<#typ>) -> Self { + self.#field_name = try_serialize_field(Self::#descr_fn_name(), [#field_name]); + self + } + } + } + }); + + let with_methods = if obj.is_eager_rust_archetype() { + quote!(#(#eager_with_methods)*) + } else { + quote!(#(#native_with_methods)*) + }; + quote! { impl #name { #fn_new - #(#with_methods)* + #with_methods } } } diff --git a/crates/build/re_types_builder/src/lib.rs b/crates/build/re_types_builder/src/lib.rs index 4641ace5d09f..b891af2e3bff 100644 --- a/crates/build/re_types_builder/src/lib.rs +++ b/crates/build/re_types_builder/src/lib.rs @@ -194,6 +194,10 @@ pub const ATTR_RERUN_EXPERIMENTAL: &str = "attr.rerun.experimental"; pub const ATTR_PYTHON_ALIASES: &str = "attr.python.aliases"; pub const ATTR_PYTHON_ARRAY_ALIASES: &str = "attr.python.array_aliases"; +pub const ATTR_CPP_NO_FIELD_CTORS: &str = "attr.cpp.no_field_ctors"; +pub const ATTR_CPP_RENAME_FIELD: &str = "attr.cpp.rename_field"; + +pub const ATTR_RUST_ARCHETYPE_EAGER: &str = "attr.rust.archetype_eager"; pub const ATTR_RUST_CUSTOM_CLAUSE: &str = "attr.rust.custom_clause"; pub const ATTR_RUST_DERIVE: &str = "attr.rust.derive"; pub const ATTR_RUST_DERIVE_ONLY: &str = "attr.rust.derive_only"; @@ -201,8 +205,6 @@ pub const ATTR_RUST_NEW_PUB_CRATE: &str = "attr.rust.new_pub_crate"; pub const ATTR_RUST_OVERRIDE_CRATE: &str = "attr.rust.override_crate"; pub const ATTR_RUST_REPR: &str = "attr.rust.repr"; pub const ATTR_RUST_TUPLE_STRUCT: &str = "attr.rust.tuple_struct"; -pub const ATTR_CPP_NO_FIELD_CTORS: &str = "attr.cpp.no_field_ctors"; -pub const ATTR_CPP_RENAME_FIELD: &str = "attr.cpp.rename_field"; pub const ATTR_DOCS_UNRELEASED: &str = "attr.docs.unreleased"; pub const ATTR_DOCS_CATEGORY: &str = "attr.docs.category"; diff --git a/crates/build/re_types_builder/src/objects.rs b/crates/build/re_types_builder/src/objects.rs index bee035715392..519460d3d83b 100644 --- a/crates/build/re_types_builder/src/objects.rs +++ b/crates/build/re_types_builder/src/objects.rs @@ -12,7 +12,7 @@ use itertools::Itertools; use crate::{ root_as_schema, Docs, FbsBaseType, FbsEnum, FbsEnumVal, FbsField, FbsKeyValue, FbsObject, FbsSchema, FbsType, Reporter, ATTR_RERUN_COMPONENT_OPTIONAL, ATTR_RERUN_COMPONENT_RECOMMENDED, - ATTR_RERUN_COMPONENT_REQUIRED, ATTR_RERUN_OVERRIDE_TYPE, + ATTR_RERUN_COMPONENT_REQUIRED, ATTR_RERUN_OVERRIDE_TYPE, ATTR_RUST_ARCHETYPE_EAGER, }; // --- @@ -686,6 +686,14 @@ impl Object { self.kind.plural_snake_case().to_owned() } } + + pub fn is_archetype(&self) -> bool { + self.kind == ObjectKind::Archetype + } + + pub fn is_eager_rust_archetype(&self) -> bool { + self.is_archetype() && self.is_attr_set(ATTR_RUST_ARCHETYPE_EAGER) + } } pub fn is_testing_fqname(fqname: &str) -> bool { diff --git a/crates/store/re_types/definitions/attributes/rust.fbs b/crates/store/re_types/definitions/attributes/rust.fbs index 0a3df9d13229..0d9b7b2a3e37 100644 --- a/crates/store/re_types/definitions/attributes/rust.fbs +++ b/crates/store/re_types/definitions/attributes/rust.fbs @@ -41,3 +41,8 @@ attribute "attr.rust.new_pub_crate"; /// an object of kind `Blueprint` with `attr.rust.override_crate=re_viewport`, the final /// object will be generated in `re_viewport/src/blueprint`. attribute "attr.rust.override_crate"; + +/// The generated Rust object should be eagerly serialized, i.e. only comprised of Arrow arrays. +/// +/// Applies only to archetypes. No-op otherwise. +attribute "attr.rust.archetype_eager"; diff --git a/crates/store/re_types/definitions/rerun/archetypes/points3d.fbs b/crates/store/re_types/definitions/rerun/archetypes/points3d.fbs index 1468d2102bae..2bc5b5eb7a30 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/points3d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/points3d.fbs @@ -9,6 +9,7 @@ namespace rerun.archetypes; /// \example archetypes/points3d_ui_radius title="Log points with radii given in UI points" image="https://static.rerun.io/point3d_ui_radius/e051a65b4317438bcaea8d0eee016ac9460b5336/1200w.png" /// \example archetypes/points3d_send_columns title="Send several point clouds with varying point count over time in a single call" image="https://static.rerun.io/points3d_send_columns/633b524a2ee439b0e3afc3f894f4927ce938a3ec/1200w.png" missing="rs" table Points3D ( + "attr.rust.archetype_eager": "", "attr.rust.derive": "PartialEq", "attr.docs.category": "Spatial 3D", "attr.docs.view_types": "Spatial3DView, Spatial2DView: if logged above active projection" diff --git a/crates/store/re_types/src/archetypes/annotation_context.rs b/crates/store/re_types/src/archetypes/annotation_context.rs index 46c624eed099..2ad8d8e42cca 100644 --- a/crates/store/re_types/src/archetypes/annotation_context.rs +++ b/crates/store/re_types/src/archetypes/annotation_context.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/arrows2d.rs b/crates/store/re_types/src/archetypes/arrows2d.rs index 8f5b6bd3bb0e..6afea171fe0b 100644 --- a/crates/store/re_types/src/archetypes/arrows2d.rs +++ b/crates/store/re_types/src/archetypes/arrows2d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/arrows3d.rs b/crates/store/re_types/src/archetypes/arrows3d.rs index 9b5e0a42cf51..dd0027b11e8d 100644 --- a/crates/store/re_types/src/archetypes/arrows3d.rs +++ b/crates/store/re_types/src/archetypes/arrows3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/asset3d.rs b/crates/store/re_types/src/archetypes/asset3d.rs index f81cb11028e1..298dce11e646 100644 --- a/crates/store/re_types/src/archetypes/asset3d.rs +++ b/crates/store/re_types/src/archetypes/asset3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/asset_video.rs b/crates/store/re_types/src/archetypes/asset_video.rs index 879a61910230..2cfb6b65fa5e 100644 --- a/crates/store/re_types/src/archetypes/asset_video.rs +++ b/crates/store/re_types/src/archetypes/asset_video.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/bar_chart.rs b/crates/store/re_types/src/archetypes/bar_chart.rs index ed1a5f6314d5..29ed3f84cf21 100644 --- a/crates/store/re_types/src/archetypes/bar_chart.rs +++ b/crates/store/re_types/src/archetypes/bar_chart.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/boxes2d.rs b/crates/store/re_types/src/archetypes/boxes2d.rs index 05434a880009..3b77c0f5e852 100644 --- a/crates/store/re_types/src/archetypes/boxes2d.rs +++ b/crates/store/re_types/src/archetypes/boxes2d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/boxes3d.rs b/crates/store/re_types/src/archetypes/boxes3d.rs index 77081336ee7d..6c552c979962 100644 --- a/crates/store/re_types/src/archetypes/boxes3d.rs +++ b/crates/store/re_types/src/archetypes/boxes3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/capsules3d.rs b/crates/store/re_types/src/archetypes/capsules3d.rs index 6cfdb3123738..db56147fb9cf 100644 --- a/crates/store/re_types/src/archetypes/capsules3d.rs +++ b/crates/store/re_types/src/archetypes/capsules3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/depth_image.rs b/crates/store/re_types/src/archetypes/depth_image.rs index 0ea59252fcee..9feba02636a2 100644 --- a/crates/store/re_types/src/archetypes/depth_image.rs +++ b/crates/store/re_types/src/archetypes/depth_image.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/ellipsoids3d.rs b/crates/store/re_types/src/archetypes/ellipsoids3d.rs index ef5863d567b4..06677f84f624 100644 --- a/crates/store/re_types/src/archetypes/ellipsoids3d.rs +++ b/crates/store/re_types/src/archetypes/ellipsoids3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/encoded_image.rs b/crates/store/re_types/src/archetypes/encoded_image.rs index 795213edfd25..8dfd575a277f 100644 --- a/crates/store/re_types/src/archetypes/encoded_image.rs +++ b/crates/store/re_types/src/archetypes/encoded_image.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/geo_line_strings.rs b/crates/store/re_types/src/archetypes/geo_line_strings.rs index 362e813bb0f7..58109147e0bc 100644 --- a/crates/store/re_types/src/archetypes/geo_line_strings.rs +++ b/crates/store/re_types/src/archetypes/geo_line_strings.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/geo_points.rs b/crates/store/re_types/src/archetypes/geo_points.rs index 1934ade73f87..44dfd2581e17 100644 --- a/crates/store/re_types/src/archetypes/geo_points.rs +++ b/crates/store/re_types/src/archetypes/geo_points.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/graph_edges.rs b/crates/store/re_types/src/archetypes/graph_edges.rs index 10b9b0a24b66..a3b74d6e0c45 100644 --- a/crates/store/re_types/src/archetypes/graph_edges.rs +++ b/crates/store/re_types/src/archetypes/graph_edges.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/graph_nodes.rs b/crates/store/re_types/src/archetypes/graph_nodes.rs index 176e1bb55730..615538403848 100644 --- a/crates/store/re_types/src/archetypes/graph_nodes.rs +++ b/crates/store/re_types/src/archetypes/graph_nodes.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/image.rs b/crates/store/re_types/src/archetypes/image.rs index 6e0ee68ab5c3..e01ce1dc934a 100644 --- a/crates/store/re_types/src/archetypes/image.rs +++ b/crates/store/re_types/src/archetypes/image.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/image_ext.rs b/crates/store/re_types/src/archetypes/image_ext.rs index 0304cecb27fe..004877acd2bd 100644 --- a/crates/store/re_types/src/archetypes/image_ext.rs +++ b/crates/store/re_types/src/archetypes/image_ext.rs @@ -63,12 +63,7 @@ impl Image { color_model: Some(color_model), }; - Ok(Self { - buffer: blob.into(), - format: image_format.into(), - opacity: None, - draw_order: None, - }) + Ok(Self::new(blob, image_format)) } /// Construct an image from a byte buffer given its resolution and pixel format. @@ -90,12 +85,7 @@ impl Image { ); } - Self { - buffer, - format: image_format.into(), - opacity: None, - draw_order: None, - } + Self::new(buffer, image_format) } /// Construct an image from a byte buffer given its resolution, color model, and data type. @@ -124,12 +114,7 @@ impl Image { ); } - Self { - buffer, - format: image_format.into(), - opacity: None, - draw_order: None, - } + Self::new(buffer, image_format) } /// Construct an image from a byte buffer given its resolution, color model, diff --git a/crates/store/re_types/src/archetypes/instance_poses3d.rs b/crates/store/re_types/src/archetypes/instance_poses3d.rs index b1d4dd13f7a5..daf9df5a9dc9 100644 --- a/crates/store/re_types/src/archetypes/instance_poses3d.rs +++ b/crates/store/re_types/src/archetypes/instance_poses3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/line_strips2d.rs b/crates/store/re_types/src/archetypes/line_strips2d.rs index 0280b098c209..868167d34697 100644 --- a/crates/store/re_types/src/archetypes/line_strips2d.rs +++ b/crates/store/re_types/src/archetypes/line_strips2d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/line_strips3d.rs b/crates/store/re_types/src/archetypes/line_strips3d.rs index e7b70cd37243..761c01bb048d 100644 --- a/crates/store/re_types/src/archetypes/line_strips3d.rs +++ b/crates/store/re_types/src/archetypes/line_strips3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/mesh3d.rs b/crates/store/re_types/src/archetypes/mesh3d.rs index c6cd40cb1b7c..9dfd9a44fa53 100644 --- a/crates/store/re_types/src/archetypes/mesh3d.rs +++ b/crates/store/re_types/src/archetypes/mesh3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/pinhole.rs b/crates/store/re_types/src/archetypes/pinhole.rs index 8e984d718c49..b3ef6e548e74 100644 --- a/crates/store/re_types/src/archetypes/pinhole.rs +++ b/crates/store/re_types/src/archetypes/pinhole.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/points2d.rs b/crates/store/re_types/src/archetypes/points2d.rs index 3aaa10eb1946..ff673182bf6a 100644 --- a/crates/store/re_types/src/archetypes/points2d.rs +++ b/crates/store/re_types/src/archetypes/points2d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/points3d.rs b/crates/store/re_types/src/archetypes/points3d.rs index 33bd5bcaa3bc..cd9ed1edb7b2 100644 --- a/crates/store/re_types/src/archetypes/points3d.rs +++ b/crates/store/re_types/src/archetypes/points3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; @@ -97,27 +97,27 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; #[derive(Clone, Debug, PartialEq)] pub struct Points3D { /// All the 3D positions at which the point cloud shows points. - pub positions: Vec, + pub positions: Option, /// Optional radii for the points, effectively turning them into circles. - pub radii: Option>, + pub radii: Option, /// Optional colors for the points. - pub colors: Option>, + pub colors: Option, /// Optional text labels for the points. /// /// If there's a single label present, it will be placed at the center of the entity. /// Otherwise, each instance will have its own label. - pub labels: Option>, + pub labels: Option, /// Optional choice of whether the text labels should be shown by default. - pub show_labels: Option, + pub show_labels: Option, /// Optional class Ids for the points. /// /// The [`components::ClassId`][crate::components::ClassId] provides colors and labels if not specified explicitly. - pub class_ids: Option>, + pub class_ids: Option, /// Optional keypoint IDs for the points, identifying them within a class. /// @@ -127,7 +127,7 @@ pub struct Points3D { /// with `class_id`). /// E.g. the classification might be 'Person' and the keypoints refer to joints on a /// detected skeleton. - pub keypoint_ids: Option>, + pub keypoint_ids: Option, } impl Points3D { @@ -302,89 +302,35 @@ impl ::re_types_core::Archetype for Points3D { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let positions = { - let array = arrays_by_descr - .get(&Self::descriptor_positions()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.Points3D#positions")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points3D#positions")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Points3D#positions")? - }; - let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points3D#radii")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Points3D#radii")? - }) - } else { - None - }; - let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points3D#colors")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Points3D#colors")? - }) - } else { - None - }; - let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points3D#labels")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Points3D#labels")? - }) - } else { - None - }; - let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points3D#show_labels")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points3D#class_ids")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Points3D#class_ids")? - }) - } else { - None - }; - let keypoint_ids = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_keypoint_ids()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points3D#keypoint_ids")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Points3D#keypoint_ids")? - }) - } else { - None - }; + let positions = arrays_by_descr + .get(&Self::descriptor_positions()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_positions()) + }); + let radii = arrays_by_descr + .get(&Self::descriptor_radii()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_radii())); + let colors = arrays_by_descr + .get(&Self::descriptor_colors()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_colors())); + let labels = arrays_by_descr + .get(&Self::descriptor_labels()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_labels())); + let show_labels = arrays_by_descr + .get(&Self::descriptor_show_labels()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_show_labels()) + }); + let class_ids = arrays_by_descr + .get(&Self::descriptor_class_ids()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_class_ids()) + }); + let keypoint_ids = arrays_by_descr + .get(&Self::descriptor_keypoint_ids()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_keypoint_ids()) + }); Ok(Self { positions, radii, @@ -398,65 +344,18 @@ impl ::re_types_core::Archetype for Points3D { } impl ::re_types_core::AsComponents for Points3D { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.positions as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_positions()), - } - }), - (self - .radii - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_radii()), - }), - (self - .colors - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_colors()), - }), - (self - .labels - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_labels()), - }), - (self - .show_labels - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_show_labels()), - }), - (self - .class_ids - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_class_ids()), - }), - (self - .keypoint_ids - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_keypoint_ids()), - }), + Self::indicator().serialized(), + self.positions.clone(), + self.radii.clone(), + self.colors.clone(), + self.labels.clone(), + self.show_labels.clone(), + self.class_ids.clone(), + self.keypoint_ids.clone(), ] .into_iter() .flatten() @@ -473,7 +372,7 @@ impl Points3D { positions: impl IntoIterator>, ) -> Self { Self { - positions: positions.into_iter().map(Into::into).collect(), + positions: try_serialize_field(Self::descriptor_positions(), positions), radii: None, colors: None, labels: None, @@ -489,7 +388,7 @@ impl Points3D { mut self, radii: impl IntoIterator>, ) -> Self { - self.radii = Some(radii.into_iter().map(Into::into).collect()); + self.radii = try_serialize_field(Self::descriptor_radii(), radii); self } @@ -499,7 +398,7 @@ impl Points3D { mut self, colors: impl IntoIterator>, ) -> Self { - self.colors = Some(colors.into_iter().map(Into::into).collect()); + self.colors = try_serialize_field(Self::descriptor_colors(), colors); self } @@ -512,7 +411,7 @@ impl Points3D { mut self, labels: impl IntoIterator>, ) -> Self { - self.labels = Some(labels.into_iter().map(Into::into).collect()); + self.labels = try_serialize_field(Self::descriptor_labels(), labels); self } @@ -522,7 +421,7 @@ impl Points3D { mut self, show_labels: impl Into, ) -> Self { - self.show_labels = Some(show_labels.into()); + self.show_labels = try_serialize_field(Self::descriptor_show_labels(), [show_labels]); self } @@ -534,7 +433,7 @@ impl Points3D { mut self, class_ids: impl IntoIterator>, ) -> Self { - self.class_ids = Some(class_ids.into_iter().map(Into::into).collect()); + self.class_ids = try_serialize_field(Self::descriptor_class_ids(), class_ids); self } @@ -551,7 +450,7 @@ impl Points3D { mut self, keypoint_ids: impl IntoIterator>, ) -> Self { - self.keypoint_ids = Some(keypoint_ids.into_iter().map(Into::into).collect()); + self.keypoint_ids = try_serialize_field(Self::descriptor_keypoint_ids(), keypoint_ids); self } } @@ -567,15 +466,4 @@ impl ::re_byte_size::SizeBytes for Points3D { + self.class_ids.heap_size_bytes() + self.keypoint_ids.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >::is_pod() - && >>::is_pod() - && >>::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/scalar.rs b/crates/store/re_types/src/archetypes/scalar.rs index 32c439cdeba4..686aa4a106ce 100644 --- a/crates/store/re_types/src/archetypes/scalar.rs +++ b/crates/store/re_types/src/archetypes/scalar.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/segmentation_image.rs b/crates/store/re_types/src/archetypes/segmentation_image.rs index 139115f765d1..45e298b84e07 100644 --- a/crates/store/re_types/src/archetypes/segmentation_image.rs +++ b/crates/store/re_types/src/archetypes/segmentation_image.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/series_line.rs b/crates/store/re_types/src/archetypes/series_line.rs index a19722217d34..d1c7ffda63b5 100644 --- a/crates/store/re_types/src/archetypes/series_line.rs +++ b/crates/store/re_types/src/archetypes/series_line.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/series_point.rs b/crates/store/re_types/src/archetypes/series_point.rs index 28c4924b984a..67dd7ff002e5 100644 --- a/crates/store/re_types/src/archetypes/series_point.rs +++ b/crates/store/re_types/src/archetypes/series_point.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/tensor.rs b/crates/store/re_types/src/archetypes/tensor.rs index b0a430afa7e3..fa1325ad6264 100644 --- a/crates/store/re_types/src/archetypes/tensor.rs +++ b/crates/store/re_types/src/archetypes/tensor.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/text_document.rs b/crates/store/re_types/src/archetypes/text_document.rs index c0163e38bfed..e990e14407c3 100644 --- a/crates/store/re_types/src/archetypes/text_document.rs +++ b/crates/store/re_types/src/archetypes/text_document.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/text_log.rs b/crates/store/re_types/src/archetypes/text_log.rs index f793585d0764..e417bb959b7c 100644 --- a/crates/store/re_types/src/archetypes/text_log.rs +++ b/crates/store/re_types/src/archetypes/text_log.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/transform3d.rs b/crates/store/re_types/src/archetypes/transform3d.rs index 956b11b83fc4..9cbb0b33385d 100644 --- a/crates/store/re_types/src/archetypes/transform3d.rs +++ b/crates/store/re_types/src/archetypes/transform3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/video_frame_reference.rs b/crates/store/re_types/src/archetypes/video_frame_reference.rs index 2afacca0e0cb..45092d428a7e 100644 --- a/crates/store/re_types/src/archetypes/video_frame_reference.rs +++ b/crates/store/re_types/src/archetypes/video_frame_reference.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/archetypes/view_coordinates.rs b/crates/store/re_types/src/archetypes/view_coordinates.rs index f81be2c5a02a..50bd3297c176 100644 --- a/crates/store/re_types/src/archetypes/view_coordinates.rs +++ b/crates/store/re_types/src/archetypes/view_coordinates.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/background.rs b/crates/store/re_types/src/blueprint/archetypes/background.rs index 7ab89ed7bbbe..3aa96cdf3711 100644 --- a/crates/store/re_types/src/blueprint/archetypes/background.rs +++ b/crates/store/re_types/src/blueprint/archetypes/background.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/container_blueprint.rs b/crates/store/re_types/src/blueprint/archetypes/container_blueprint.rs index cf38f7676d7f..ccd1e4dbb08c 100644 --- a/crates/store/re_types/src/blueprint/archetypes/container_blueprint.rs +++ b/crates/store/re_types/src/blueprint/archetypes/container_blueprint.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/dataframe_query.rs b/crates/store/re_types/src/blueprint/archetypes/dataframe_query.rs index ffe0a6c419f3..271e7e0e7936 100644 --- a/crates/store/re_types/src/blueprint/archetypes/dataframe_query.rs +++ b/crates/store/re_types/src/blueprint/archetypes/dataframe_query.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/force_center.rs b/crates/store/re_types/src/blueprint/archetypes/force_center.rs index 0f97a4bb4345..79a0bbbe17bb 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_center.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_center.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs b/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs index 44cb5548da8f..809f2c4ab50b 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/force_link.rs b/crates/store/re_types/src/blueprint/archetypes/force_link.rs index 8e1b0e3e8372..ed81ba18c7cf 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_link.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_link.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs b/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs index ec364a91cea9..12a4f7f61971 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/force_position.rs b/crates/store/re_types/src/blueprint/archetypes/force_position.rs index b2412e4b617b..ca3cbcec4559 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_position.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_position.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs index 496ed5cf92dc..7c68426495bb 100644 --- a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs +++ b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/map_background.rs b/crates/store/re_types/src/blueprint/archetypes/map_background.rs index cfbd868dfbf6..b1854843b142 100644 --- a/crates/store/re_types/src/blueprint/archetypes/map_background.rs +++ b/crates/store/re_types/src/blueprint/archetypes/map_background.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/map_zoom.rs b/crates/store/re_types/src/blueprint/archetypes/map_zoom.rs index c251ed93accf..4c08c0ded30d 100644 --- a/crates/store/re_types/src/blueprint/archetypes/map_zoom.rs +++ b/crates/store/re_types/src/blueprint/archetypes/map_zoom.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/near_clip_plane.rs b/crates/store/re_types/src/blueprint/archetypes/near_clip_plane.rs index 821e600f05a2..3ecaabfff1e0 100644 --- a/crates/store/re_types/src/blueprint/archetypes/near_clip_plane.rs +++ b/crates/store/re_types/src/blueprint/archetypes/near_clip_plane.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/panel_blueprint.rs b/crates/store/re_types/src/blueprint/archetypes/panel_blueprint.rs index fa197eae2c1a..30f03a303bf5 100644 --- a/crates/store/re_types/src/blueprint/archetypes/panel_blueprint.rs +++ b/crates/store/re_types/src/blueprint/archetypes/panel_blueprint.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/plot_legend.rs b/crates/store/re_types/src/blueprint/archetypes/plot_legend.rs index 93536284ed46..3f5bde616686 100644 --- a/crates/store/re_types/src/blueprint/archetypes/plot_legend.rs +++ b/crates/store/re_types/src/blueprint/archetypes/plot_legend.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/scalar_axis.rs b/crates/store/re_types/src/blueprint/archetypes/scalar_axis.rs index 368a0b90efcb..b354df518205 100644 --- a/crates/store/re_types/src/blueprint/archetypes/scalar_axis.rs +++ b/crates/store/re_types/src/blueprint/archetypes/scalar_axis.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs b/crates/store/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs index d030c8614c23..17b9bf68667e 100644 --- a/crates/store/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs +++ b/crates/store/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/tensor_slice_selection.rs b/crates/store/re_types/src/blueprint/archetypes/tensor_slice_selection.rs index ccb227899752..035003e10020 100644 --- a/crates/store/re_types/src/blueprint/archetypes/tensor_slice_selection.rs +++ b/crates/store/re_types/src/blueprint/archetypes/tensor_slice_selection.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/tensor_view_fit.rs b/crates/store/re_types/src/blueprint/archetypes/tensor_view_fit.rs index 2e82f018aa1b..009e5a72db54 100644 --- a/crates/store/re_types/src/blueprint/archetypes/tensor_view_fit.rs +++ b/crates/store/re_types/src/blueprint/archetypes/tensor_view_fit.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/view_blueprint.rs b/crates/store/re_types/src/blueprint/archetypes/view_blueprint.rs index 0ae6e1fbbf1b..e7699eda7997 100644 --- a/crates/store/re_types/src/blueprint/archetypes/view_blueprint.rs +++ b/crates/store/re_types/src/blueprint/archetypes/view_blueprint.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/view_contents.rs b/crates/store/re_types/src/blueprint/archetypes/view_contents.rs index 1739475c1e29..d6c99cfa3613 100644 --- a/crates/store/re_types/src/blueprint/archetypes/view_contents.rs +++ b/crates/store/re_types/src/blueprint/archetypes/view_contents.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/viewport_blueprint.rs b/crates/store/re_types/src/blueprint/archetypes/viewport_blueprint.rs index bca398edba82..a72945cb4bb2 100644 --- a/crates/store/re_types/src/blueprint/archetypes/viewport_blueprint.rs +++ b/crates/store/re_types/src/blueprint/archetypes/viewport_blueprint.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges.rs b/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges.rs index b32ea79b1926..db09e1d83237 100644 --- a/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges.rs +++ b/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs b/crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs index abacfe530fea..8066f0e81f7d 100644 --- a/crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs +++ b/crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/active_tab.rs b/crates/store/re_types/src/blueprint/components/active_tab.rs index 1b91ab7b9cfa..a81edd2c1550 100644 --- a/crates/store/re_types/src/blueprint/components/active_tab.rs +++ b/crates/store/re_types/src/blueprint/components/active_tab.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/apply_latest_at.rs b/crates/store/re_types/src/blueprint/components/apply_latest_at.rs index 8c9480191d8e..3e58e4cc361b 100644 --- a/crates/store/re_types/src/blueprint/components/apply_latest_at.rs +++ b/crates/store/re_types/src/blueprint/components/apply_latest_at.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/auto_layout.rs b/crates/store/re_types/src/blueprint/components/auto_layout.rs index 4859a819c8a0..ee60dab85c20 100644 --- a/crates/store/re_types/src/blueprint/components/auto_layout.rs +++ b/crates/store/re_types/src/blueprint/components/auto_layout.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/auto_views.rs b/crates/store/re_types/src/blueprint/components/auto_views.rs index 1cfd797358e4..aaec370975f7 100644 --- a/crates/store/re_types/src/blueprint/components/auto_views.rs +++ b/crates/store/re_types/src/blueprint/components/auto_views.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/background_kind.rs b/crates/store/re_types/src/blueprint/components/background_kind.rs index 5fcc182ac525..054075dff6c1 100644 --- a/crates/store/re_types/src/blueprint/components/background_kind.rs +++ b/crates/store/re_types/src/blueprint/components/background_kind.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/column_share.rs b/crates/store/re_types/src/blueprint/components/column_share.rs index 3f59207f722e..9c69baa20219 100644 --- a/crates/store/re_types/src/blueprint/components/column_share.rs +++ b/crates/store/re_types/src/blueprint/components/column_share.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/component_column_selector.rs b/crates/store/re_types/src/blueprint/components/component_column_selector.rs index 5f90bc7bfeab..01d2c62c3510 100644 --- a/crates/store/re_types/src/blueprint/components/component_column_selector.rs +++ b/crates/store/re_types/src/blueprint/components/component_column_selector.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/container_kind.rs b/crates/store/re_types/src/blueprint/components/container_kind.rs index 7c4fc983903c..2851a649522f 100644 --- a/crates/store/re_types/src/blueprint/components/container_kind.rs +++ b/crates/store/re_types/src/blueprint/components/container_kind.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/corner2d.rs b/crates/store/re_types/src/blueprint/components/corner2d.rs index 7ac7c8538db0..81d2daa8b81f 100644 --- a/crates/store/re_types/src/blueprint/components/corner2d.rs +++ b/crates/store/re_types/src/blueprint/components/corner2d.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/enabled.rs b/crates/store/re_types/src/blueprint/components/enabled.rs index a8a1354c59fb..c1a1c451b7b1 100644 --- a/crates/store/re_types/src/blueprint/components/enabled.rs +++ b/crates/store/re_types/src/blueprint/components/enabled.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/filter_by_range.rs b/crates/store/re_types/src/blueprint/components/filter_by_range.rs index e4cbfc8162f3..155c6cbaf25c 100644 --- a/crates/store/re_types/src/blueprint/components/filter_by_range.rs +++ b/crates/store/re_types/src/blueprint/components/filter_by_range.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/filter_is_not_null.rs b/crates/store/re_types/src/blueprint/components/filter_is_not_null.rs index cd02500a070c..032d42d20610 100644 --- a/crates/store/re_types/src/blueprint/components/filter_is_not_null.rs +++ b/crates/store/re_types/src/blueprint/components/filter_is_not_null.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/force_distance.rs b/crates/store/re_types/src/blueprint/components/force_distance.rs index d8f5fde94f87..3daf996ac7fc 100644 --- a/crates/store/re_types/src/blueprint/components/force_distance.rs +++ b/crates/store/re_types/src/blueprint/components/force_distance.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/force_iterations.rs b/crates/store/re_types/src/blueprint/components/force_iterations.rs index 5302f0430b0e..2eba63afc8f0 100644 --- a/crates/store/re_types/src/blueprint/components/force_iterations.rs +++ b/crates/store/re_types/src/blueprint/components/force_iterations.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/force_strength.rs b/crates/store/re_types/src/blueprint/components/force_strength.rs index f1157a980a73..8411d02f849f 100644 --- a/crates/store/re_types/src/blueprint/components/force_strength.rs +++ b/crates/store/re_types/src/blueprint/components/force_strength.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/grid_columns.rs b/crates/store/re_types/src/blueprint/components/grid_columns.rs index 6950601146b8..f2f634b313f6 100644 --- a/crates/store/re_types/src/blueprint/components/grid_columns.rs +++ b/crates/store/re_types/src/blueprint/components/grid_columns.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/grid_spacing.rs b/crates/store/re_types/src/blueprint/components/grid_spacing.rs index 67368c6eb804..141f4fc27b5b 100644 --- a/crates/store/re_types/src/blueprint/components/grid_spacing.rs +++ b/crates/store/re_types/src/blueprint/components/grid_spacing.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/included_content.rs b/crates/store/re_types/src/blueprint/components/included_content.rs index a27a093dbe40..1f75942e0d7e 100644 --- a/crates/store/re_types/src/blueprint/components/included_content.rs +++ b/crates/store/re_types/src/blueprint/components/included_content.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/interactive.rs b/crates/store/re_types/src/blueprint/components/interactive.rs index 5cf80fe44ddc..cdf7a9d5901e 100644 --- a/crates/store/re_types/src/blueprint/components/interactive.rs +++ b/crates/store/re_types/src/blueprint/components/interactive.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/lock_range_during_zoom.rs b/crates/store/re_types/src/blueprint/components/lock_range_during_zoom.rs index c06621d1dc93..eb96ac39b8a5 100644 --- a/crates/store/re_types/src/blueprint/components/lock_range_during_zoom.rs +++ b/crates/store/re_types/src/blueprint/components/lock_range_during_zoom.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/map_provider.rs b/crates/store/re_types/src/blueprint/components/map_provider.rs index ad764d173239..08a65c4b46a7 100644 --- a/crates/store/re_types/src/blueprint/components/map_provider.rs +++ b/crates/store/re_types/src/blueprint/components/map_provider.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/near_clip_plane.rs b/crates/store/re_types/src/blueprint/components/near_clip_plane.rs index 384eb76a11a5..6b5e77a57289 100644 --- a/crates/store/re_types/src/blueprint/components/near_clip_plane.rs +++ b/crates/store/re_types/src/blueprint/components/near_clip_plane.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/panel_state.rs b/crates/store/re_types/src/blueprint/components/panel_state.rs index a29107ea53f8..e918f1f3098b 100644 --- a/crates/store/re_types/src/blueprint/components/panel_state.rs +++ b/crates/store/re_types/src/blueprint/components/panel_state.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/query_expression.rs b/crates/store/re_types/src/blueprint/components/query_expression.rs index 8aeffb6455da..8aba7241f6a6 100644 --- a/crates/store/re_types/src/blueprint/components/query_expression.rs +++ b/crates/store/re_types/src/blueprint/components/query_expression.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/root_container.rs b/crates/store/re_types/src/blueprint/components/root_container.rs index a7229f5404b1..f7fbe5fcfdb6 100644 --- a/crates/store/re_types/src/blueprint/components/root_container.rs +++ b/crates/store/re_types/src/blueprint/components/root_container.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/row_share.rs b/crates/store/re_types/src/blueprint/components/row_share.rs index a034d968900b..c1bbf8bb310b 100644 --- a/crates/store/re_types/src/blueprint/components/row_share.rs +++ b/crates/store/re_types/src/blueprint/components/row_share.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/selected_columns.rs b/crates/store/re_types/src/blueprint/components/selected_columns.rs index a06326bbea9b..6c080b410bd4 100644 --- a/crates/store/re_types/src/blueprint/components/selected_columns.rs +++ b/crates/store/re_types/src/blueprint/components/selected_columns.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/tensor_dimension_index_slider.rs b/crates/store/re_types/src/blueprint/components/tensor_dimension_index_slider.rs index c749f8869fcb..91aee85a6997 100644 --- a/crates/store/re_types/src/blueprint/components/tensor_dimension_index_slider.rs +++ b/crates/store/re_types/src/blueprint/components/tensor_dimension_index_slider.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/timeline_name.rs b/crates/store/re_types/src/blueprint/components/timeline_name.rs index 87752231d9b8..8b2e3ccbac73 100644 --- a/crates/store/re_types/src/blueprint/components/timeline_name.rs +++ b/crates/store/re_types/src/blueprint/components/timeline_name.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/view_class.rs b/crates/store/re_types/src/blueprint/components/view_class.rs index 9da8e7f78b88..659b6728122d 100644 --- a/crates/store/re_types/src/blueprint/components/view_class.rs +++ b/crates/store/re_types/src/blueprint/components/view_class.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/view_fit.rs b/crates/store/re_types/src/blueprint/components/view_fit.rs index 2a3fb9c2fdf9..8dd32122f914 100644 --- a/crates/store/re_types/src/blueprint/components/view_fit.rs +++ b/crates/store/re_types/src/blueprint/components/view_fit.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/view_maximized.rs b/crates/store/re_types/src/blueprint/components/view_maximized.rs index d9db278c87aa..afd1cdac36e1 100644 --- a/crates/store/re_types/src/blueprint/components/view_maximized.rs +++ b/crates/store/re_types/src/blueprint/components/view_maximized.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/view_origin.rs b/crates/store/re_types/src/blueprint/components/view_origin.rs index 1fe49e41b346..b76c3e642446 100644 --- a/crates/store/re_types/src/blueprint/components/view_origin.rs +++ b/crates/store/re_types/src/blueprint/components/view_origin.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/viewer_recommendation_hash.rs b/crates/store/re_types/src/blueprint/components/viewer_recommendation_hash.rs index 6af94f115973..fbf037b84741 100644 --- a/crates/store/re_types/src/blueprint/components/viewer_recommendation_hash.rs +++ b/crates/store/re_types/src/blueprint/components/viewer_recommendation_hash.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/visible.rs b/crates/store/re_types/src/blueprint/components/visible.rs index 0e6b02b8e321..838565bff5e9 100644 --- a/crates/store/re_types/src/blueprint/components/visible.rs +++ b/crates/store/re_types/src/blueprint/components/visible.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/visible_time_range.rs b/crates/store/re_types/src/blueprint/components/visible_time_range.rs index a39c447e73b8..036036aedc9d 100644 --- a/crates/store/re_types/src/blueprint/components/visible_time_range.rs +++ b/crates/store/re_types/src/blueprint/components/visible_time_range.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/visual_bounds2d.rs b/crates/store/re_types/src/blueprint/components/visual_bounds2d.rs index e29d1785ee22..d427f36efab9 100644 --- a/crates/store/re_types/src/blueprint/components/visual_bounds2d.rs +++ b/crates/store/re_types/src/blueprint/components/visual_bounds2d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/visualizer_overrides.rs b/crates/store/re_types/src/blueprint/components/visualizer_overrides.rs index 6eefee094b8d..eda1fa427e7c 100644 --- a/crates/store/re_types/src/blueprint/components/visualizer_overrides.rs +++ b/crates/store/re_types/src/blueprint/components/visualizer_overrides.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/components/zoom_level.rs b/crates/store/re_types/src/blueprint/components/zoom_level.rs index 4eebc060b74a..b1feded6ebc6 100644 --- a/crates/store/re_types/src/blueprint/components/zoom_level.rs +++ b/crates/store/re_types/src/blueprint/components/zoom_level.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/datatypes/component_column_selector.rs b/crates/store/re_types/src/blueprint/datatypes/component_column_selector.rs index e749c618a07c..2dde6fbb57c1 100644 --- a/crates/store/re_types/src/blueprint/datatypes/component_column_selector.rs +++ b/crates/store/re_types/src/blueprint/datatypes/component_column_selector.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/datatypes/filter_by_range.rs b/crates/store/re_types/src/blueprint/datatypes/filter_by_range.rs index 095e918cd8ed..696911a2c8c3 100644 --- a/crates/store/re_types/src/blueprint/datatypes/filter_by_range.rs +++ b/crates/store/re_types/src/blueprint/datatypes/filter_by_range.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/datatypes/filter_is_not_null.rs b/crates/store/re_types/src/blueprint/datatypes/filter_is_not_null.rs index 69d39160e5a1..ac0a5f8e0b38 100644 --- a/crates/store/re_types/src/blueprint/datatypes/filter_is_not_null.rs +++ b/crates/store/re_types/src/blueprint/datatypes/filter_is_not_null.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/datatypes/selected_columns.rs b/crates/store/re_types/src/blueprint/datatypes/selected_columns.rs index 885984d19456..43d8bec361a1 100644 --- a/crates/store/re_types/src/blueprint/datatypes/selected_columns.rs +++ b/crates/store/re_types/src/blueprint/datatypes/selected_columns.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/datatypes/tensor_dimension_index_slider.rs b/crates/store/re_types/src/blueprint/datatypes/tensor_dimension_index_slider.rs index ba1cd75100b0..d31ecd59ed56 100644 --- a/crates/store/re_types/src/blueprint/datatypes/tensor_dimension_index_slider.rs +++ b/crates/store/re_types/src/blueprint/datatypes/tensor_dimension_index_slider.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/datatypes/utf8list.rs b/crates/store/re_types/src/blueprint/datatypes/utf8list.rs index 8ccff46c6ec7..0e2bf517c123 100644 --- a/crates/store/re_types/src/blueprint/datatypes/utf8list.rs +++ b/crates/store/re_types/src/blueprint/datatypes/utf8list.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/views/bar_chart_view.rs b/crates/store/re_types/src/blueprint/views/bar_chart_view.rs index 06b3b09f46ae..29fa957fa493 100644 --- a/crates/store/re_types/src/blueprint/views/bar_chart_view.rs +++ b/crates/store/re_types/src/blueprint/views/bar_chart_view.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/views/dataframe_view.rs b/crates/store/re_types/src/blueprint/views/dataframe_view.rs index 172d2bf70afa..3b71a7d57243 100644 --- a/crates/store/re_types/src/blueprint/views/dataframe_view.rs +++ b/crates/store/re_types/src/blueprint/views/dataframe_view.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/views/graph_view.rs b/crates/store/re_types/src/blueprint/views/graph_view.rs index 885cdb6605ea..5a99bd126e53 100644 --- a/crates/store/re_types/src/blueprint/views/graph_view.rs +++ b/crates/store/re_types/src/blueprint/views/graph_view.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/views/map_view.rs b/crates/store/re_types/src/blueprint/views/map_view.rs index 5d6142d37e63..cd717be84a04 100644 --- a/crates/store/re_types/src/blueprint/views/map_view.rs +++ b/crates/store/re_types/src/blueprint/views/map_view.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/views/spatial2d_view.rs b/crates/store/re_types/src/blueprint/views/spatial2d_view.rs index 4aad1cc8585a..964d6a4fea08 100644 --- a/crates/store/re_types/src/blueprint/views/spatial2d_view.rs +++ b/crates/store/re_types/src/blueprint/views/spatial2d_view.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/views/spatial3d_view.rs b/crates/store/re_types/src/blueprint/views/spatial3d_view.rs index 3acbb006ec82..dd967fb88bc6 100644 --- a/crates/store/re_types/src/blueprint/views/spatial3d_view.rs +++ b/crates/store/re_types/src/blueprint/views/spatial3d_view.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/views/tensor_view.rs b/crates/store/re_types/src/blueprint/views/tensor_view.rs index adf89dc6cf03..6d75fde69a19 100644 --- a/crates/store/re_types/src/blueprint/views/tensor_view.rs +++ b/crates/store/re_types/src/blueprint/views/tensor_view.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/views/text_document_view.rs b/crates/store/re_types/src/blueprint/views/text_document_view.rs index d958f115d25c..a3508ebf9329 100644 --- a/crates/store/re_types/src/blueprint/views/text_document_view.rs +++ b/crates/store/re_types/src/blueprint/views/text_document_view.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/views/text_log_view.rs b/crates/store/re_types/src/blueprint/views/text_log_view.rs index 9bbac80422aa..2dacea70d743 100644 --- a/crates/store/re_types/src/blueprint/views/text_log_view.rs +++ b/crates/store/re_types/src/blueprint/views/text_log_view.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/blueprint/views/time_series_view.rs b/crates/store/re_types/src/blueprint/views/time_series_view.rs index 9967cd94f4ab..7a718eedf993 100644 --- a/crates/store/re_types/src/blueprint/views/time_series_view.rs +++ b/crates/store/re_types/src/blueprint/views/time_series_view.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/aggregation_policy.rs b/crates/store/re_types/src/components/aggregation_policy.rs index dcd7f0684fb6..19b874a919a0 100644 --- a/crates/store/re_types/src/components/aggregation_policy.rs +++ b/crates/store/re_types/src/components/aggregation_policy.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/albedo_factor.rs b/crates/store/re_types/src/components/albedo_factor.rs index 9d7b2d354fa0..45cdfd75d53f 100644 --- a/crates/store/re_types/src/components/albedo_factor.rs +++ b/crates/store/re_types/src/components/albedo_factor.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/annotation_context.rs b/crates/store/re_types/src/components/annotation_context.rs index 194b745375b4..31f628218df0 100644 --- a/crates/store/re_types/src/components/annotation_context.rs +++ b/crates/store/re_types/src/components/annotation_context.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/axis_length.rs b/crates/store/re_types/src/components/axis_length.rs index 722edf9bd427..fb016e17b256 100644 --- a/crates/store/re_types/src/components/axis_length.rs +++ b/crates/store/re_types/src/components/axis_length.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/blob.rs b/crates/store/re_types/src/components/blob.rs index 022750bdda3b..2148cb941c58 100644 --- a/crates/store/re_types/src/components/blob.rs +++ b/crates/store/re_types/src/components/blob.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/class_id.rs b/crates/store/re_types/src/components/class_id.rs index e16850292cf8..020f9ed24c64 100644 --- a/crates/store/re_types/src/components/class_id.rs +++ b/crates/store/re_types/src/components/class_id.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/color.rs b/crates/store/re_types/src/components/color.rs index 49e15a98733d..80b1a9d7ba04 100644 --- a/crates/store/re_types/src/components/color.rs +++ b/crates/store/re_types/src/components/color.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/colormap.rs b/crates/store/re_types/src/components/colormap.rs index 90a57d0a630b..969a0f62f7e6 100644 --- a/crates/store/re_types/src/components/colormap.rs +++ b/crates/store/re_types/src/components/colormap.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/depth_meter.rs b/crates/store/re_types/src/components/depth_meter.rs index 46464337b2e2..6580c390066b 100644 --- a/crates/store/re_types/src/components/depth_meter.rs +++ b/crates/store/re_types/src/components/depth_meter.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/draw_order.rs b/crates/store/re_types/src/components/draw_order.rs index d28fe41539a8..e699b097b2a3 100644 --- a/crates/store/re_types/src/components/draw_order.rs +++ b/crates/store/re_types/src/components/draw_order.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/entity_path.rs b/crates/store/re_types/src/components/entity_path.rs index 106475c4c466..eee07c4c5c86 100644 --- a/crates/store/re_types/src/components/entity_path.rs +++ b/crates/store/re_types/src/components/entity_path.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/fill_mode.rs b/crates/store/re_types/src/components/fill_mode.rs index 004d2538cf28..ba6f38fa611c 100644 --- a/crates/store/re_types/src/components/fill_mode.rs +++ b/crates/store/re_types/src/components/fill_mode.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/fill_ratio.rs b/crates/store/re_types/src/components/fill_ratio.rs index 1d5bde9cfc42..8e351a5bac4d 100644 --- a/crates/store/re_types/src/components/fill_ratio.rs +++ b/crates/store/re_types/src/components/fill_ratio.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/gamma_correction.rs b/crates/store/re_types/src/components/gamma_correction.rs index a0986e24e194..3ee9374feef1 100644 --- a/crates/store/re_types/src/components/gamma_correction.rs +++ b/crates/store/re_types/src/components/gamma_correction.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/geo_line_string.rs b/crates/store/re_types/src/components/geo_line_string.rs index d1ba3cc65de1..f22cd05ee8dc 100644 --- a/crates/store/re_types/src/components/geo_line_string.rs +++ b/crates/store/re_types/src/components/geo_line_string.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/graph_edge.rs b/crates/store/re_types/src/components/graph_edge.rs index 8eed941ad2d2..877b4815db79 100644 --- a/crates/store/re_types/src/components/graph_edge.rs +++ b/crates/store/re_types/src/components/graph_edge.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/graph_node.rs b/crates/store/re_types/src/components/graph_node.rs index 42565d20e9c5..b2ec7be326ee 100644 --- a/crates/store/re_types/src/components/graph_node.rs +++ b/crates/store/re_types/src/components/graph_node.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/graph_type.rs b/crates/store/re_types/src/components/graph_type.rs index b0846f0d67dd..4f4c03f135ce 100644 --- a/crates/store/re_types/src/components/graph_type.rs +++ b/crates/store/re_types/src/components/graph_type.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/half_size2d.rs b/crates/store/re_types/src/components/half_size2d.rs index ae34e95a5f64..b748be80fbec 100644 --- a/crates/store/re_types/src/components/half_size2d.rs +++ b/crates/store/re_types/src/components/half_size2d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/half_size3d.rs b/crates/store/re_types/src/components/half_size3d.rs index cb0072d24805..f64fe87bace6 100644 --- a/crates/store/re_types/src/components/half_size3d.rs +++ b/crates/store/re_types/src/components/half_size3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/image_buffer.rs b/crates/store/re_types/src/components/image_buffer.rs index f0e7b8af7aa0..e37bd67bf0f3 100644 --- a/crates/store/re_types/src/components/image_buffer.rs +++ b/crates/store/re_types/src/components/image_buffer.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/image_format.rs b/crates/store/re_types/src/components/image_format.rs index 6beb6ce51bc1..33dd4f369312 100644 --- a/crates/store/re_types/src/components/image_format.rs +++ b/crates/store/re_types/src/components/image_format.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/image_plane_distance.rs b/crates/store/re_types/src/components/image_plane_distance.rs index 634e0d49ebf9..c6c80562c420 100644 --- a/crates/store/re_types/src/components/image_plane_distance.rs +++ b/crates/store/re_types/src/components/image_plane_distance.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/keypoint_id.rs b/crates/store/re_types/src/components/keypoint_id.rs index cdd8795f951d..d7ffad1f2699 100644 --- a/crates/store/re_types/src/components/keypoint_id.rs +++ b/crates/store/re_types/src/components/keypoint_id.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/lat_lon.rs b/crates/store/re_types/src/components/lat_lon.rs index c978842c6f49..857068d89c57 100644 --- a/crates/store/re_types/src/components/lat_lon.rs +++ b/crates/store/re_types/src/components/lat_lon.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/length.rs b/crates/store/re_types/src/components/length.rs index 4549de30bb30..7039d630f8a5 100644 --- a/crates/store/re_types/src/components/length.rs +++ b/crates/store/re_types/src/components/length.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/line_strip2d.rs b/crates/store/re_types/src/components/line_strip2d.rs index b727f3c38672..12e9afd4ff3a 100644 --- a/crates/store/re_types/src/components/line_strip2d.rs +++ b/crates/store/re_types/src/components/line_strip2d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/line_strip3d.rs b/crates/store/re_types/src/components/line_strip3d.rs index 8c9ef7506e69..59c4d4b70300 100644 --- a/crates/store/re_types/src/components/line_strip3d.rs +++ b/crates/store/re_types/src/components/line_strip3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/magnification_filter.rs b/crates/store/re_types/src/components/magnification_filter.rs index 9d5a5631a00f..1b4eb5ea3eb4 100644 --- a/crates/store/re_types/src/components/magnification_filter.rs +++ b/crates/store/re_types/src/components/magnification_filter.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/marker_shape.rs b/crates/store/re_types/src/components/marker_shape.rs index 39eb72988474..cea44fe1bc5f 100644 --- a/crates/store/re_types/src/components/marker_shape.rs +++ b/crates/store/re_types/src/components/marker_shape.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/marker_size.rs b/crates/store/re_types/src/components/marker_size.rs index 617bb824a028..896aa14f4d98 100644 --- a/crates/store/re_types/src/components/marker_size.rs +++ b/crates/store/re_types/src/components/marker_size.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/media_type.rs b/crates/store/re_types/src/components/media_type.rs index fd9ad84fb9bf..d75ef3d9a5a9 100644 --- a/crates/store/re_types/src/components/media_type.rs +++ b/crates/store/re_types/src/components/media_type.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/name.rs b/crates/store/re_types/src/components/name.rs index ff2e8281c401..d847bb2a55af 100644 --- a/crates/store/re_types/src/components/name.rs +++ b/crates/store/re_types/src/components/name.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/opacity.rs b/crates/store/re_types/src/components/opacity.rs index 58a6a52e4074..e40e51ae00d7 100644 --- a/crates/store/re_types/src/components/opacity.rs +++ b/crates/store/re_types/src/components/opacity.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/pinhole_projection.rs b/crates/store/re_types/src/components/pinhole_projection.rs index 1dddd8a46995..c36f0a00a6e3 100644 --- a/crates/store/re_types/src/components/pinhole_projection.rs +++ b/crates/store/re_types/src/components/pinhole_projection.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/plane3d.rs b/crates/store/re_types/src/components/plane3d.rs index 2a34c7990e35..d284b634c8ad 100644 --- a/crates/store/re_types/src/components/plane3d.rs +++ b/crates/store/re_types/src/components/plane3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/pose_rotation_axis_angle.rs b/crates/store/re_types/src/components/pose_rotation_axis_angle.rs index 70a70395d2fd..d2d06f17b943 100644 --- a/crates/store/re_types/src/components/pose_rotation_axis_angle.rs +++ b/crates/store/re_types/src/components/pose_rotation_axis_angle.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/pose_rotation_quat.rs b/crates/store/re_types/src/components/pose_rotation_quat.rs index 44fd3f2fb038..7c9c34529f8b 100644 --- a/crates/store/re_types/src/components/pose_rotation_quat.rs +++ b/crates/store/re_types/src/components/pose_rotation_quat.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/pose_scale3d.rs b/crates/store/re_types/src/components/pose_scale3d.rs index ff391e032d0d..38e24437323c 100644 --- a/crates/store/re_types/src/components/pose_scale3d.rs +++ b/crates/store/re_types/src/components/pose_scale3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/pose_transform_mat3x3.rs b/crates/store/re_types/src/components/pose_transform_mat3x3.rs index 2ebc6cd241fe..d870bf241669 100644 --- a/crates/store/re_types/src/components/pose_transform_mat3x3.rs +++ b/crates/store/re_types/src/components/pose_transform_mat3x3.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/pose_translation3d.rs b/crates/store/re_types/src/components/pose_translation3d.rs index 8dc154e7b17f..f0ecb52c00be 100644 --- a/crates/store/re_types/src/components/pose_translation3d.rs +++ b/crates/store/re_types/src/components/pose_translation3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/position2d.rs b/crates/store/re_types/src/components/position2d.rs index c0346a3f3f5c..059bf4fa3dc6 100644 --- a/crates/store/re_types/src/components/position2d.rs +++ b/crates/store/re_types/src/components/position2d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/position3d.rs b/crates/store/re_types/src/components/position3d.rs index 4f98af93e4d9..be84619c40e6 100644 --- a/crates/store/re_types/src/components/position3d.rs +++ b/crates/store/re_types/src/components/position3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/radius.rs b/crates/store/re_types/src/components/radius.rs index 84ea10ffb9b0..323d4c927512 100644 --- a/crates/store/re_types/src/components/radius.rs +++ b/crates/store/re_types/src/components/radius.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/range1d.rs b/crates/store/re_types/src/components/range1d.rs index 336a7af848cc..519bff1d5334 100644 --- a/crates/store/re_types/src/components/range1d.rs +++ b/crates/store/re_types/src/components/range1d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/recording_uri.rs b/crates/store/re_types/src/components/recording_uri.rs index ba0ffd32e3b8..2c010dbf69ca 100644 --- a/crates/store/re_types/src/components/recording_uri.rs +++ b/crates/store/re_types/src/components/recording_uri.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/resolution.rs b/crates/store/re_types/src/components/resolution.rs index fd2d8e4e8c50..942e8ded5d9a 100644 --- a/crates/store/re_types/src/components/resolution.rs +++ b/crates/store/re_types/src/components/resolution.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/rotation_axis_angle.rs b/crates/store/re_types/src/components/rotation_axis_angle.rs index ddc1d6961ed5..b76abaa079a2 100644 --- a/crates/store/re_types/src/components/rotation_axis_angle.rs +++ b/crates/store/re_types/src/components/rotation_axis_angle.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/rotation_quat.rs b/crates/store/re_types/src/components/rotation_quat.rs index d1c354b3c048..5eb6c2773f38 100644 --- a/crates/store/re_types/src/components/rotation_quat.rs +++ b/crates/store/re_types/src/components/rotation_quat.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/scalar.rs b/crates/store/re_types/src/components/scalar.rs index 7073a274c156..5c215db20704 100644 --- a/crates/store/re_types/src/components/scalar.rs +++ b/crates/store/re_types/src/components/scalar.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/scale3d.rs b/crates/store/re_types/src/components/scale3d.rs index d131ec69ee63..53cf03a89305 100644 --- a/crates/store/re_types/src/components/scale3d.rs +++ b/crates/store/re_types/src/components/scale3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/show_labels.rs b/crates/store/re_types/src/components/show_labels.rs index 83685dbfa29f..505d7e7b4892 100644 --- a/crates/store/re_types/src/components/show_labels.rs +++ b/crates/store/re_types/src/components/show_labels.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/stroke_width.rs b/crates/store/re_types/src/components/stroke_width.rs index 16d853d43c60..a60591fd8586 100644 --- a/crates/store/re_types/src/components/stroke_width.rs +++ b/crates/store/re_types/src/components/stroke_width.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/tensor_data.rs b/crates/store/re_types/src/components/tensor_data.rs index e60ddff6d622..5b012c667e14 100644 --- a/crates/store/re_types/src/components/tensor_data.rs +++ b/crates/store/re_types/src/components/tensor_data.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/tensor_dimension_index_selection.rs b/crates/store/re_types/src/components/tensor_dimension_index_selection.rs index 8170519c013a..cb52ac4e32d4 100644 --- a/crates/store/re_types/src/components/tensor_dimension_index_selection.rs +++ b/crates/store/re_types/src/components/tensor_dimension_index_selection.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/tensor_height_dimension.rs b/crates/store/re_types/src/components/tensor_height_dimension.rs index 4b4b27c7edf2..cfa1b1cac397 100644 --- a/crates/store/re_types/src/components/tensor_height_dimension.rs +++ b/crates/store/re_types/src/components/tensor_height_dimension.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/tensor_width_dimension.rs b/crates/store/re_types/src/components/tensor_width_dimension.rs index df018addf686..0a395c69b217 100644 --- a/crates/store/re_types/src/components/tensor_width_dimension.rs +++ b/crates/store/re_types/src/components/tensor_width_dimension.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/texcoord2d.rs b/crates/store/re_types/src/components/texcoord2d.rs index ed5002ed2b5c..d01cf77aa12b 100644 --- a/crates/store/re_types/src/components/texcoord2d.rs +++ b/crates/store/re_types/src/components/texcoord2d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/text.rs b/crates/store/re_types/src/components/text.rs index 4ea697a899ce..014369c11e14 100644 --- a/crates/store/re_types/src/components/text.rs +++ b/crates/store/re_types/src/components/text.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/text_log_level.rs b/crates/store/re_types/src/components/text_log_level.rs index 2cb0f1be4583..4fc5e833567d 100644 --- a/crates/store/re_types/src/components/text_log_level.rs +++ b/crates/store/re_types/src/components/text_log_level.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/transform_mat3x3.rs b/crates/store/re_types/src/components/transform_mat3x3.rs index 7712852f0194..4b22174bae9e 100644 --- a/crates/store/re_types/src/components/transform_mat3x3.rs +++ b/crates/store/re_types/src/components/transform_mat3x3.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/transform_relation.rs b/crates/store/re_types/src/components/transform_relation.rs index add1dbc0b74c..9aa39cade685 100644 --- a/crates/store/re_types/src/components/transform_relation.rs +++ b/crates/store/re_types/src/components/transform_relation.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/translation3d.rs b/crates/store/re_types/src/components/translation3d.rs index 0627084829df..30451799c04c 100644 --- a/crates/store/re_types/src/components/translation3d.rs +++ b/crates/store/re_types/src/components/translation3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/triangle_indices.rs b/crates/store/re_types/src/components/triangle_indices.rs index 8d34b46ba81f..63d5316e6637 100644 --- a/crates/store/re_types/src/components/triangle_indices.rs +++ b/crates/store/re_types/src/components/triangle_indices.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/value_range.rs b/crates/store/re_types/src/components/value_range.rs index 22272cd82bd4..ccaa552121e3 100644 --- a/crates/store/re_types/src/components/value_range.rs +++ b/crates/store/re_types/src/components/value_range.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/vector2d.rs b/crates/store/re_types/src/components/vector2d.rs index 4e4ed06698f4..80640d73335a 100644 --- a/crates/store/re_types/src/components/vector2d.rs +++ b/crates/store/re_types/src/components/vector2d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/vector3d.rs b/crates/store/re_types/src/components/vector3d.rs index bd9dd507e389..6a5388c1da2c 100644 --- a/crates/store/re_types/src/components/vector3d.rs +++ b/crates/store/re_types/src/components/vector3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/video_timestamp.rs b/crates/store/re_types/src/components/video_timestamp.rs index d7d3c447adaf..4ebc48ec98c6 100644 --- a/crates/store/re_types/src/components/video_timestamp.rs +++ b/crates/store/re_types/src/components/video_timestamp.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/components/view_coordinates.rs b/crates/store/re_types/src/components/view_coordinates.rs index 615179efcd66..a4c317487d4c 100644 --- a/crates/store/re_types/src/components/view_coordinates.rs +++ b/crates/store/re_types/src/components/view_coordinates.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/angle.rs b/crates/store/re_types/src/datatypes/angle.rs index e130da32da55..7602af41cd53 100644 --- a/crates/store/re_types/src/datatypes/angle.rs +++ b/crates/store/re_types/src/datatypes/angle.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/annotation_info.rs b/crates/store/re_types/src/datatypes/annotation_info.rs index c061e4b7a73a..fc5903aecce8 100644 --- a/crates/store/re_types/src/datatypes/annotation_info.rs +++ b/crates/store/re_types/src/datatypes/annotation_info.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/blob.rs b/crates/store/re_types/src/datatypes/blob.rs index 44ac156e2fe7..b426c434fd58 100644 --- a/crates/store/re_types/src/datatypes/blob.rs +++ b/crates/store/re_types/src/datatypes/blob.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/channel_datatype.rs b/crates/store/re_types/src/datatypes/channel_datatype.rs index 86ba1c3faa46..0889533c2e76 100644 --- a/crates/store/re_types/src/datatypes/channel_datatype.rs +++ b/crates/store/re_types/src/datatypes/channel_datatype.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/class_description.rs b/crates/store/re_types/src/datatypes/class_description.rs index 1a9f0a0264c9..8a973105aaaa 100644 --- a/crates/store/re_types/src/datatypes/class_description.rs +++ b/crates/store/re_types/src/datatypes/class_description.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/class_description_map_elem.rs b/crates/store/re_types/src/datatypes/class_description_map_elem.rs index debd1de96def..e44381c2480b 100644 --- a/crates/store/re_types/src/datatypes/class_description_map_elem.rs +++ b/crates/store/re_types/src/datatypes/class_description_map_elem.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/class_id.rs b/crates/store/re_types/src/datatypes/class_id.rs index 270b8357bc95..d9edc5920617 100644 --- a/crates/store/re_types/src/datatypes/class_id.rs +++ b/crates/store/re_types/src/datatypes/class_id.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/color_model.rs b/crates/store/re_types/src/datatypes/color_model.rs index 5847c9428ebf..f7f6f68303b9 100644 --- a/crates/store/re_types/src/datatypes/color_model.rs +++ b/crates/store/re_types/src/datatypes/color_model.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/dvec2d.rs b/crates/store/re_types/src/datatypes/dvec2d.rs index e1fba77a96a1..dca7abb60020 100644 --- a/crates/store/re_types/src/datatypes/dvec2d.rs +++ b/crates/store/re_types/src/datatypes/dvec2d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/image_format.rs b/crates/store/re_types/src/datatypes/image_format.rs index 0b6573df5b24..c7be2dba584e 100644 --- a/crates/store/re_types/src/datatypes/image_format.rs +++ b/crates/store/re_types/src/datatypes/image_format.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/keypoint_id.rs b/crates/store/re_types/src/datatypes/keypoint_id.rs index 7b628dcb7f66..c3754c32712f 100644 --- a/crates/store/re_types/src/datatypes/keypoint_id.rs +++ b/crates/store/re_types/src/datatypes/keypoint_id.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/keypoint_pair.rs b/crates/store/re_types/src/datatypes/keypoint_pair.rs index 111dd73659f9..e7138ef83e81 100644 --- a/crates/store/re_types/src/datatypes/keypoint_pair.rs +++ b/crates/store/re_types/src/datatypes/keypoint_pair.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/mat3x3.rs b/crates/store/re_types/src/datatypes/mat3x3.rs index ca407ab35471..07c0f3ed03c8 100644 --- a/crates/store/re_types/src/datatypes/mat3x3.rs +++ b/crates/store/re_types/src/datatypes/mat3x3.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/mat4x4.rs b/crates/store/re_types/src/datatypes/mat4x4.rs index 540b511bff6b..9553147cdaec 100644 --- a/crates/store/re_types/src/datatypes/mat4x4.rs +++ b/crates/store/re_types/src/datatypes/mat4x4.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/pixel_format.rs b/crates/store/re_types/src/datatypes/pixel_format.rs index e934a4e0cf2d..a21cec6c4e21 100644 --- a/crates/store/re_types/src/datatypes/pixel_format.rs +++ b/crates/store/re_types/src/datatypes/pixel_format.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/plane3d.rs b/crates/store/re_types/src/datatypes/plane3d.rs index beeddac84549..e807be38bf01 100644 --- a/crates/store/re_types/src/datatypes/plane3d.rs +++ b/crates/store/re_types/src/datatypes/plane3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/quaternion.rs b/crates/store/re_types/src/datatypes/quaternion.rs index e60ca25dec16..f33e6a0aab0e 100644 --- a/crates/store/re_types/src/datatypes/quaternion.rs +++ b/crates/store/re_types/src/datatypes/quaternion.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/range1d.rs b/crates/store/re_types/src/datatypes/range1d.rs index d539d4864e15..9db25bd1a9cb 100644 --- a/crates/store/re_types/src/datatypes/range1d.rs +++ b/crates/store/re_types/src/datatypes/range1d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/range2d.rs b/crates/store/re_types/src/datatypes/range2d.rs index 86bca486283e..09bd52b0caf7 100644 --- a/crates/store/re_types/src/datatypes/range2d.rs +++ b/crates/store/re_types/src/datatypes/range2d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/rgba32.rs b/crates/store/re_types/src/datatypes/rgba32.rs index d9dd349a7f8b..df5cff7bac2e 100644 --- a/crates/store/re_types/src/datatypes/rgba32.rs +++ b/crates/store/re_types/src/datatypes/rgba32.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/rotation_axis_angle.rs b/crates/store/re_types/src/datatypes/rotation_axis_angle.rs index c12faed9f37b..4e2efc7e17ca 100644 --- a/crates/store/re_types/src/datatypes/rotation_axis_angle.rs +++ b/crates/store/re_types/src/datatypes/rotation_axis_angle.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/tensor_buffer.rs b/crates/store/re_types/src/datatypes/tensor_buffer.rs index b01022c0e9c8..19df1b11c690 100644 --- a/crates/store/re_types/src/datatypes/tensor_buffer.rs +++ b/crates/store/re_types/src/datatypes/tensor_buffer.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/tensor_data.rs b/crates/store/re_types/src/datatypes/tensor_data.rs index f8f4333e71af..315248747bee 100644 --- a/crates/store/re_types/src/datatypes/tensor_data.rs +++ b/crates/store/re_types/src/datatypes/tensor_data.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/tensor_dimension_index_selection.rs b/crates/store/re_types/src/datatypes/tensor_dimension_index_selection.rs index 8007da1d08ae..b344d5477865 100644 --- a/crates/store/re_types/src/datatypes/tensor_dimension_index_selection.rs +++ b/crates/store/re_types/src/datatypes/tensor_dimension_index_selection.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/tensor_dimension_selection.rs b/crates/store/re_types/src/datatypes/tensor_dimension_selection.rs index ca4a71c8f667..7f7e73bcf8a9 100644 --- a/crates/store/re_types/src/datatypes/tensor_dimension_selection.rs +++ b/crates/store/re_types/src/datatypes/tensor_dimension_selection.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/utf8pair.rs b/crates/store/re_types/src/datatypes/utf8pair.rs index 5de43d0e2862..928fb06e5fe6 100644 --- a/crates/store/re_types/src/datatypes/utf8pair.rs +++ b/crates/store/re_types/src/datatypes/utf8pair.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/uuid.rs b/crates/store/re_types/src/datatypes/uuid.rs index 0aa243465bb3..6f9c8d548741 100644 --- a/crates/store/re_types/src/datatypes/uuid.rs +++ b/crates/store/re_types/src/datatypes/uuid.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/uvec2d.rs b/crates/store/re_types/src/datatypes/uvec2d.rs index 26674bd0813d..d99841311376 100644 --- a/crates/store/re_types/src/datatypes/uvec2d.rs +++ b/crates/store/re_types/src/datatypes/uvec2d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/uvec3d.rs b/crates/store/re_types/src/datatypes/uvec3d.rs index 35b1b6961f2b..99a0dcf95dee 100644 --- a/crates/store/re_types/src/datatypes/uvec3d.rs +++ b/crates/store/re_types/src/datatypes/uvec3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/uvec4d.rs b/crates/store/re_types/src/datatypes/uvec4d.rs index da39e7ad8356..4b76b63b8e21 100644 --- a/crates/store/re_types/src/datatypes/uvec4d.rs +++ b/crates/store/re_types/src/datatypes/uvec4d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/vec2d.rs b/crates/store/re_types/src/datatypes/vec2d.rs index 19e75e270cf7..02250192f749 100644 --- a/crates/store/re_types/src/datatypes/vec2d.rs +++ b/crates/store/re_types/src/datatypes/vec2d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/vec3d.rs b/crates/store/re_types/src/datatypes/vec3d.rs index f9c8ca82043a..b36a06e8a0e2 100644 --- a/crates/store/re_types/src/datatypes/vec3d.rs +++ b/crates/store/re_types/src/datatypes/vec3d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/vec4d.rs b/crates/store/re_types/src/datatypes/vec4d.rs index 51cb7cce251d..0c3ddefbd9e6 100644 --- a/crates/store/re_types/src/datatypes/vec4d.rs +++ b/crates/store/re_types/src/datatypes/vec4d.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/video_timestamp.rs b/crates/store/re_types/src/datatypes/video_timestamp.rs index 25b7c7eeecd6..ed839f0cc9d8 100644 --- a/crates/store/re_types/src/datatypes/video_timestamp.rs +++ b/crates/store/re_types/src/datatypes/video_timestamp.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/datatypes/view_coordinates.rs b/crates/store/re_types/src/datatypes/view_coordinates.rs index 9abae8fa5c8d..b73a1c3a365f 100644 --- a/crates/store/re_types/src/datatypes/view_coordinates.rs +++ b/crates/store/re_types/src/datatypes/view_coordinates.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/archetypes/affix_fuzzer1.rs b/crates/store/re_types/src/testing/archetypes/affix_fuzzer1.rs index 482b2ea77fdc..ff489dee4de3 100644 --- a/crates/store/re_types/src/testing/archetypes/affix_fuzzer1.rs +++ b/crates/store/re_types/src/testing/archetypes/affix_fuzzer1.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/archetypes/affix_fuzzer2.rs b/crates/store/re_types/src/testing/archetypes/affix_fuzzer2.rs index 6cbf0a642ec3..6c448e386ddd 100644 --- a/crates/store/re_types/src/testing/archetypes/affix_fuzzer2.rs +++ b/crates/store/re_types/src/testing/archetypes/affix_fuzzer2.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/archetypes/affix_fuzzer3.rs b/crates/store/re_types/src/testing/archetypes/affix_fuzzer3.rs index b8d68b503664..dd08e2fe4d63 100644 --- a/crates/store/re_types/src/testing/archetypes/affix_fuzzer3.rs +++ b/crates/store/re_types/src/testing/archetypes/affix_fuzzer3.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/archetypes/affix_fuzzer4.rs b/crates/store/re_types/src/testing/archetypes/affix_fuzzer4.rs index 897a08968001..aba3e4f94d71 100644 --- a/crates/store/re_types/src/testing/archetypes/affix_fuzzer4.rs +++ b/crates/store/re_types/src/testing/archetypes/affix_fuzzer4.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer1.rs b/crates/store/re_types/src/testing/components/affix_fuzzer1.rs index 29505f44ad4c..c2cff8dec953 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer1.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer1.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer10.rs b/crates/store/re_types/src/testing/components/affix_fuzzer10.rs index 78d8120d6127..204f429d70fd 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer10.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer10.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer11.rs b/crates/store/re_types/src/testing/components/affix_fuzzer11.rs index 49cc82cd9612..8bd9d33d7946 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer11.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer11.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer12.rs b/crates/store/re_types/src/testing/components/affix_fuzzer12.rs index de971ef6edef..fbc078b5beb8 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer12.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer12.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer13.rs b/crates/store/re_types/src/testing/components/affix_fuzzer13.rs index c369624f4b94..9342d264d038 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer13.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer13.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer14.rs b/crates/store/re_types/src/testing/components/affix_fuzzer14.rs index d9729794c48c..5067593e81ee 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer14.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer14.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer15.rs b/crates/store/re_types/src/testing/components/affix_fuzzer15.rs index ef2450ebfa3b..cb2ad5bc1980 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer15.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer15.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer16.rs b/crates/store/re_types/src/testing/components/affix_fuzzer16.rs index 842062acb232..f2658bc06cb4 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer16.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer16.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer17.rs b/crates/store/re_types/src/testing/components/affix_fuzzer17.rs index 7d88994ebf5c..f3182b2fd257 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer17.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer17.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer18.rs b/crates/store/re_types/src/testing/components/affix_fuzzer18.rs index eb126b062116..fed1da38c806 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer18.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer18.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer19.rs b/crates/store/re_types/src/testing/components/affix_fuzzer19.rs index 4b334d0dbdb2..8b6032bd257a 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer19.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer19.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer2.rs b/crates/store/re_types/src/testing/components/affix_fuzzer2.rs index 4db29568518e..a932b92f47a7 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer2.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer2.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer20.rs b/crates/store/re_types/src/testing/components/affix_fuzzer20.rs index 1fc4f8d5dc23..1b5eb4731e3f 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer20.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer20.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer21.rs b/crates/store/re_types/src/testing/components/affix_fuzzer21.rs index a59e41f5558e..bca72320c768 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer21.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer21.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer22.rs b/crates/store/re_types/src/testing/components/affix_fuzzer22.rs index 31e17671c000..5ae4cbe887a3 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer22.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer22.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer23.rs b/crates/store/re_types/src/testing/components/affix_fuzzer23.rs index 7a18bab0d544..b4e46c296a92 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer23.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer23.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer3.rs b/crates/store/re_types/src/testing/components/affix_fuzzer3.rs index 51c4b053ecae..8617e5e18c61 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer3.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer3.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer4.rs b/crates/store/re_types/src/testing/components/affix_fuzzer4.rs index c126113aea85..fafb630b60bf 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer4.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer4.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer5.rs b/crates/store/re_types/src/testing/components/affix_fuzzer5.rs index e8be179ff786..4ad2ad080296 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer5.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer5.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer6.rs b/crates/store/re_types/src/testing/components/affix_fuzzer6.rs index a973a4c245f8..0b177e1e5e9c 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer6.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer6.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer7.rs b/crates/store/re_types/src/testing/components/affix_fuzzer7.rs index bc1f57c83281..3a0d8bf40484 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer7.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer7.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer8.rs b/crates/store/re_types/src/testing/components/affix_fuzzer8.rs index 8776ae35afc3..c775293cebc3 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer8.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer8.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/components/affix_fuzzer9.rs b/crates/store/re_types/src/testing/components/affix_fuzzer9.rs index 72718a1d0054..59e32c0d2904 100644 --- a/crates/store/re_types/src/testing/components/affix_fuzzer9.rs +++ b/crates/store/re_types/src/testing/components/affix_fuzzer9.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/datatypes/affix_fuzzer1.rs b/crates/store/re_types/src/testing/datatypes/affix_fuzzer1.rs index 638c5611a318..ea42e58924af 100644 --- a/crates/store/re_types/src/testing/datatypes/affix_fuzzer1.rs +++ b/crates/store/re_types/src/testing/datatypes/affix_fuzzer1.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/datatypes/affix_fuzzer2.rs b/crates/store/re_types/src/testing/datatypes/affix_fuzzer2.rs index 01996fb46bc4..a916b646eb3a 100644 --- a/crates/store/re_types/src/testing/datatypes/affix_fuzzer2.rs +++ b/crates/store/re_types/src/testing/datatypes/affix_fuzzer2.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/datatypes/affix_fuzzer20.rs b/crates/store/re_types/src/testing/datatypes/affix_fuzzer20.rs index 4574270fbbe0..e7b0af03f603 100644 --- a/crates/store/re_types/src/testing/datatypes/affix_fuzzer20.rs +++ b/crates/store/re_types/src/testing/datatypes/affix_fuzzer20.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/datatypes/affix_fuzzer21.rs b/crates/store/re_types/src/testing/datatypes/affix_fuzzer21.rs index ce8317cd7432..e9279ccb0602 100644 --- a/crates/store/re_types/src/testing/datatypes/affix_fuzzer21.rs +++ b/crates/store/re_types/src/testing/datatypes/affix_fuzzer21.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/datatypes/affix_fuzzer22.rs b/crates/store/re_types/src/testing/datatypes/affix_fuzzer22.rs index 9a993f87d7b5..1100cc809f1e 100644 --- a/crates/store/re_types/src/testing/datatypes/affix_fuzzer22.rs +++ b/crates/store/re_types/src/testing/datatypes/affix_fuzzer22.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/datatypes/affix_fuzzer3.rs b/crates/store/re_types/src/testing/datatypes/affix_fuzzer3.rs index 020cba986dab..547567ed035d 100644 --- a/crates/store/re_types/src/testing/datatypes/affix_fuzzer3.rs +++ b/crates/store/re_types/src/testing/datatypes/affix_fuzzer3.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/datatypes/affix_fuzzer4.rs b/crates/store/re_types/src/testing/datatypes/affix_fuzzer4.rs index cf0a30c779e4..e3126bb948c8 100644 --- a/crates/store/re_types/src/testing/datatypes/affix_fuzzer4.rs +++ b/crates/store/re_types/src/testing/datatypes/affix_fuzzer4.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/datatypes/affix_fuzzer5.rs b/crates/store/re_types/src/testing/datatypes/affix_fuzzer5.rs index 4faf06378952..385d878dd62f 100644 --- a/crates/store/re_types/src/testing/datatypes/affix_fuzzer5.rs +++ b/crates/store/re_types/src/testing/datatypes/affix_fuzzer5.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/datatypes/enum_test.rs b/crates/store/re_types/src/testing/datatypes/enum_test.rs index 529b5a1e205e..3cf1f93cadeb 100644 --- a/crates/store/re_types/src/testing/datatypes/enum_test.rs +++ b/crates/store/re_types/src/testing/datatypes/enum_test.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/datatypes/flattened_scalar.rs b/crates/store/re_types/src/testing/datatypes/flattened_scalar.rs index 9a0a55dfa505..7d39fe768ae8 100644 --- a/crates/store/re_types/src/testing/datatypes/flattened_scalar.rs +++ b/crates/store/re_types/src/testing/datatypes/flattened_scalar.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/datatypes/multi_enum.rs b/crates/store/re_types/src/testing/datatypes/multi_enum.rs index 3aae5a95e84d..bd19de09d3d9 100644 --- a/crates/store/re_types/src/testing/datatypes/multi_enum.rs +++ b/crates/store/re_types/src/testing/datatypes/multi_enum.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/datatypes/primitive_component.rs b/crates/store/re_types/src/testing/datatypes/primitive_component.rs index d749b7b8a267..3d7f926878e9 100644 --- a/crates/store/re_types/src/testing/datatypes/primitive_component.rs +++ b/crates/store/re_types/src/testing/datatypes/primitive_component.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/datatypes/string_component.rs b/crates/store/re_types/src/testing/datatypes/string_component.rs index 58cebe9c5c8b..fc7b9f1cdb06 100644 --- a/crates/store/re_types/src/testing/datatypes/string_component.rs +++ b/crates/store/re_types/src/testing/datatypes/string_component.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/src/testing/datatypes/valued_enum.rs b/crates/store/re_types/src/testing/datatypes/valued_enum.rs index 287f93a5cfd8..6191394e2fce 100644 --- a/crates/store/re_types/src/testing/datatypes/valued_enum.rs +++ b/crates/store/re_types/src/testing/datatypes/valued_enum.rs @@ -13,9 +13,9 @@ #![allow(clippy::too_many_lines)] #![allow(non_camel_case_types)] -use ::re_types_core::external::arrow; +use ::re_types_core::try_serialize_field; use ::re_types_core::SerializationResult; -use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use ::re_types_core::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types/tests/types/points3d.rs b/crates/store/re_types/tests/types/points3d.rs index 362d0b4a6110..37b8ea61d14c 100644 --- a/crates/store/re_types/tests/types/points3d.rs +++ b/crates/store/re_types/tests/types/points3d.rs @@ -1,4 +1,6 @@ -use re_types::{archetypes::Points3D, components, Archetype as _, AsComponents as _}; +use re_types::{ + archetypes::Points3D, components, Archetype as _, AsComponents as _, ComponentBatch, +}; #[test] fn roundtrip() { @@ -6,28 +8,39 @@ fn roundtrip() { positions: vec![ components::Position3D::new(1.0, 2.0, 3.0), // components::Position3D::new(4.0, 5.0, 6.0), - ], - radii: Some(vec![ + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Points3D::descriptor_positions())), + radii: vec![ components::Radius::from(42.0), // components::Radius::from(43.0), - ]), - colors: Some(vec![ + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Points3D::descriptor_radii())), + colors: vec![ components::Color::from_unmultiplied_rgba(0xAA, 0x00, 0x00, 0xCC), // components::Color::from_unmultiplied_rgba(0x00, 0xBB, 0x00, 0xDD), - ]), - labels: Some(vec![ - "hello".into(), // - "friend".into(), // - ]), - class_ids: Some(vec![ + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Points3D::descriptor_colors())), + labels: (vec!["hello".into(), "friend".into()] as Vec) + .serialized() + .map(|batch| batch.with_descriptor_override(Points3D::descriptor_labels())), + class_ids: vec![ components::ClassId::from(126), // components::ClassId::from(127), // - ]), - keypoint_ids: Some(vec![ + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Points3D::descriptor_class_ids())), + keypoint_ids: vec![ components::KeypointId::from(2), // components::KeypointId::from(3), // - ]), - show_labels: Some(true.into()), + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Points3D::descriptor_keypoint_ids())), + show_labels: components::ShowLabels(true.into()) + .serialized() + .map(|batch| batch.with_descriptor_override(Points3D::descriptor_show_labels())), }; let arch = Points3D::new([(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)]) diff --git a/crates/store/re_types_core/src/archetypes/clear.rs b/crates/store/re_types_core/src/archetypes/clear.rs index 3f480bdb7a43..f380e13e1295 100644 --- a/crates/store/re_types_core/src/archetypes/clear.rs +++ b/crates/store/re_types_core/src/archetypes/clear.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use crate::external::arrow; +use crate::try_serialize_field; use crate::SerializationResult; -use crate::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use crate::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use crate::{ComponentDescriptor, ComponentName}; use crate::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types_core/src/archetypes/clear_ext.rs b/crates/store/re_types_core/src/archetypes/clear_ext.rs index 50b7a581b095..5dfd3e4b0ffe 100644 --- a/crates/store/re_types_core/src/archetypes/clear_ext.rs +++ b/crates/store/re_types_core/src/archetypes/clear_ext.rs @@ -7,9 +7,7 @@ impl Clear { /// Children will be left untouched. #[inline] pub fn flat() -> Self { - Self { - is_recursive: false.into(), - } + Self::new(false) } /// Returns a recursive clear. @@ -17,8 +15,6 @@ impl Clear { /// This will empty all components of the associated entity at the logged timepoint, as well as /// all components of all its recursive children. pub fn recursive() -> Self { - Self { - is_recursive: true.into(), - } + Self::new(true) } } diff --git a/crates/store/re_types_core/src/components/clear_is_recursive.rs b/crates/store/re_types_core/src/components/clear_is_recursive.rs index 31d4da43f447..bea7656bbd70 100644 --- a/crates/store/re_types_core/src/components/clear_is_recursive.rs +++ b/crates/store/re_types_core/src/components/clear_is_recursive.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use crate::external::arrow; +use crate::try_serialize_field; use crate::SerializationResult; -use crate::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use crate::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use crate::{ComponentDescriptor, ComponentName}; use crate::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types_core/src/datatypes/bool.rs b/crates/store/re_types_core/src/datatypes/bool.rs index f3d984598a9c..5b0449faf392 100644 --- a/crates/store/re_types_core/src/datatypes/bool.rs +++ b/crates/store/re_types_core/src/datatypes/bool.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use crate::external::arrow; +use crate::try_serialize_field; use crate::SerializationResult; -use crate::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use crate::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use crate::{ComponentDescriptor, ComponentName}; use crate::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types_core/src/datatypes/entity_path.rs b/crates/store/re_types_core/src/datatypes/entity_path.rs index 2bc8087e5921..6d0dcb557526 100644 --- a/crates/store/re_types_core/src/datatypes/entity_path.rs +++ b/crates/store/re_types_core/src/datatypes/entity_path.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use crate::external::arrow; +use crate::try_serialize_field; use crate::SerializationResult; -use crate::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use crate::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use crate::{ComponentDescriptor, ComponentName}; use crate::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types_core/src/datatypes/float32.rs b/crates/store/re_types_core/src/datatypes/float32.rs index 0087f5dd0d2d..a896b9511961 100644 --- a/crates/store/re_types_core/src/datatypes/float32.rs +++ b/crates/store/re_types_core/src/datatypes/float32.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use crate::external::arrow; +use crate::try_serialize_field; use crate::SerializationResult; -use crate::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use crate::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use crate::{ComponentDescriptor, ComponentName}; use crate::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types_core/src/datatypes/float64.rs b/crates/store/re_types_core/src/datatypes/float64.rs index 441ef8f67755..f37dd44c68c0 100644 --- a/crates/store/re_types_core/src/datatypes/float64.rs +++ b/crates/store/re_types_core/src/datatypes/float64.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use crate::external::arrow; +use crate::try_serialize_field; use crate::SerializationResult; -use crate::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use crate::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use crate::{ComponentDescriptor, ComponentName}; use crate::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types_core/src/datatypes/time_int.rs b/crates/store/re_types_core/src/datatypes/time_int.rs index 78630dabef36..0e4140163f6a 100644 --- a/crates/store/re_types_core/src/datatypes/time_int.rs +++ b/crates/store/re_types_core/src/datatypes/time_int.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use crate::external::arrow; +use crate::try_serialize_field; use crate::SerializationResult; -use crate::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use crate::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use crate::{ComponentDescriptor, ComponentName}; use crate::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types_core/src/datatypes/time_range.rs b/crates/store/re_types_core/src/datatypes/time_range.rs index ad85212160be..bb531e04c3bb 100644 --- a/crates/store/re_types_core/src/datatypes/time_range.rs +++ b/crates/store/re_types_core/src/datatypes/time_range.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use crate::external::arrow; +use crate::try_serialize_field; use crate::SerializationResult; -use crate::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use crate::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use crate::{ComponentDescriptor, ComponentName}; use crate::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types_core/src/datatypes/time_range_boundary.rs b/crates/store/re_types_core/src/datatypes/time_range_boundary.rs index 644bd4883deb..00dbf2167aeb 100644 --- a/crates/store/re_types_core/src/datatypes/time_range_boundary.rs +++ b/crates/store/re_types_core/src/datatypes/time_range_boundary.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use crate::external::arrow; +use crate::try_serialize_field; use crate::SerializationResult; -use crate::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use crate::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use crate::{ComponentDescriptor, ComponentName}; use crate::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types_core/src/datatypes/uint16.rs b/crates/store/re_types_core/src/datatypes/uint16.rs index 63fc1a0c31d5..5f5454b8f398 100644 --- a/crates/store/re_types_core/src/datatypes/uint16.rs +++ b/crates/store/re_types_core/src/datatypes/uint16.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use crate::external::arrow; +use crate::try_serialize_field; use crate::SerializationResult; -use crate::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use crate::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use crate::{ComponentDescriptor, ComponentName}; use crate::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types_core/src/datatypes/uint32.rs b/crates/store/re_types_core/src/datatypes/uint32.rs index be5e4be8037f..7ea217ece7dc 100644 --- a/crates/store/re_types_core/src/datatypes/uint32.rs +++ b/crates/store/re_types_core/src/datatypes/uint32.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use crate::external::arrow; +use crate::try_serialize_field; use crate::SerializationResult; -use crate::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use crate::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use crate::{ComponentDescriptor, ComponentName}; use crate::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types_core/src/datatypes/uint64.rs b/crates/store/re_types_core/src/datatypes/uint64.rs index 43fb6ac9cd05..278a18839f90 100644 --- a/crates/store/re_types_core/src/datatypes/uint64.rs +++ b/crates/store/re_types_core/src/datatypes/uint64.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use crate::external::arrow; +use crate::try_serialize_field; use crate::SerializationResult; -use crate::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use crate::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use crate::{ComponentDescriptor, ComponentName}; use crate::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types_core/src/datatypes/utf8.rs b/crates/store/re_types_core/src/datatypes/utf8.rs index 630e2ed5c70f..8b5a927b46fb 100644 --- a/crates/store/re_types_core/src/datatypes/utf8.rs +++ b/crates/store/re_types_core/src/datatypes/utf8.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use crate::external::arrow; +use crate::try_serialize_field; use crate::SerializationResult; -use crate::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use crate::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use crate::{ComponentDescriptor, ComponentName}; use crate::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types_core/src/datatypes/visible_time_range.rs b/crates/store/re_types_core/src/datatypes/visible_time_range.rs index a763867bd657..c9855edf005e 100644 --- a/crates/store/re_types_core/src/datatypes/visible_time_range.rs +++ b/crates/store/re_types_core/src/datatypes/visible_time_range.rs @@ -12,9 +12,9 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -use crate::external::arrow; +use crate::try_serialize_field; use crate::SerializationResult; -use crate::{ComponentBatch, ComponentBatchCowWithDescriptor}; +use crate::{ComponentBatch, ComponentBatchCowWithDescriptor, SerializedComponentBatch}; use crate::{ComponentDescriptor, ComponentName}; use crate::{DeserializationError, DeserializationResult}; diff --git a/crates/store/re_types_core/src/lib.rs b/crates/store/re_types_core/src/lib.rs index aa012b7bcab3..c927f0197538 100644 --- a/crates/store/re_types_core/src/lib.rs +++ b/crates/store/re_types_core/src/lib.rs @@ -141,3 +141,50 @@ macro_rules! static_assert_struct_has_fields { }; } } + +// --- + +/// Internal serialization helper for code-generated archetypes. +/// +/// # Fallibility +/// +/// There are very few ways in which serialization can fail, all of which are very rare to hit +/// in practice. +/// One such example is trying to serialize data with more than 2^31 elements into a `ListArray`. +/// +/// For that reason, this method favors a nice user experience over error handling: errors will +/// merely be logged, not returned (except in debug builds, where all errors panic). +#[doc(hidden)] // public so we can access it from re_types too +#[allow(clippy::unnecessary_wraps)] // clippy gets confused in debug builds +pub fn try_serialize_field( + descriptor: ComponentDescriptor, + instances: impl IntoIterator>, +) -> Option { + let res = C::to_arrow( + instances + .into_iter() + .map(|v| std::borrow::Cow::Owned(v.into())), + ); + + match res { + Ok(array) => Some(SerializedComponentBatch::new(array, descriptor)), + + #[cfg(debug_assertions)] + Err(err) => { + panic!( + "failed to serialize data for {descriptor}: {}", + re_error::format_ref(&err) + ) + } + + #[cfg(not(debug_assertions))] + Err(err) => { + re_log::error!( + %descriptor, + "failed to serialize data: {}", + re_error::format_ref(&err) + ); + None + } + } +} From 1b9e5102de2693c4c4fc39f198ea8f3090ed9700 Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Mon, 13 Jan 2025 09:37:54 +0100 Subject: [PATCH 09/57] Automatically generate partial update APIs for eager archetypes (#8647) This extends the codegen of the `attr.rust.archetype_eager` attribute so that it automatically generates partial updates APIs for all eager archetypes. * DNM: requires #8646 * Part of #8581 --- .../re_types_builder/src/codegen/rust/api.rs | 53 +++++++++++++++++- .../store/re_types/src/archetypes/points3d.rs | 54 ++++++++++++++++++- crates/store/re_types_core/src/loggable.rs | 6 +++ 3 files changed, 110 insertions(+), 3 deletions(-) diff --git a/crates/build/re_types_builder/src/codegen/rust/api.rs b/crates/build/re_types_builder/src/codegen/rust/api.rs index 2880f8c00077..c80138f4810e 100644 --- a/crates/build/re_types_builder/src/codegen/rust/api.rs +++ b/crates/build/re_types_builder/src/codegen/rust/api.rs @@ -284,6 +284,15 @@ fn quote_struct( let quoted_repr_clause = quote_meta_clause_from_obj(obj, ATTR_RUST_REPR, "repr"); let quoted_custom_clause = quote_meta_clause_from_obj(obj, ATTR_RUST_CUSTOM_CLAUSE, ""); + // Eager archetypes must always derive Default. + let quoted_eager_derive_default_clause = (obj.is_eager_rust_archetype() + && !quoted_derive_clause.to_string().contains("Default")) + .then(|| { + quote! { + #[derive(Default)] + } + }); + let quoted_fields = fields .iter() .map(|obj_field| ObjectFieldTokenizer(reporter, obj, obj_field).quoted(objects)); @@ -353,6 +362,7 @@ fn quote_struct( #quoted_doc #quoted_derive_clone_debug #quoted_derive_clause + #quoted_eager_derive_default_clause #quoted_repr_clause #quoted_custom_clause #quoted_deprecation_notice @@ -1731,7 +1741,7 @@ fn quote_builder_from_obj(reporter: &Reporter, objects: &Objects, obj: &Object) } }); - let eager_with_methods = optional.iter().map(|field| { + let eager_with_methods = required.iter().chain(optional.iter()).map(|field| { // fn with_*() let field_name = format_ident!("{}", field.name); let descr_fn_name = format_ident!("descriptor_{field_name}"); @@ -1760,8 +1770,47 @@ fn quote_builder_from_obj(reporter: &Reporter, objects: &Objects, obj: &Object) } }); + let partial_update_methods = obj.is_eager_rust_archetype().then(|| { + let update_fields_doc = + quote_doc_line(&format!("Update only some specific fields of a `{name}`.")); + let clear_fields_doc = quote_doc_line(&format!("Clear all the fields of a `{name}`.")); + + let fields = required.iter().chain(optional.iter()).map(|field| { + let field_name = format_ident!("{}", field.name); + let descr_fn_name = format_ident!("descriptor_{field_name}"); + let (typ, _) = quote_field_type_from_typ(&field.typ, true); + quote! { + #field_name: Some(SerializedComponentBatch::new( + #typ::arrow_empty(), + Self::#descr_fn_name(), + )) + } + }); + + quote! { + #update_fields_doc + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + #clear_fields_doc + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + #(#fields),* + } + } + } + }); + let with_methods = if obj.is_eager_rust_archetype() { - quote!(#(#eager_with_methods)*) + quote! { + #partial_update_methods + + #(#eager_with_methods)* + } } else { quote!(#(#native_with_methods)*) }; diff --git a/crates/store/re_types/src/archetypes/points3d.rs b/crates/store/re_types/src/archetypes/points3d.rs index cd9ed1edb7b2..c540dcdc24a6 100644 --- a/crates/store/re_types/src/archetypes/points3d.rs +++ b/crates/store/re_types/src/archetypes/points3d.rs @@ -94,7 +94,7 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct Points3D { /// All the 3D positions at which the point cloud shows points. pub positions: Option, @@ -382,6 +382,58 @@ impl Points3D { } } + /// Update only some specific fields of a `Points3D`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `Points3D`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + positions: Some(SerializedComponentBatch::new( + crate::components::Position3D::arrow_empty(), + Self::descriptor_positions(), + )), + radii: Some(SerializedComponentBatch::new( + crate::components::Radius::arrow_empty(), + Self::descriptor_radii(), + )), + colors: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_colors(), + )), + labels: Some(SerializedComponentBatch::new( + crate::components::Text::arrow_empty(), + Self::descriptor_labels(), + )), + show_labels: Some(SerializedComponentBatch::new( + crate::components::ShowLabels::arrow_empty(), + Self::descriptor_show_labels(), + )), + class_ids: Some(SerializedComponentBatch::new( + crate::components::ClassId::arrow_empty(), + Self::descriptor_class_ids(), + )), + keypoint_ids: Some(SerializedComponentBatch::new( + crate::components::KeypointId::arrow_empty(), + Self::descriptor_keypoint_ids(), + )), + } + } + + /// All the 3D positions at which the point cloud shows points. + #[inline] + pub fn with_positions( + mut self, + positions: impl IntoIterator>, + ) -> Self { + self.positions = try_serialize_field(Self::descriptor_positions(), positions); + self + } + /// Optional radii for the points, effectively turning them into circles. #[inline] pub fn with_radii( diff --git a/crates/store/re_types_core/src/loggable.rs b/crates/store/re_types_core/src/loggable.rs index 0be4bdcc9bf2..dab5fa39086d 100644 --- a/crates/store/re_types_core/src/loggable.rs +++ b/crates/store/re_types_core/src/loggable.rs @@ -25,6 +25,12 @@ pub trait Loggable: 'static + Send + Sync + Clone + Sized + SizeBytes { /// The underlying [`arrow::datatypes::DataType`], excluding datatype extensions. fn arrow_datatype() -> arrow::datatypes::DataType; + // Returns an empty Arrow array that matches this `Loggable`'s underlying datatype. + #[inline] + fn arrow_empty() -> arrow::array::ArrayRef { + arrow::array::new_empty_array(&Self::arrow_datatype()) + } + /// Given an iterator of owned or reference values to the current [`Loggable`], serializes /// them into an Arrow array. /// From 822a192bd06fc2cc34fc1623efbe4d7ff6691c43 Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Mon, 13 Jan 2025 09:42:23 +0100 Subject: [PATCH 10/57] Prevent flaky roundtrips in `rerun rrd compare` (#8648) Store-side compaction has election heuristics that can yield different results depending on the order in which the chunks arrive. This can make some cross-language roundtrip tests flaky. This PR makes sure to disabled store-side compaction when running RRD comparison tests. * DNM: requires #8647 --- crates/top/rerun/src/commands/rrd/compare.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/top/rerun/src/commands/rrd/compare.rs b/crates/top/rerun/src/commands/rrd/compare.rs index c9c7c4778e4d..901d71da750d 100644 --- a/crates/top/rerun/src/commands/rrd/compare.rs +++ b/crates/top/rerun/src/commands/rrd/compare.rs @@ -103,7 +103,14 @@ fn compute_uber_table( let msg = msg.context("decode rrd message")?; stores .entry(msg.store_id().clone()) - .or_insert_with(|| re_entity_db::EntityDb::new(msg.store_id().clone())) + .or_insert_with(|| { + re_entity_db::EntityDb::with_store_config( + msg.store_id().clone(), + // We must make sure not to do any store-side compaction during comparisons, or + // this will result in flaky roundtrips in some instances. + re_chunk_store::ChunkStoreConfig::ALL_DISABLED, + ) + }) .add(&msg) .context("decode rrd file contents")?; } From e905439b67c131fe3bc4934b66af82439be0eb25 Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Mon, 13 Jan 2025 09:45:49 +0100 Subject: [PATCH 11/57] Add legacy and next-gen partial updates snippets for all languages (#8649) This adds a partial update example for `Points3D`, in all languages, using both the legacy and new APIs (if they already exist). This acts as a before/after comparison, a piece of documentation and a way to make sure that the legacy and new APIs behave similarly. * DNM: requires #8648 * Part of #8583 * Part of #8581 * Part of #8582 --- docs/snippets/INDEX.md | 16 +++++ .../archetypes/points3d_partial_updates.cpp | 62 +++++++++++++++++++ .../archetypes/points3d_partial_updates.py | 36 +++++++++++ .../archetypes/points3d_partial_updates.rs | 40 ++++++++++++ .../points3d_partial_updates_legacy.cpp | 58 +++++++++++++++++ .../points3d_partial_updates_legacy.py | 32 ++++++++++ .../points3d_partial_updates_legacy.rs | 51 +++++++++++++++ lychee.toml | 10 ++- 8 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 docs/snippets/all/archetypes/points3d_partial_updates.cpp create mode 100644 docs/snippets/all/archetypes/points3d_partial_updates.py create mode 100644 docs/snippets/all/archetypes/points3d_partial_updates.rs create mode 100644 docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp create mode 100644 docs/snippets/all/archetypes/points3d_partial_updates_legacy.py create mode 100644 docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs diff --git a/docs/snippets/INDEX.md b/docs/snippets/INDEX.md index 7ae27d8bee17..aa559659970c 100644 --- a/docs/snippets/INDEX.md +++ b/docs/snippets/INDEX.md @@ -128,6 +128,8 @@ _All snippets, organized by the [`Archetype`](https://rerun.io/docs/reference/ty | **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `archetypes/points3d_simple` | Log some very simple points | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_simple.cpp) | | **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `archetypes/points3d_send_columns` | Use the `send_columns` API to send several point clouds over time in a single call | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_send_columns.py) | | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_send_columns.cpp) | | **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `archetypes/points3d_random` | Log some random points with color and radii | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_random.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_random.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_random.cpp) | +| **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | +| **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `archetypes/points3d_partial_updates` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp) | | **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `archetypes/annotation_context_connections` | Log annotation context with connections between keypoints | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_connections.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_connections.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_connections.cpp) | | **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `archetypes/ellipsoids3d_simple` | Log random points and the corresponding covariance ellipsoid | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/ellipsoids3d_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/ellipsoids3d_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/ellipsoids3d_simple.cpp) | | **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `archetypes/instance_poses3d_combined` | Log a simple 3D box with a regular & instance pose transform | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/instance_poses3d_combined.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/instance_poses3d_combined.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/instance_poses3d_combined.cpp) | @@ -196,6 +198,10 @@ _All snippets, organized by the [`Component`](https://rerun.io/docs/reference/ty | **[`AnnotationContext`](https://rerun.io/docs/reference/types/components/annotation_context)** | `archetypes/annotation_context_connections` | Log annotation context with connections between keypoints | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_connections.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_connections.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_connections.cpp) | | **[`AnnotationContext`](https://rerun.io/docs/reference/types/components/annotation_context)** | `archetypes/segmentation_image_simple` | Create and log a segmentation image | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/segmentation_image_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/segmentation_image_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/segmentation_image_simple.cpp) | | **[`AnnotationContext`](https://rerun.io/docs/reference/types/components/annotation_context)** | `tutorials/annotation-context` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation-context.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation-context.rs) | | +| **[`ClassId`](https://rerun.io/docs/reference/types/components/class_id)** | `archetypes/points3d_partial_updates` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp) | +| **[`ClassId`](https://rerun.io/docs/reference/types/components/class_id)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | +| **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `archetypes/points3d_partial_updates` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp) | +| **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | | **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `archetypes/points3d_send_columns` | Use the `send_columns` API to send several point clouds over time in a single call | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_send_columns.py) | | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_send_columns.cpp) | | **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `concepts/different_data_per_timeline` | Log different data on different timelines | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.cpp) | | **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `concepts/viscomp-component-default` | Add a component default | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/viscomp-component-default.py) | | | @@ -212,10 +218,14 @@ _All snippets, organized by the [`Component`](https://rerun.io/docs/reference/ty | **[`GraphNode`](https://rerun.io/docs/reference/types/components/graph_node)** | `views/graph` | Use a blueprint to customize a graph view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/graph.py) | | | | **[`ImageBuffer`](https://rerun.io/docs/reference/types/components/image_buffer)** | `archetypes/image_send_columns` | Send multiple images at once using `send_columns` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.cpp) | | **[`ImageFormat`](https://rerun.io/docs/reference/types/components/image_format)** | `archetypes/image_send_columns` | Send multiple images at once using `send_columns` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.cpp) | +| **[`KeypointId`](https://rerun.io/docs/reference/types/components/keypoint_id)** | `archetypes/points3d_partial_updates` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp) | +| **[`KeypointId`](https://rerun.io/docs/reference/types/components/keypoint_id)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | | **[`MediaType`](https://rerun.io/docs/reference/types/components/media_type)** | `archetypes/text_document` | Log a `TextDocument` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_document.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_document.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_document.cpp) | | **[`MediaType`](https://rerun.io/docs/reference/types/components/media_type)** | `views/text_document` | Use a blueprint to show a text document | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/text_document.py) | | | | **[`Plane3D`](https://rerun.io/docs/reference/types/components/plane3d)** | `views/spatial3d` | Use a blueprint to customize a Spatial3DView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/spatial3d.py) | | | | **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `archetypes/mesh3d_partial_updates` | Log a simple colored triangle, then update its vertices' positions each frame | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/mesh3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/mesh3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/mesh3d_partial_updates.cpp) | +| **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `archetypes/points3d_partial_updates` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp) | +| **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | | **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `archetypes/points3d_send_columns` | Use the `send_columns` API to send several point clouds over time in a single call | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_send_columns.py) | | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_send_columns.cpp) | | **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `descriptors/descr_builtin_component` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_component.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_component.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_component.cpp) | | **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `descriptors/descr_custom_archetype` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.cpp) | @@ -226,6 +236,8 @@ _All snippets, organized by the [`Component`](https://rerun.io/docs/reference/ty | **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `archetypes/line_strips2d_ui_radius` | Log lines with ui points & scene unit radii | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/line_strips2d_ui_radius.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/line_strips2d_ui_radius.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/line_strips2d_ui_radius.cpp) | | **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `archetypes/geo_line_strings_simple` | Log a simple geospatial line string | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_line_strings_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_line_strings_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_line_strings_simple.cpp) | | **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `archetypes/geo_points_simple` | Log some very simple geospatial point | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_points_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_points_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_points_simple.cpp) | +| **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `archetypes/points3d_partial_updates` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp) | +| **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | | **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `concepts/different_data_per_timeline` | Log different data on different timelines | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.cpp) | | **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `views/map` | Use a blueprint to customize a map view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/map.py) | | | | **[`RotationAxisAngle`](https://rerun.io/docs/reference/types/components/rotation_axis_angle)** | `archetypes/capsules3d_batch` | Log a batch of capsules | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/capsules3d_batch.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/capsules3d_batch.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/capsules3d_batch.cpp) | @@ -245,6 +257,8 @@ _All snippets, organized by the [`Component`](https://rerun.io/docs/reference/ty | **[`Scalar`](https://rerun.io/docs/reference/types/components/scalar)** | `views/dataframe` | Use a blueprint to customize a DataframeView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/dataframe.py) | | | | **[`Scalar`](https://rerun.io/docs/reference/types/components/scalar)** | `views/tensor` | Use a blueprint to show a tensor view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/tensor.py) | | | | **[`Scalar`](https://rerun.io/docs/reference/types/components/scalar)** | `views/timeseries` | Use a blueprint to customize a TimeSeriesView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/timeseries.py) | | | +| **[`ShowLabels`](https://rerun.io/docs/reference/types/components/show_labels)** | `archetypes/points3d_partial_updates` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp) | +| **[`ShowLabels`](https://rerun.io/docs/reference/types/components/show_labels)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | | **[`TensorDimensionIndexSelection`](https://rerun.io/docs/reference/types/components/tensor_dimension_index_selection)** | `views/tensor` | Use a blueprint to show a tensor view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/tensor.py) | | | | **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `views/text_log` | Use a blueprint to show a text log | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/text_log.py) | | | | **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `views/text_document` | Use a blueprint to show a text document | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/text_document.py) | | | @@ -252,6 +266,8 @@ _All snippets, organized by the [`Component`](https://rerun.io/docs/reference/ty | **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `archetypes/text_log` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_log.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_log.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_log.cpp) | | **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `archetypes/text_document` | Log a `TextDocument` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_document.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_document.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_document.cpp) | | **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `archetypes/entity_path` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/entity_path.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/entity_path.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/entity_path.cpp) | +| **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `archetypes/points3d_partial_updates` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp) | +| **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | | **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `concepts/app-model/native-async` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-async.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-async.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-async.cpp) | | **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `concepts/app-model/native-sync` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-sync.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-sync.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-sync.cpp) | | **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `tutorials/data_out` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/data_out.py) | | | diff --git a/docs/snippets/all/archetypes/points3d_partial_updates.cpp b/docs/snippets/all/archetypes/points3d_partial_updates.cpp new file mode 100644 index 000000000000..7171ddb33e63 --- /dev/null +++ b/docs/snippets/all/archetypes/points3d_partial_updates.cpp @@ -0,0 +1,62 @@ +//! Demonstrates usage of the new partial updates APIs. + +#include + +#include +#include + +int main() { + const auto rec = rerun::RecordingStream("rerun_example_points3d_partial_updates"); + rec.spawn().exit_on_failure(); + + std::vector positions; + for (int i = 0; i < 10; ++i) { + positions.emplace_back(static_cast(i), 0.0f, 0.0f); + } + + rec.set_time_sequence("frame", 0); + rec.log("points", rerun::Points3D(positions)); + + for (int i = 0; i < 10; ++i) { + std::vector colors; + for (int n = 0; n < 10; ++n) { + if (n < i) { + colors.emplace_back(rerun::Color(20, 200, 20)); + } else { + colors.emplace_back(rerun::Color(200, 20, 20)); + } + } + + std::vector radii; + for (int n = 0; n < 10; ++n) { + if (n < i) { + radii.emplace_back(rerun::Radius(0.6f)); + } else { + radii.emplace_back(rerun::Radius(0.2f)); + } + } + + rec.set_time_sequence("frame", i); + rec.log("points", rerun::Points3D::IndicatorComponent(), colors, radii); + // TODO(cmc): implement new APIs and use them! + // rec.log("points", rerun::Points3D::update_fields().with_radii(radii).with_colors(colors)); + } + + std::vector radii; + radii.emplace_back(0.3f); + + rec.set_time_sequence("frame", 20); + rec.log( + "points", + rerun::Points3D::IndicatorComponent(), + positions, + radii, + std::vector(), + std::vector(), + std::vector(), + std::vector(), + std::vector() + ); + // TODO(cmc): implement new APIs and use them! + // rec.log("points", rerun::Points3D::clear_fields().with_radii(radii).with_colors(colors)); +} diff --git a/docs/snippets/all/archetypes/points3d_partial_updates.py b/docs/snippets/all/archetypes/points3d_partial_updates.py new file mode 100644 index 000000000000..69f56d5c62ae --- /dev/null +++ b/docs/snippets/all/archetypes/points3d_partial_updates.py @@ -0,0 +1,36 @@ +"""Demonstrates usage of the new partial updates APIs.""" + +import rerun as rr + +rr.init("rerun_example_points3d_partial_updates", spawn=True) + +positions = [[i, 0, 0] for i in range(0, 10)] + +rr.set_time_sequence("frame", 0) +rr.log("points", rr.Points3D(positions)) + +for i in range(0, 10): + colors = [[20, 200, 20] if n < i else [200, 20, 20] for n in range(0, 10)] + radii = [0.6 if n < i else 0.2 for n in range(0, 10)] + + rr.set_time_sequence("frame", i) + rr.log("points", [rr.Points3D.indicator(), rr.components.ColorBatch(colors), rr.components.RadiusBatch(radii)]) + # TODO(cmc): implement new APIs and use them! + # rr.log("points", rr.Points3D.update_fields(radii=radii, colors=colors)) + +rr.set_time_sequence("frame", 20) +rr.log( + "points", + [ + rr.Points3D.indicator(), + rr.components.Position3DBatch(positions), + rr.components.RadiusBatch(0.3), + rr.components.ColorBatch([]), + rr.components.TextBatch([]), + rr.components.ShowLabelsBatch([]), + rr.components.ClassIdBatch([]), + rr.components.KeypointIdBatch([]), + ], +) +# TODO(cmc): implement new APIs and use them! +# rr.log("points", rr.Points3D.clear_fields().update_fields(positions=positions, radii=0.3)) diff --git a/docs/snippets/all/archetypes/points3d_partial_updates.rs b/docs/snippets/all/archetypes/points3d_partial_updates.rs new file mode 100644 index 000000000000..cc09f155e2ad --- /dev/null +++ b/docs/snippets/all/archetypes/points3d_partial_updates.rs @@ -0,0 +1,40 @@ +//! Demonstrates usage of the new partial updates APIs. + +fn main() -> Result<(), Box> { + let rec = + rerun::RecordingStreamBuilder::new("rerun_example_points3d_partial_updates").spawn()?; + + let positions = || (0..10).map(|i| (i as f32, 0.0, 0.0)); + + rec.set_time_sequence("frame", 0); + rec.log("points", &rerun::Points3D::new(positions()))?; + + for i in 0..10 { + let colors = (0..10).map(|n| { + if n < i { + rerun::Color::from_rgb(20, 200, 20) + } else { + rerun::Color::from_rgb(200, 20, 20) + } + }); + let radii = (0..10).map(|n| if n < i { 0.6 } else { 0.2 }); + + rec.set_time_sequence("frame", i); + rec.log( + "points", + &rerun::Points3D::update_fields() + .with_radii(radii) + .with_colors(colors), + )?; + } + + rec.set_time_sequence("frame", 20); + rec.log( + "points", + &rerun::Points3D::clear_fields() + .with_positions(positions()) + .with_radii([0.3]), + )?; + + Ok(()) +} diff --git a/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp b/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp new file mode 100644 index 000000000000..ad39a9c5cd9c --- /dev/null +++ b/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp @@ -0,0 +1,58 @@ +// Demonstrates usage of the legacy partial updates APIs. + +#include + +#include +#include + +int main() { + const auto rec = rerun::RecordingStream("rerun_example_points3d_partial_updates_legacy"); + rec.spawn().exit_on_failure(); + + std::vector positions; + for (int i = 0; i < 10; ++i) { + positions.emplace_back(static_cast(i), 0.0f, 0.0f); + } + + rec.set_time_sequence("frame", 0); + rec.log("points", rerun::Points3D(positions)); + + for (int i = 0; i < 10; ++i) { + std::vector colors; + for (int n = 0; n < 10; ++n) { + if (n < i) { + colors.emplace_back(rerun::Color(20, 200, 20)); + } else { + colors.emplace_back(rerun::Color(200, 20, 20)); + } + } + + std::vector radii; + for (int n = 0; n < 10; ++n) { + if (n < i) { + radii.emplace_back(rerun::Radius(0.6f)); + } else { + radii.emplace_back(rerun::Radius(0.2f)); + } + } + + rec.set_time_sequence("frame", i); + rec.log("points", colors, radii); + } + + std::vector radii; + radii.emplace_back(0.3f); + + rec.set_time_sequence("frame", 20); + rec.log( + "points", + rerun::Points3D::IndicatorComponent(), + positions, + radii, + std::vector(), + std::vector(), + std::vector(), + std::vector(), + std::vector() + ); +} diff --git a/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py b/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py new file mode 100644 index 000000000000..fab36e44e771 --- /dev/null +++ b/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py @@ -0,0 +1,32 @@ +"""Demonstrates usage of the new partial updates APIs.""" + +import rerun as rr + +rr.init("rerun_example_points3d_partial_updates_legacy", spawn=True) + +positions = [[i, 0, 0] for i in range(0, 10)] + +rr.set_time_sequence("frame", 0) +rr.log("points", rr.Points3D(positions)) + +for i in range(0, 10): + colors = [[20, 200, 20] if n < i else [200, 20, 20] for n in range(0, 10)] + radii = [0.6 if n < i else 0.2 for n in range(0, 10)] + + rr.set_time_sequence("frame", i) + rr.log("points", [rr.components.ColorBatch(colors), rr.components.RadiusBatch(radii)]) + +rr.set_time_sequence("frame", 20) +rr.log( + "points", + [ + rr.Points3D.indicator(), + rr.components.Position3DBatch(positions), + rr.components.RadiusBatch(0.3), + rr.components.ColorBatch([]), + rr.components.TextBatch([]), + rr.components.ShowLabelsBatch([]), + rr.components.ClassIdBatch([]), + rr.components.KeypointIdBatch([]), + ], +) diff --git a/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs b/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs new file mode 100644 index 000000000000..de4ca9f83cef --- /dev/null +++ b/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs @@ -0,0 +1,51 @@ +//! Demonstrates usage of the legacy partial updates APIs. + +fn main() -> Result<(), Box> { + let rec = rerun::RecordingStreamBuilder::new("rerun_example_points3d_partial_updates_legacy") + .spawn()?; + + let positions = (0..10).map(|i| (i as f32, 0.0, 0.0)); + + rec.set_time_sequence("frame", 0); + rec.log("points", &rerun::Points3D::new(positions))?; + + for i in 0..10 { + let colors: Vec = (0..10) + .map(|n| { + if n < i { + rerun::Color::from_rgb(20, 200, 20) + } else { + rerun::Color::from_rgb(200, 20, 20) + } + }) + .collect(); + let radii: Vec = (0..10) + .map(|n| if n < i { 0.6 } else { 0.2 }) + .map(Into::into) + .collect(); + + rec.set_time_sequence("frame", i); + rec.log("points", &[&colors as &dyn rerun::ComponentBatch, &radii])?; + } + + use rerun::Archetype as _; + let positions: Vec = + (0..10).map(|i| (i as f32, 0.0, 0.0).into()).collect(); + + rec.set_time_sequence("frame", 20); + rec.log( + "points", + &[ + &rerun::Points3D::indicator() as &dyn rerun::ComponentBatch, + &positions, + &vec![rerun::components::Radius(0.3.into())], + &Vec::::new(), + &Vec::::new(), + &Vec::::new(), + &Vec::::new(), + &Vec::::new(), + ], + )?; + + Ok(()) +} diff --git a/lychee.toml b/lychee.toml index bb97b38fa5ab..7342caee577e 100644 --- a/lychee.toml +++ b/lychee.toml @@ -151,5 +151,13 @@ exclude = [ 'https://openaccess.thecvf.com/content/CVPR2023/html/Du_Learning_To_Render_Novel_Views_From_Wide-Baseline_Stereo_Pairs_CVPR_2023_paper.html', 'https://anaconda.org/conda-forge/arrow-cpp', - #'^file:///', # Ignore local file links. They need to be tested, but it's useful for external links we have to ping. + # '^file:///', # Ignore local file links. They need to be tested, but it's useful for external links we have to ping. + + # Snippets that haven't been released yet. + 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py', + 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py', + 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp', + 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp', + 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs', + 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs', ] From e26d858ffdd90cfe81fe02423b86e96745d49227 Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Mon, 13 Jan 2025 09:49:13 +0100 Subject: [PATCH 12/57] Eagerly serialized, partially updatable 2D & 3D line strips (#8650) This PR makes `LineStrips2D` and `LineStrips3D` eagerly serialized and partially update-able. This demonstrates how to migrate an archetype in the simple case. * DNM: requires #8649 * Part of #8581 --- .../rerun/archetypes/line_strips2d.fbs | 1 + .../rerun/archetypes/line_strips3d.fbs | 1 + .../re_types/src/archetypes/line_strips2d.rs | 266 +++++++----------- .../re_types/src/archetypes/line_strips3d.rs | 234 ++++++--------- .../re_types/tests/types/line_strips2d.rs | 57 ++-- .../re_types/tests/types/line_strips3d.rs | 53 ++-- 6 files changed, 261 insertions(+), 351 deletions(-) diff --git a/crates/store/re_types/definitions/rerun/archetypes/line_strips2d.fbs b/crates/store/re_types/definitions/rerun/archetypes/line_strips2d.fbs index 1884710c1815..900826114edb 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/line_strips2d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/line_strips2d.fbs @@ -9,6 +9,7 @@ namespace rerun.archetypes; /// \example archetypes/line_strips2d_batch image="https://static.rerun.io/line_strip2d_batch/c6f4062bcf510462d298a5dfe9fdbe87c754acee/1200w.png" /// \example archetypes/line_strips2d_ui_radius title="Lines with scene & UI radius each" image="https://static.rerun.io/line_strip2d_ui_radius/d3d7d5bd36278564ee37e2ed6932963ec16f5131/1200w.png table LineStrips2D ( + "attr.rust.archetype_eager": "", "attr.rust.derive": "PartialEq", "attr.docs.category": "Spatial 2D", "attr.docs.view_types": "Spatial2DView, Spatial3DView: if logged under a projection" diff --git a/crates/store/re_types/definitions/rerun/archetypes/line_strips3d.fbs b/crates/store/re_types/definitions/rerun/archetypes/line_strips3d.fbs index 6984cdcd2334..3df0519c0b5d 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/line_strips3d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/line_strips3d.fbs @@ -9,6 +9,7 @@ namespace rerun.archetypes; /// \example archetypes/line_strips3d_batch title="Many strips" image="https://static.rerun.io/line_strip3d_batch/15e8ff18a6c95a3191acb0eae6eb04adea3b4874/1200w.png" /// \example archetypes/line_strips3d_ui_radius title="Lines with scene & UI radius each" image="https://static.rerun.io/line_strip3d_ui_radius/36b98f47e45747b5a3601511ff39b8d74c61d120/1200w.png" table LineStrips3D ( + "attr.rust.archetype_eager": "", "attr.rust.derive": "PartialEq", "attr.docs.category": "Spatial 3D", "attr.docs.view_types": "Spatial3DView, Spatial2DView: if logged above active projection" diff --git a/crates/store/re_types/src/archetypes/line_strips2d.rs b/crates/store/re_types/src/archetypes/line_strips2d.rs index 868167d34697..daef1b89ef07 100644 --- a/crates/store/re_types/src/archetypes/line_strips2d.rs +++ b/crates/store/re_types/src/archetypes/line_strips2d.rs @@ -85,35 +85,35 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// Ok(()) /// } /// ``` -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct LineStrips2D { /// All the actual 2D line strips that make up the batch. - pub strips: Vec, + pub strips: Option, /// Optional radii for the line strips. - pub radii: Option>, + pub radii: Option, /// Optional colors for the line strips. - pub colors: Option>, + pub colors: Option, /// Optional text labels for the line strips. /// /// If there's a single label present, it will be placed at the center of the entity. /// Otherwise, each instance will have its own label. - pub labels: Option>, + pub labels: Option, /// Optional choice of whether the text labels should be shown by default. - pub show_labels: Option, + pub show_labels: Option, /// An optional floating point value that specifies the 2D drawing order of each line strip. /// /// Objects with higher values are drawn on top of those with lower values. - pub draw_order: Option, + pub draw_order: Option, /// Optional [`components::ClassId`][crate::components::ClassId]s for the lines. /// /// The [`components::ClassId`][crate::components::ClassId] provides colors and labels if not specified explicitly. - pub class_ids: Option>, + pub class_ids: Option, } impl LineStrips2D { @@ -288,85 +288,33 @@ impl ::re_types_core::Archetype for LineStrips2D { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let strips = { - let array = arrays_by_descr - .get(&Self::descriptor_strips()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.LineStrips2D#strips")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.LineStrips2D#strips")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.LineStrips2D#strips")? - }; - let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.LineStrips2D#radii")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.LineStrips2D#radii")? - }) - } else { - None - }; - let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.LineStrips2D#colors")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.LineStrips2D#colors")? - }) - } else { - None - }; - let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.LineStrips2D#labels")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.LineStrips2D#labels")? - }) - } else { - None - }; - let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.LineStrips2D#show_labels")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let draw_order = if let Some(array) = arrays_by_descr.get(&Self::descriptor_draw_order()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.LineStrips2D#draw_order")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.LineStrips2D#class_ids")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.LineStrips2D#class_ids")? - }) - } else { - None - }; + let strips = arrays_by_descr + .get(&Self::descriptor_strips()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_strips())); + let radii = arrays_by_descr + .get(&Self::descriptor_radii()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_radii())); + let colors = arrays_by_descr + .get(&Self::descriptor_colors()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_colors())); + let labels = arrays_by_descr + .get(&Self::descriptor_labels()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_labels())); + let show_labels = arrays_by_descr + .get(&Self::descriptor_show_labels()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_show_labels()) + }); + let draw_order = arrays_by_descr + .get(&Self::descriptor_draw_order()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_draw_order()) + }); + let class_ids = arrays_by_descr + .get(&Self::descriptor_class_ids()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_class_ids()) + }); Ok(Self { strips, radii, @@ -380,65 +328,18 @@ impl ::re_types_core::Archetype for LineStrips2D { } impl ::re_types_core::AsComponents for LineStrips2D { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.strips as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_strips()), - } - }), - (self - .radii - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_radii()), - }), - (self - .colors - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_colors()), - }), - (self - .labels - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_labels()), - }), - (self - .show_labels - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_show_labels()), - }), - (self - .draw_order - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_draw_order()), - }), - (self - .class_ids - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_class_ids()), - }), + Self::indicator().serialized(), + self.strips.clone(), + self.radii.clone(), + self.colors.clone(), + self.labels.clone(), + self.show_labels.clone(), + self.draw_order.clone(), + self.class_ids.clone(), ] .into_iter() .flatten() @@ -455,7 +356,7 @@ impl LineStrips2D { strips: impl IntoIterator>, ) -> Self { Self { - strips: strips.into_iter().map(Into::into).collect(), + strips: try_serialize_field(Self::descriptor_strips(), strips), radii: None, colors: None, labels: None, @@ -465,13 +366,65 @@ impl LineStrips2D { } } + /// Update only some specific fields of a `LineStrips2D`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `LineStrips2D`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + strips: Some(SerializedComponentBatch::new( + crate::components::LineStrip2D::arrow_empty(), + Self::descriptor_strips(), + )), + radii: Some(SerializedComponentBatch::new( + crate::components::Radius::arrow_empty(), + Self::descriptor_radii(), + )), + colors: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_colors(), + )), + labels: Some(SerializedComponentBatch::new( + crate::components::Text::arrow_empty(), + Self::descriptor_labels(), + )), + show_labels: Some(SerializedComponentBatch::new( + crate::components::ShowLabels::arrow_empty(), + Self::descriptor_show_labels(), + )), + draw_order: Some(SerializedComponentBatch::new( + crate::components::DrawOrder::arrow_empty(), + Self::descriptor_draw_order(), + )), + class_ids: Some(SerializedComponentBatch::new( + crate::components::ClassId::arrow_empty(), + Self::descriptor_class_ids(), + )), + } + } + + /// All the actual 2D line strips that make up the batch. + #[inline] + pub fn with_strips( + mut self, + strips: impl IntoIterator>, + ) -> Self { + self.strips = try_serialize_field(Self::descriptor_strips(), strips); + self + } + /// Optional radii for the line strips. #[inline] pub fn with_radii( mut self, radii: impl IntoIterator>, ) -> Self { - self.radii = Some(radii.into_iter().map(Into::into).collect()); + self.radii = try_serialize_field(Self::descriptor_radii(), radii); self } @@ -481,7 +434,7 @@ impl LineStrips2D { mut self, colors: impl IntoIterator>, ) -> Self { - self.colors = Some(colors.into_iter().map(Into::into).collect()); + self.colors = try_serialize_field(Self::descriptor_colors(), colors); self } @@ -494,7 +447,7 @@ impl LineStrips2D { mut self, labels: impl IntoIterator>, ) -> Self { - self.labels = Some(labels.into_iter().map(Into::into).collect()); + self.labels = try_serialize_field(Self::descriptor_labels(), labels); self } @@ -504,7 +457,7 @@ impl LineStrips2D { mut self, show_labels: impl Into, ) -> Self { - self.show_labels = Some(show_labels.into()); + self.show_labels = try_serialize_field(Self::descriptor_show_labels(), [show_labels]); self } @@ -513,7 +466,7 @@ impl LineStrips2D { /// Objects with higher values are drawn on top of those with lower values. #[inline] pub fn with_draw_order(mut self, draw_order: impl Into) -> Self { - self.draw_order = Some(draw_order.into()); + self.draw_order = try_serialize_field(Self::descriptor_draw_order(), [draw_order]); self } @@ -525,7 +478,7 @@ impl LineStrips2D { mut self, class_ids: impl IntoIterator>, ) -> Self { - self.class_ids = Some(class_ids.into_iter().map(Into::into).collect()); + self.class_ids = try_serialize_field(Self::descriptor_class_ids(), class_ids); self } } @@ -541,15 +494,4 @@ impl ::re_byte_size::SizeBytes for LineStrips2D { + self.draw_order.heap_size_bytes() + self.class_ids.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >::is_pod() - && >::is_pod() - && >>::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/line_strips3d.rs b/crates/store/re_types/src/archetypes/line_strips3d.rs index 761c01bb048d..308ae9c0fe83 100644 --- a/crates/store/re_types/src/archetypes/line_strips3d.rs +++ b/crates/store/re_types/src/archetypes/line_strips3d.rs @@ -98,30 +98,30 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct LineStrips3D { /// All the actual 3D line strips that make up the batch. - pub strips: Vec, + pub strips: Option, /// Optional radii for the line strips. - pub radii: Option>, + pub radii: Option, /// Optional colors for the line strips. - pub colors: Option>, + pub colors: Option, /// Optional text labels for the line strips. /// /// If there's a single label present, it will be placed at the center of the entity. /// Otherwise, each instance will have its own label. - pub labels: Option>, + pub labels: Option, /// Optional choice of whether the text labels should be shown by default. - pub show_labels: Option, + pub show_labels: Option, /// Optional [`components::ClassId`][crate::components::ClassId]s for the lines. /// /// The [`components::ClassId`][crate::components::ClassId] provides colors and labels if not specified explicitly. - pub class_ids: Option>, + pub class_ids: Option, } impl LineStrips3D { @@ -284,76 +284,28 @@ impl ::re_types_core::Archetype for LineStrips3D { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let strips = { - let array = arrays_by_descr - .get(&Self::descriptor_strips()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.LineStrips3D#strips")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.LineStrips3D#strips")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.LineStrips3D#strips")? - }; - let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.LineStrips3D#radii")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.LineStrips3D#radii")? - }) - } else { - None - }; - let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.LineStrips3D#colors")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.LineStrips3D#colors")? - }) - } else { - None - }; - let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.LineStrips3D#labels")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.LineStrips3D#labels")? - }) - } else { - None - }; - let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.LineStrips3D#show_labels")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.LineStrips3D#class_ids")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.LineStrips3D#class_ids")? - }) - } else { - None - }; + let strips = arrays_by_descr + .get(&Self::descriptor_strips()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_strips())); + let radii = arrays_by_descr + .get(&Self::descriptor_radii()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_radii())); + let colors = arrays_by_descr + .get(&Self::descriptor_colors()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_colors())); + let labels = arrays_by_descr + .get(&Self::descriptor_labels()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_labels())); + let show_labels = arrays_by_descr + .get(&Self::descriptor_show_labels()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_show_labels()) + }); + let class_ids = arrays_by_descr + .get(&Self::descriptor_class_ids()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_class_ids()) + }); Ok(Self { strips, radii, @@ -366,57 +318,17 @@ impl ::re_types_core::Archetype for LineStrips3D { } impl ::re_types_core::AsComponents for LineStrips3D { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.strips as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_strips()), - } - }), - (self - .radii - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_radii()), - }), - (self - .colors - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_colors()), - }), - (self - .labels - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_labels()), - }), - (self - .show_labels - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_show_labels()), - }), - (self - .class_ids - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_class_ids()), - }), + Self::indicator().serialized(), + self.strips.clone(), + self.radii.clone(), + self.colors.clone(), + self.labels.clone(), + self.show_labels.clone(), + self.class_ids.clone(), ] .into_iter() .flatten() @@ -433,7 +345,7 @@ impl LineStrips3D { strips: impl IntoIterator>, ) -> Self { Self { - strips: strips.into_iter().map(Into::into).collect(), + strips: try_serialize_field(Self::descriptor_strips(), strips), radii: None, colors: None, labels: None, @@ -442,13 +354,61 @@ impl LineStrips3D { } } + /// Update only some specific fields of a `LineStrips3D`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `LineStrips3D`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + strips: Some(SerializedComponentBatch::new( + crate::components::LineStrip3D::arrow_empty(), + Self::descriptor_strips(), + )), + radii: Some(SerializedComponentBatch::new( + crate::components::Radius::arrow_empty(), + Self::descriptor_radii(), + )), + colors: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_colors(), + )), + labels: Some(SerializedComponentBatch::new( + crate::components::Text::arrow_empty(), + Self::descriptor_labels(), + )), + show_labels: Some(SerializedComponentBatch::new( + crate::components::ShowLabels::arrow_empty(), + Self::descriptor_show_labels(), + )), + class_ids: Some(SerializedComponentBatch::new( + crate::components::ClassId::arrow_empty(), + Self::descriptor_class_ids(), + )), + } + } + + /// All the actual 3D line strips that make up the batch. + #[inline] + pub fn with_strips( + mut self, + strips: impl IntoIterator>, + ) -> Self { + self.strips = try_serialize_field(Self::descriptor_strips(), strips); + self + } + /// Optional radii for the line strips. #[inline] pub fn with_radii( mut self, radii: impl IntoIterator>, ) -> Self { - self.radii = Some(radii.into_iter().map(Into::into).collect()); + self.radii = try_serialize_field(Self::descriptor_radii(), radii); self } @@ -458,7 +418,7 @@ impl LineStrips3D { mut self, colors: impl IntoIterator>, ) -> Self { - self.colors = Some(colors.into_iter().map(Into::into).collect()); + self.colors = try_serialize_field(Self::descriptor_colors(), colors); self } @@ -471,7 +431,7 @@ impl LineStrips3D { mut self, labels: impl IntoIterator>, ) -> Self { - self.labels = Some(labels.into_iter().map(Into::into).collect()); + self.labels = try_serialize_field(Self::descriptor_labels(), labels); self } @@ -481,7 +441,7 @@ impl LineStrips3D { mut self, show_labels: impl Into, ) -> Self { - self.show_labels = Some(show_labels.into()); + self.show_labels = try_serialize_field(Self::descriptor_show_labels(), [show_labels]); self } @@ -493,7 +453,7 @@ impl LineStrips3D { mut self, class_ids: impl IntoIterator>, ) -> Self { - self.class_ids = Some(class_ids.into_iter().map(Into::into).collect()); + self.class_ids = try_serialize_field(Self::descriptor_class_ids(), class_ids); self } } @@ -508,14 +468,4 @@ impl ::re_byte_size::SizeBytes for LineStrips3D { + self.show_labels.heap_size_bytes() + self.class_ids.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >::is_pod() - && >>::is_pod() - } } diff --git a/crates/store/re_types/tests/types/line_strips2d.rs b/crates/store/re_types/tests/types/line_strips2d.rs index e75bf9353c3e..e784d312970d 100644 --- a/crates/store/re_types/tests/types/line_strips2d.rs +++ b/crates/store/re_types/tests/types/line_strips2d.rs @@ -1,7 +1,5 @@ use re_types::{ - archetypes::LineStrips2D, - components::{ClassId, Color, DrawOrder, LineStrip2D, Radius}, - Archetype as _, AsComponents as _, + archetypes::LineStrips2D, components, Archetype as _, AsComponents as _, ComponentBatch, }; #[test] @@ -9,27 +7,38 @@ fn roundtrip() { let expected = LineStrips2D { #[rustfmt::skip] strips: vec![ - LineStrip2D::from_iter([[0., 0.], [2., 1.], [4., -1.], [6., 0.]]), // - LineStrip2D::from_iter([[0., 3.], [1., 4.], [2., 2.], [3., 4.], [4., 2.], [5., 4.], [6., 3.]]), // - ], - radii: Some(vec![ - Radius::from(42.0), // - Radius::from(43.0), - ]), - colors: Some(vec![ - Color::from_unmultiplied_rgba(0xAA, 0x00, 0x00, 0xCC), // - Color::from_unmultiplied_rgba(0x00, 0xBB, 0x00, 0xDD), - ]), - labels: Some(vec![ - "hello".into(), // - "friend".into(), // - ]), - draw_order: Some(DrawOrder(300.0.into())), - class_ids: Some(vec![ - ClassId::from(126), // - ClassId::from(127), // - ]), - show_labels: Some(false.into()), + components::LineStrip2D::from_iter([[0., 0.], [2., 1.], [4., -1.], [6., 0.]]), // + components::LineStrip2D::from_iter([[0., 3.], [1., 4.], [2., 2.], [3., 4.], [4., 2.], [5., 4.], [6., 3.]]), // + ] + .serialized() + .map(|batch| batch.with_descriptor_override(LineStrips2D::descriptor_strips())), + radii: vec![ + components::Radius::from(42.0), // + components::Radius::from(43.0), + ] + .serialized() + .map(|batch| batch.with_descriptor_override(LineStrips2D::descriptor_radii())), + colors: vec![ + components::Color::from_unmultiplied_rgba(0xAA, 0x00, 0x00, 0xCC), // + components::Color::from_unmultiplied_rgba(0x00, 0xBB, 0x00, 0xDD), + ] + .serialized() + .map(|batch| batch.with_descriptor_override(LineStrips2D::descriptor_colors())), + labels: (vec!["hello".into(), "friend".into()] as Vec) + .serialized() + .map(|batch| batch.with_descriptor_override(LineStrips2D::descriptor_labels())), + draw_order: vec![components::DrawOrder(300.0.into())] + .serialized() + .map(|batch| batch.with_descriptor_override(LineStrips2D::descriptor_draw_order())), + class_ids: vec![ + components::ClassId::from(126), // + components::ClassId::from(127), // + ] + .serialized() + .map(|batch| batch.with_descriptor_override(LineStrips2D::descriptor_class_ids())), + show_labels: components::ShowLabels(false.into()) + .serialized() + .map(|batch| batch.with_descriptor_override(LineStrips2D::descriptor_show_labels())), }; #[rustfmt::skip] diff --git a/crates/store/re_types/tests/types/line_strips3d.rs b/crates/store/re_types/tests/types/line_strips3d.rs index 444866508186..ae78d07dd2e7 100644 --- a/crates/store/re_types/tests/types/line_strips3d.rs +++ b/crates/store/re_types/tests/types/line_strips3d.rs @@ -1,7 +1,5 @@ use re_types::{ - archetypes::LineStrips3D, - components::{ClassId, Color, LineStrip3D, Radius}, - Archetype as _, AsComponents as _, + archetypes::LineStrips3D, components, Archetype as _, AsComponents as _, ComponentBatch, }; #[test] @@ -9,26 +7,35 @@ fn roundtrip() { let expected = LineStrips3D { #[rustfmt::skip] strips: vec![ - LineStrip3D::from_iter([[0., 0., 1.], [2., 1., 2.], [4., -1., 3.], [6., 0., 4.]]), - LineStrip3D::from_iter([[0., 3., 1.], [1., 4., 2.], [2., 2., 3.], [3., 4., 4.], [4., 2., 5.], [5., 4., 6.], [6., 3., 7.]]), - ], - radii: Some(vec![ - Radius::from(42.0), // - Radius::from(43.0), - ]), - colors: Some(vec![ - Color::from_unmultiplied_rgba(0xAA, 0x00, 0x00, 0xCC), // - Color::from_unmultiplied_rgba(0x00, 0xBB, 0x00, 0xDD), - ]), - labels: Some(vec![ - "hello".into(), // - "friend".into(), // - ]), - class_ids: Some(vec![ - ClassId::from(126), // - ClassId::from(127), // - ]), - show_labels: Some(true.into()), + components::LineStrip3D::from_iter([[0., 0., 1.], [2., 1., 2.], [4., -1., 3.], [6., 0., 4.]]), + components::LineStrip3D::from_iter([[0., 3., 1.], [1., 4., 2.], [2., 2., 3.], [3., 4., 4.], [4., 2., 5.], [5., 4., 6.], [6., 3., 7.]]), + ] + .serialized() + .map(|batch| batch.with_descriptor_override(LineStrips3D::descriptor_strips())), + radii: vec![ + components::Radius::from(42.0), // + components::Radius::from(43.0), + ] + .serialized() + .map(|batch| batch.with_descriptor_override(LineStrips3D::descriptor_radii())), + colors: vec![ + components::Color::from_unmultiplied_rgba(0xAA, 0x00, 0x00, 0xCC), // + components::Color::from_unmultiplied_rgba(0x00, 0xBB, 0x00, 0xDD), + ] + .serialized() + .map(|batch| batch.with_descriptor_override(LineStrips3D::descriptor_colors())), + labels: (vec!["hello".into(), "friend".into()] as Vec) + .serialized() + .map(|batch| batch.with_descriptor_override(LineStrips3D::descriptor_labels())), + class_ids: vec![ + components::ClassId::from(126), // + components::ClassId::from(127), // + ] + .serialized() + .map(|batch| batch.with_descriptor_override(LineStrips3D::descriptor_class_ids())), + show_labels: components::ShowLabels(true.into()) + .serialized() + .map(|batch| batch.with_descriptor_override(LineStrips3D::descriptor_show_labels())), }; #[rustfmt::skip] From c63e6cf497543920b72ff8a5ebcb1d4a44ceba58 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Mon, 13 Jan 2025 10:44:38 +0100 Subject: [PATCH 13/57] Enable lfs checkout on contributor ci (for screenshot tests) (#8661) --- .github/workflows/contrib_checks.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/contrib_checks.yml b/.github/workflows/contrib_checks.yml index 967edbacb36b..44f68ed6d9ab 100644 --- a/.github/workflows/contrib_checks.yml +++ b/.github/workflows/contrib_checks.yml @@ -95,6 +95,8 @@ jobs: runs-on: ubuntu-latest-16-cores steps: - uses: actions/checkout@v4 + with: + lfs: true - uses: prefix-dev/setup-pixi@v0.8.1 with: From 92949cfaacaca25def9159b0ee332f325abfdbe6 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Mon, 13 Jan 2025 10:58:42 +0100 Subject: [PATCH 14/57] Fix formatting of RowId/Tuid when printing ChunkStore (#8656) Also added a regression test * Part of #3741 --------- Co-authored-by: Clement Rey --- Cargo.lock | 14 ++++-- Cargo.toml | 1 + crates/store/re_chunk/Cargo.toml | 1 + crates/store/re_chunk/src/chunk.rs | 4 +- crates/store/re_chunk/src/transport.rs | 11 ++++- .../store/re_chunk_store/tests/formatting.rs | 48 +++++++++++++++++++ .../formatting__format_chunk_store.snap | 33 +++++++++++++ crates/store/re_format_arrow/Cargo.toml | 1 + crates/store/re_format_arrow/src/lib.rs | 41 ++++------------ .../store/re_log_encoding/src/decoder/mod.rs | 14 ++++-- crates/store/re_types_core/src/tuid.rs | 2 +- crates/utils/re_tuid/src/lib.rs | 2 +- 12 files changed, 129 insertions(+), 43 deletions(-) create mode 100644 crates/store/re_chunk_store/tests/formatting.rs create mode 100644 crates/store/re_chunk_store/tests/snapshots/formatting__format_chunk_store.snap diff --git a/Cargo.lock b/Cargo.lock index 61be28db6ef1..3879fb612337 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3885,7 +3885,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -5203,7 +5203,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c1318b19085f08681016926435853bbf7858f9c082d0999b80550ff5d9abe15" dependencies = [ "bytes", - "heck 0.4.1", + "heck 0.5.0", "itertools 0.13.0", "log", "multimap", @@ -5686,6 +5686,7 @@ dependencies = [ "re_types_core", "serde", "similar-asserts", + "tap", "thiserror 1.0.65", ] @@ -5980,6 +5981,7 @@ name = "re_format_arrow" version = "0.22.0-alpha.1+dev" dependencies = [ "comfy-table", + "itertools 0.13.0", "re_arrow2", "re_tuid", "re_types_core", @@ -8483,6 +8485,12 @@ dependencies = [ "libc", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "target-lexicon" version = "0.12.16" @@ -9848,7 +9856,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 28e8da64fc1f..7f5ca6092ce4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -269,6 +269,7 @@ strum_macros = "0.26" sublime_fuzzy = "0.7" syn = "2.0" sysinfo = { version = "0.30.1", default-features = false } +tap = "1.0.1" tempfile = "3.0" thiserror = "1.0" time = { version = "0.3.36", default-features = false, features = [ diff --git a/crates/store/re_chunk/Cargo.toml b/crates/store/re_chunk/Cargo.toml index 4e091da8a29e..38a9e5b8c963 100644 --- a/crates/store/re_chunk/Cargo.toml +++ b/crates/store/re_chunk/Cargo.toml @@ -63,6 +63,7 @@ itertools.workspace = true nohash-hasher.workspace = true rand = { workspace = true, features = ["std_rng"] } similar-asserts.workspace = true +tap.workspace = true thiserror.workspace = true # Optional dependencies: diff --git a/crates/store/re_chunk/src/chunk.rs b/crates/store/re_chunk/src/chunk.rs index eb0bc8045b0e..b7032f6acf14 100644 --- a/crates/store/re_chunk/src/chunk.rs +++ b/crates/store/re_chunk/src/chunk.rs @@ -1355,11 +1355,11 @@ impl Chunk { impl std::fmt::Display for Chunk { #[inline] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let chunk = self.to_transport().map_err(|err| { + let transport_chunk = self.to_transport().map_err(|err| { re_log::error_once!("couldn't display Chunk: {err}"); std::fmt::Error })?; - chunk.fmt(f) + transport_chunk.fmt(f) } } diff --git a/crates/store/re_chunk/src/transport.rs b/crates/store/re_chunk/src/transport.rs index e603ad9fd856..69350f685d71 100644 --- a/crates/store/re_chunk/src/transport.rs +++ b/crates/store/re_chunk/src/transport.rs @@ -13,6 +13,7 @@ use nohash_hasher::IntMap; use re_byte_size::SizeBytes as _; use re_log_types::{EntityPath, Timeline}; use re_types_core::{Component as _, ComponentDescriptor, Loggable as _}; +use tap::Tap as _; use crate::{chunk::ChunkComponents, Chunk, ChunkError, ChunkId, ChunkResult, RowId, TimeColumn}; @@ -434,7 +435,15 @@ impl Chunk { row_ids.data_type().clone(), false, ) - .with_metadata(TransportChunk::field_metadata_control_column()), + .with_metadata( + TransportChunk::field_metadata_control_column().tap_mut(|metadata| { + // This ensures the RowId/Tuid is formatted correctly + metadata.insert( + "ARROW:extension:name".to_owned(), + re_tuid::Tuid::ARROW_EXTENSION_NAME.to_owned(), + ); + }), + ), ); columns.push(row_ids.clone().boxed()); } diff --git a/crates/store/re_chunk_store/tests/formatting.rs b/crates/store/re_chunk_store/tests/formatting.rs new file mode 100644 index 000000000000..e71fbffdbd1c --- /dev/null +++ b/crates/store/re_chunk_store/tests/formatting.rs @@ -0,0 +1,48 @@ +use std::sync::Arc; + +use re_chunk::{Chunk, ChunkId, RowId}; +use re_chunk_store::ChunkStore; +use re_log_types::{ + build_frame_nr, build_log_time, + example_components::{MyColor, MyIndex}, + EntityPath, Time, +}; +use re_types_core::ComponentBatch as _; + +/// Ensure that `ChunkStore::to_string()` is nice and readable. +#[test] +fn format_chunk_store() -> anyhow::Result<()> { + re_log::setup_logging(); + + let mut store = ChunkStore::new( + re_log_types::StoreId::from_string( + re_log_types::StoreKind::Recording, + "test_id".to_owned(), + ), + Default::default(), + ); + + let entity_path = EntityPath::from("this/that"); + + let (indices1, colors1) = (MyIndex::from_iter(0..3), MyColor::from_iter(0..3)); + + let chunk_id = ChunkId::from_u128(123_456_789_123_456_789_123_456_789); + let row_id = RowId::from_u128(32_033_410_000_000_000_000_000_000_123); + + store.insert_chunk(&Arc::new( + Chunk::builder_with_id(chunk_id, entity_path.clone()) + .with_serialized_batches( + row_id, + [ + build_frame_nr(1), + build_log_time(Time::from_ns_since_epoch(1_736_534_622_123_456_789)), + ], + [indices1.try_serialized()?, colors1.try_serialized()?], + ) + .build()?, + ))?; + + insta::assert_snapshot!("format_chunk_store", store.to_string()); + + Ok(()) +} diff --git a/crates/store/re_chunk_store/tests/snapshots/formatting__format_chunk_store.snap b/crates/store/re_chunk_store/tests/snapshots/formatting__format_chunk_store.snap new file mode 100644 index 000000000000..f8edb7be14e0 --- /dev/null +++ b/crates/store/re_chunk_store/tests/snapshots/formatting__format_chunk_store.snap @@ -0,0 +1,33 @@ +--- +source: crates/store/re_chunk_store/tests/formatting.rs +expression: store.to_string() +--- +ChunkStore { + id: test_id + config: ChunkStoreConfig { enable_changelog: true, chunk_max_bytes: 393216, chunk_max_rows: 4096, chunk_max_rows_if_unsorted: 1024 } + stats: { + num_chunks: 1 + total_size_bytes: 1.0 KiB + num_rows: 1 + num_events: 2 + } + chunks: [ + ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ CHUNK METADATA: │ + │ * entity_path: "/this/that" │ + │ * heap_size_bytes: "838" │ + │ * id: "661EFDF2E3B19F7C045F15" │ + │ * is_sorted: "" │ + ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ + │ ┌──────────────────────────────────┬───────────────┬───────────────────────────────┬───────────────────┬───────────────────┐ │ + │ │ RowId ┆ frame_nr ┆ log_time ┆ example.MyColor ┆ example.MyIndex │ │ + │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ + │ │ type: "struct[2]" ┆ type: "i64" ┆ type: "timestamp(ns)" ┆ type: "list[u32]" ┆ type: "list[u64]" │ │ + │ │ ARROW:extension:name: "TUID" ┆ is_sorted: "" ┆ is_sorted: "" ┆ kind: "data" ┆ kind: "data" │ │ + │ │ kind: "control" ┆ kind: "time" ┆ kind: "time" ┆ ┆ │ │ + │ ╞══════════════════════════════════╪═══════════════╪═══════════════════════════════╪═══════════════════╪═══════════════════╡ │ + │ │ 0000000067816A6BB4B8C1254D40007B ┆ 1 ┆ 2025-01-10 18:43:42.123456789 ┆ [0, 1, 2] ┆ [0, 1, 2] │ │ + │ └──────────────────────────────────┴───────────────┴───────────────────────────────┴───────────────────┴───────────────────┘ │ + └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + ] +} diff --git a/crates/store/re_format_arrow/Cargo.toml b/crates/store/re_format_arrow/Cargo.toml index e752139d70b2..f2d76dd0f8e4 100644 --- a/crates/store/re_format_arrow/Cargo.toml +++ b/crates/store/re_format_arrow/Cargo.toml @@ -21,6 +21,7 @@ all-features = true [dependencies] arrow2.workspace = true +itertools.workspace = true re_tuid.workspace = true re_types_core.workspace = true # tuid serialization diff --git a/crates/store/re_format_arrow/src/lib.rs b/crates/store/re_format_arrow/src/lib.rs index 22ebebbb89f5..a6b143053067 100644 --- a/crates/store/re_format_arrow/src/lib.rs +++ b/crates/store/re_format_arrow/src/lib.rs @@ -21,24 +21,13 @@ use re_types_core::Loggable as _; type CustomFormatter<'a, F> = Box std::fmt::Result + 'a>; fn get_custom_display<'a, F: std::fmt::Write + 'a>( + field: &Field, array: &'a dyn Array, null: &'static str, ) -> CustomFormatter<'a, F> { - // NOTE: If the top-level array is a list, it's probably not the type we're looking for: we're - // interested in the type of the array that's underneath. - let datatype = (|| match array.data_type().to_logical_type() { - DataType::List(_) => array - .as_any() - .downcast_ref::>()? - .iter() - .next()? - .map(|array| array.data_type().clone()), - _ => Some(array.data_type().clone()), - })(); - - if let Some(DataType::Extension(name, _, _)) = datatype { + if let Some(extension_name) = field.metadata.get("ARROW:extension:name") { // TODO(#1775): This should be registered dynamically. - if name.as_str() == Tuid::NAME { + if extension_name.as_str() == Tuid::ARROW_EXTENSION_NAME { return Box::new(|w, index| { if let Some(tuid) = parse_tuid(array, index) { w.write_fmt(format_args!("{tuid}")) @@ -244,21 +233,10 @@ where outer_table.add_row({ let mut row = Row::new(); - row.add_cell({ - let cell = Cell::new(format!( - "CHUNK METADATA:\n{}", - DisplayMetadata(metadata, "* ") - )); - - #[cfg(not(target_arch = "wasm32"))] // requires TTY - { - cell.add_attribute(comfy_table::Attribute::Italic) - } - #[cfg(target_arch = "wasm32")] - { - cell - } - }); + row.add_cell(Cell::new(format!( + "CHUNK METADATA:\n{}", + DisplayMetadata(metadata, "* ") + ))); row }); @@ -280,9 +258,8 @@ where }); table.set_header(header); - let displays = columns - .iter() - .map(|array| get_custom_display(&**array, "-")) + let displays = itertools::izip!(fields.iter(), columns.iter()) + .map(|(field, array)| get_custom_display(field, &**array, "-")) .collect::>(); let num_rows = columns.first().map_or(0, |list_array| list_array.len()); diff --git a/crates/store/re_log_encoding/src/decoder/mod.rs b/crates/store/re_log_encoding/src/decoder/mod.rs index 224bc03ceef2..50f6517f9a75 100644 --- a/crates/store/re_log_encoding/src/decoder/mod.rs +++ b/crates/store/re_log_encoding/src/decoder/mod.rs @@ -456,6 +456,7 @@ mod tests { ] } + // TODO(#3741): should not be needed once the migration from arrow2 is complete fn clear_arrow_extension_metadata(messages: &mut Vec) { for msg in messages { if let LogMsg::ArrowMsg(_, arrow_msg) = msg { @@ -472,7 +473,7 @@ mod tests { fn test_encode_decode() { let rrd_version = CrateVersion::LOCAL; - let messages = fake_log_messages(); + let mut messages = fake_log_messages(); let options = [ EncodingOptions { @@ -503,9 +504,14 @@ mod tests { .collect::, DecodeError>>() .unwrap(); + // TODO(#3741): should not be needed once the migration from arrow2 is complete + clear_arrow_extension_metadata(&mut messages); clear_arrow_extension_metadata(&mut decoded_messages); - assert_eq!(messages, decoded_messages); + assert!( + messages == decoded_messages, + "Got: {decoded_messages:#?}, expected: {messages:#?}" + ); } } @@ -536,7 +542,7 @@ mod tests { let mut data = vec![]; // write "2 files" i.e. 2 streams that end with end-of-stream marker - let messages = fake_log_messages(); + let mut messages = fake_log_messages(); // (2 encoders as each encoder writes a file header) let writer = std::io::Cursor::new(&mut data); @@ -565,6 +571,8 @@ mod tests { let mut decoded_messages = decoder.into_iter().collect::, _>>().unwrap(); + // TODO(#3741): should not be needed once the migration from arrow2 is complete + clear_arrow_extension_metadata(&mut messages); clear_arrow_extension_metadata(&mut decoded_messages); assert_eq!([messages.clone(), messages].concat(), decoded_messages); diff --git a/crates/store/re_types_core/src/tuid.rs b/crates/store/re_types_core/src/tuid.rs index 5d0e5afa42b0..622805a8e353 100644 --- a/crates/store/re_types_core/src/tuid.rs +++ b/crates/store/re_types_core/src/tuid.rs @@ -27,7 +27,7 @@ impl Loggable for Tuid { Self: 'a, { Err(crate::SerializationError::not_implemented( - Self::NAME, + Self::ARROW_EXTENSION_NAME, "TUIDs are never nullable, use `to_arrow()` instead", )) } diff --git a/crates/utils/re_tuid/src/lib.rs b/crates/utils/re_tuid/src/lib.rs index bcfdaa86aeee..f215f1da3477 100644 --- a/crates/utils/re_tuid/src/lib.rs +++ b/crates/utils/re_tuid/src/lib.rs @@ -23,7 +23,7 @@ impl Tuid { /// We give an actual name to [`Tuid`], and inject that name into the Arrow datatype extensions, /// as a hack so that we can compactly format them when printing Arrow data to the terminal. /// Check out `re_format_arrow` for context. - pub const NAME: &'static str = "rerun.datatypes.TUID"; + pub const ARROW_EXTENSION_NAME: &'static str = "rerun.datatypes.TUID"; } impl std::fmt::Display for Tuid { From bdb2742bee2abcb902ef5f8a8678b30ffd7c6039 Mon Sep 17 00:00:00 2001 From: Olivier Le Doeuff Date: Mon, 13 Jan 2025 13:02:31 +0100 Subject: [PATCH 15/57] docs: use `connect_tcp` instead of deprecated `connect` (#8659) Hi I'm going thru the docs for the first time, I did some copy and pasta to connect to the server and I got hit by some deprecated warning. It seems the code wasn't even working and `connect_opts` should have been the one. Co-authored-by: Andreas Reich --- docs/content/getting-started/data-in/rust.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content/getting-started/data-in/rust.md b/docs/content/getting-started/data-in/rust.md index 74b49f353ca7..014452604483 100644 --- a/docs/content/getting-started/data-in/rust.md +++ b/docs/content/getting-started/data-in/rust.md @@ -61,12 +61,12 @@ Checkout `rerun --help` for more options. To get going we want to create a [`RecordingStream`](https://docs.rs/rerun/latest/rerun/struct.RecordingStream.html): We can do all of this with the [`rerun::RecordingStreamBuilder::new`](https://docs.rs/rerun/latest/rerun/struct.RecordingStreamBuilder.html#method.new) function which allows us to name the dataset we're working on by setting its [`ApplicationId`](https://docs.rs/rerun/latest/rerun/struct.ApplicationId.html). -We then connect it to the already running Viewer via [`connect`](https://docs.rs/rerun/latest/rerun/struct.RecordingStreamBuilder.html#method.connect), returning the `RecordingStream` upon success. +We then connect it to the already running Viewer via [`connect_tcp`](https://docs.rs/rerun/latest/rerun/struct.RecordingStreamBuilder.html#method.connect_tcp), returning the `RecordingStream` upon success. ```rust fn main() -> Result<(), Box> { let rec = rerun::RecordingStreamBuilder::new("rerun_example_dna_abacus") - .connect(rerun::default_server_addr(), rerun::default_flush_timeout())?; + .connect_tcp()?; Ok(()) } From d07a374ba2ab99388646a7fc22e6d905bf6fb543 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Mon, 13 Jan 2025 13:28:16 +0100 Subject: [PATCH 16/57] Port row_ids to arrow1 (#8657) ### Related * Part of #3741 --- crates/store/re_chunk/src/arrow_util.rs | 7 +- crates/store/re_chunk/src/chunk.rs | 74 +++++++++---------- crates/store/re_chunk/src/iter.rs | 4 +- crates/store/re_chunk/src/merge.rs | 12 +-- crates/store/re_chunk/src/shuffle.rs | 23 +++--- crates/store/re_chunk/src/slice.rs | 23 +++--- crates/store/re_chunk/src/transport.rs | 22 +++--- .../formatting__format_chunk_store.snap | 6 +- crates/store/re_dataframe/src/query.rs | 4 +- crates/store/re_types_core/src/lib.rs | 1 + crates/store/re_types_core/src/tuid.rs | 13 +++- crates/utils/re_byte_size/src/arrow_sizes.rs | 8 +- 12 files changed, 105 insertions(+), 92 deletions(-) diff --git a/crates/store/re_chunk/src/arrow_util.rs b/crates/store/re_chunk/src/arrow_util.rs index 9ff23565e963..c3d80b207b9b 100644 --- a/crates/store/re_chunk/src/arrow_util.rs +++ b/crates/store/re_chunk/src/arrow_util.rs @@ -7,6 +7,11 @@ use itertools::Itertools; // --- +#[inline] +pub fn into_arrow_ref(array: impl Array + 'static) -> ArrayRef { + std::sync::Arc::new(array) +} + /// Returns true if the given `list_array` is semantically empty. /// /// Semantic emptiness is defined as either one of these: @@ -285,7 +290,7 @@ where ); if indices.len() == array.len() { - let indices = indices.values().as_ref(); + let indices = indices.values(); let starts_at_zero = || indices[0] == O::Native::ZERO; let is_consecutive = || { diff --git a/crates/store/re_chunk/src/chunk.rs b/crates/store/re_chunk/src/chunk.rs index b7032f6acf14..936c1cb6ef81 100644 --- a/crates/store/re_chunk/src/chunk.rs +++ b/crates/store/re_chunk/src/chunk.rs @@ -2,14 +2,14 @@ use std::sync::atomic::{AtomicU64, Ordering}; use ahash::HashMap; use arrow::{ - array::{Array as ArrowArray, ArrayRef as ArrowArrayRef, ListArray as ArrowListArray}, + array::{ + Array as ArrowArray, ArrayRef as ArrowArrayRef, ListArray as ArrowListArray, + StructArray as ArrowStructArray, UInt64Array as ArrowUInt64Array, + }, buffer::ScalarBuffer as ArrowScalarBuffer, }; use arrow2::{ - array::{ - Array as Arrow2Array, ListArray as Arrow2ListArray, PrimitiveArray as Arrow2PrimitiveArray, - StructArray as Arrow2StructArray, - }, + array::{Array as Arrow2Array, ListArray as Arrow2ListArray}, Either, }; use itertools::{izip, Itertools}; @@ -34,7 +34,10 @@ pub enum ChunkError { Malformed { reason: String }, #[error(transparent)] - Arrow(#[from] arrow2::error::Error), + Arrow(#[from] arrow::error::ArrowError), + + #[error(transparent)] + Arrow2(#[from] arrow2::error::Error), #[error("{kind} index out of bounds: {index} (len={len})")] IndexOutOfBounds { @@ -224,7 +227,7 @@ pub struct Chunk { pub(crate) is_sorted: bool, /// The respective [`RowId`]s for each row of data. - pub(crate) row_ids: Arrow2StructArray, + pub(crate) row_ids: ArrowStructArray, /// The time columns. /// @@ -351,12 +354,6 @@ impl Chunk { components, } = self; - let row_ids_no_extension = arrow2::array::StructArray::new( - row_ids.data_type().to_logical_type().clone(), - row_ids.values().to_vec(), - row_ids.validity().cloned(), - ); - let components_no_extension: IntMap<_, _> = components .values() .flat_map(|per_desc| { @@ -388,16 +385,10 @@ impl Chunk { }) .collect(); - let other_row_ids_no_extension = arrow2::array::StructArray::new( - other.row_ids.data_type().to_logical_type().clone(), - other.row_ids.values().to_vec(), - other.row_ids.validity().cloned(), - ); - *id == other.id && *entity_path == other.entity_path && *is_sorted == other.is_sorted - && row_ids_no_extension == other_row_ids_no_extension + && row_ids == &other.row_ids && *timelines == other.timelines && components_no_extension == other_components_no_extension } @@ -437,11 +428,11 @@ impl Chunk { .collect_vec(); #[allow(clippy::unwrap_used)] - let row_ids = ::to_arrow2(&row_ids) + let row_ids = ::to_arrow(&row_ids) // Unwrap: native RowIds cannot fail to serialize. .unwrap() .as_any() - .downcast_ref::() + .downcast_ref::() // Unwrap: RowId schema is known in advance to be a struct array -- always. .unwrap() .clone(); @@ -493,11 +484,11 @@ impl Chunk { .collect_vec(); #[allow(clippy::unwrap_used)] - let row_ids = ::to_arrow2(&row_ids) + let row_ids = ::to_arrow(&row_ids) // Unwrap: native RowIds cannot fail to serialize. .unwrap() .as_any() - .downcast_ref::() + .downcast_ref::() // Unwrap: RowId schema is known in advance to be a struct array -- always. .unwrap() .clone(); @@ -826,7 +817,7 @@ impl Chunk { id: ChunkId, entity_path: EntityPath, is_sorted: Option, - row_ids: Arrow2StructArray, + row_ids: ArrowStructArray, timelines: IntMap, components: ChunkComponents, ) -> ChunkResult { @@ -866,13 +857,13 @@ impl Chunk { ) -> ChunkResult { re_tracing::profile_function!(); let row_ids = row_ids - .to_arrow2() + .to_arrow() // NOTE: impossible, but better safe than sorry. .map_err(|err| ChunkError::Malformed { reason: format!("RowIds failed to serialize: {err}"), })? .as_any() - .downcast_ref::() + .downcast_ref::() // NOTE: impossible, but better safe than sorry. .ok_or_else(|| ChunkError::Malformed { reason: "RowIds failed to downcast".to_owned(), @@ -923,7 +914,7 @@ impl Chunk { id: ChunkId, entity_path: EntityPath, is_sorted: Option, - row_ids: Arrow2StructArray, + row_ids: ArrowStructArray, components: ChunkComponents, ) -> ChunkResult { Self::new( @@ -943,7 +934,11 @@ impl Chunk { entity_path, heap_size_bytes: Default::default(), is_sorted: true, - row_ids: Arrow2StructArray::new_empty(RowId::arrow2_datatype()), + row_ids: arrow::array::StructBuilder::from_fields( + re_types_core::tuid_arrow_fields(), + 0, + ) + .finish(), timelines: Default::default(), components: Default::default(), } @@ -1203,27 +1198,24 @@ impl Chunk { } #[inline] - pub fn row_ids_array(&self) -> &Arrow2StructArray { + pub fn row_ids_array(&self) -> &ArrowStructArray { &self.row_ids } /// Returns the [`RowId`]s in their raw-est form: a tuple of (times, counters) arrays. #[inline] - pub fn row_ids_raw(&self) -> (&Arrow2PrimitiveArray, &Arrow2PrimitiveArray) { - let [times, counters] = self.row_ids.values() else { + pub fn row_ids_raw(&self) -> (&ArrowUInt64Array, &ArrowUInt64Array) { + let [times, counters] = self.row_ids.columns() else { panic!("RowIds are corrupt -- this should be impossible (sanity checked)"); }; #[allow(clippy::unwrap_used)] - let times = times - .as_any() - .downcast_ref::>() - .unwrap(); // sanity checked + let times = times.as_any().downcast_ref::().unwrap(); // sanity checked #[allow(clippy::unwrap_used)] let counters = counters .as_any() - .downcast_ref::>() + .downcast_ref::() .unwrap(); // sanity checked (times, counters) @@ -1235,7 +1227,7 @@ impl Chunk { #[inline] pub fn row_ids(&self) -> impl Iterator + '_ { let (times, counters) = self.row_ids_raw(); - izip!(times.values().as_ref(), counters.values().as_slice()) + izip!(times.values(), counters.values()) .map(|(&time, &counter)| RowId::from_u128((time as u128) << 64 | (counter as u128))) } @@ -1277,7 +1269,7 @@ impl Chunk { } let (times, counters) = self.row_ids_raw(); - let (times, counters) = (times.values().as_ref(), counters.values().as_slice()); + let (times, counters) = (times.values(), counters.values()); #[allow(clippy::unwrap_used)] // checked above let (index_min, index_max) = if self.is_sorted() { @@ -1558,11 +1550,11 @@ impl Chunk { // Row IDs { - if *row_ids.data_type().to_logical_type() != RowId::arrow2_datatype() { + if *row_ids.data_type() != RowId::arrow_datatype() { return Err(ChunkError::Malformed { reason: format!( "RowId data has the wrong datatype: expected {:?} but got {:?} instead", - RowId::arrow2_datatype(), + RowId::arrow_datatype(), *row_ids.data_type(), ), }); diff --git a/crates/store/re_chunk/src/iter.rs b/crates/store/re_chunk/src/iter.rs index bd38875103c0..f86d28919172 100644 --- a/crates/store/re_chunk/src/iter.rs +++ b/crates/store/re_chunk/src/iter.rs @@ -683,8 +683,8 @@ impl Iterator for ChunkIndicesIter { let row_id = { let (times, incs) = self.chunk.row_ids_raw(); - let times = times.values().as_slice(); - let incs = incs.values().as_slice(); + let times = times.values(); + let incs = incs.values(); let time = *times.get(i)?; let inc = *incs.get(i)?; diff --git a/crates/store/re_chunk/src/merge.rs b/crates/store/re_chunk/src/merge.rs index 9b4433b1e975..5236b8a02813 100644 --- a/crates/store/re_chunk/src/merge.rs +++ b/crates/store/re_chunk/src/merge.rs @@ -1,12 +1,12 @@ +use arrow::array::StructArray as ArrowStructArray; use arrow::buffer::ScalarBuffer as ArrowScalarBuffer; -use arrow2::array::{ - Array as Arrow2Array, ListArray as Arrow2ListArray, StructArray as Arrow2StructArray, -}; +use arrow2::array::{Array as Arrow2Array, ListArray as Arrow2ListArray}; use itertools::{izip, Itertools}; use nohash_hasher::IntMap; use crate::{ - arrow2_util, chunk::ChunkComponents, Chunk, ChunkError, ChunkId, ChunkResult, TimeColumn, + arrow2_util, arrow_util, chunk::ChunkComponents, Chunk, ChunkError, ChunkId, ChunkResult, + TimeColumn, }; // --- @@ -48,12 +48,12 @@ impl Chunk { let row_ids = { re_tracing::profile_scope!("row_ids"); - let row_ids = arrow2_util::concat_arrays(&[&cl.row_ids, &cr.row_ids])?; + let row_ids = arrow_util::concat_arrays(&[&cl.row_ids, &cr.row_ids])?; #[allow(clippy::unwrap_used)] // concatenating 2 RowId arrays must yield another RowId array row_ids .as_any() - .downcast_ref::() + .downcast_ref::() .unwrap() .clone() }; diff --git a/crates/store/re_chunk/src/shuffle.rs b/crates/store/re_chunk/src/shuffle.rs index 86d48b35bdb2..4b15f425def6 100644 --- a/crates/store/re_chunk/src/shuffle.rs +++ b/crates/store/re_chunk/src/shuffle.rs @@ -1,9 +1,11 @@ -use arrow::buffer::ScalarBuffer as ArrowScalarBuffer; +use std::sync::Arc; + +use arrow::{ + array::{Array as _, StructArray as ArrowStructArray, UInt64Array as ArrowUInt64Array}, + buffer::ScalarBuffer as ArrowScalarBuffer, +}; use arrow2::{ - array::{ - Array as Arrow2Array, ListArray as Arrow2ListArray, PrimitiveArray as Arrow2PrimitiveArray, - StructArray, - }, + array::{Array as Arrow2Array, ListArray as Arrow2ListArray}, offset::Offsets as ArrowOffsets, }; use itertools::Itertools as _; @@ -213,14 +215,11 @@ impl Chunk { sorted_counters[to] = counters[from]; } - let times = Arrow2PrimitiveArray::::from_vec(sorted_times).boxed(); - let counters = Arrow2PrimitiveArray::::from_vec(sorted_counters).boxed(); + let times = Arc::new(ArrowUInt64Array::from(sorted_times)); + let counters = Arc::new(ArrowUInt64Array::from(sorted_counters)); - self.row_ids = StructArray::new( - self.row_ids.data_type().clone(), - vec![times, counters], - None, - ); + self.row_ids = + ArrowStructArray::new(self.row_ids.fields().clone(), vec![times, counters], None); } let Self { diff --git a/crates/store/re_chunk/src/slice.rs b/crates/store/re_chunk/src/slice.rs index 3b2f842cef92..782f97cacb0b 100644 --- a/crates/store/re_chunk/src/slice.rs +++ b/crates/store/re_chunk/src/slice.rs @@ -1,6 +1,5 @@ use arrow2::array::{ Array as Arrow2Array, BooleanArray as Arrow2BooleanArray, ListArray as Arrow2ListArray, - StructArray as Arrow2StructArray, }; use itertools::Itertools; @@ -38,8 +37,8 @@ impl Chunk { let row_id_inc = (row_id_128 & (!0 >> 64)) as u64; let (times, incs) = self.row_ids_raw(); - let times = times.values().as_slice(); - let incs = incs.values().as_slice(); + let times = times.values(); + let incs = incs.values(); let mut index = times.partition_point(|&time| time < row_id_time_ns); while index < incs.len() && incs[index] < row_id_inc { @@ -102,7 +101,7 @@ impl Chunk { entity_path: entity_path.clone(), heap_size_bytes: Default::default(), is_sorted, - row_ids: row_ids.clone().sliced(index, len), + row_ids: row_ids.clone().slice(index, len), timelines: timelines .iter() .map(|(timeline, time_column)| (*timeline, time_column.row_sliced(index, len))) @@ -369,7 +368,7 @@ impl Chunk { entity_path: entity_path.clone(), heap_size_bytes: Default::default(), is_sorted, - row_ids: arrow2_util::filter_array(row_ids, &validity_filter), + row_ids: arrow_util::filter_array(row_ids, &validity_filter.clone().into()), timelines: timelines .iter() .map(|(&timeline, time_column)| (timeline, time_column.filtered(&validity_filter))) @@ -450,7 +449,7 @@ impl Chunk { entity_path: entity_path.clone(), heap_size_bytes: Default::default(), is_sorted: true, - row_ids: Arrow2StructArray::new_empty(row_ids.data_type().clone()), + row_ids: arrow::array::StructBuilder::from_fields(row_ids.fields().clone(), 0).finish(), timelines: timelines .iter() .map(|(&timeline, time_column)| (timeline, time_column.emptied())) @@ -546,7 +545,10 @@ impl Chunk { entity_path: self.entity_path.clone(), heap_size_bytes: Default::default(), is_sorted: self.is_sorted, - row_ids: arrow2_util::take_array(&self.row_ids, &indices), + row_ids: arrow_util::take_array( + &self.row_ids, + &arrow::array::Int32Array::from(indices.clone()), + ), timelines: self .timelines .iter() @@ -619,7 +621,7 @@ impl Chunk { entity_path: entity_path.clone(), heap_size_bytes: Default::default(), is_sorted, - row_ids: arrow2_util::filter_array(row_ids, filter), + row_ids: arrow_util::filter_array(row_ids, &filter.clone().into()), timelines: timelines .iter() .map(|(&timeline, time_column)| (timeline, time_column.filtered(filter))) @@ -699,7 +701,10 @@ impl Chunk { entity_path: entity_path.clone(), heap_size_bytes: Default::default(), is_sorted, - row_ids: arrow2_util::take_array(row_ids, indices), + row_ids: arrow_util::take_array( + row_ids, + &arrow::array::Int32Array::from(indices.clone()), + ), timelines: timelines .iter() .map(|(&timeline, time_column)| (timeline, time_column.taken(indices))) diff --git a/crates/store/re_chunk/src/transport.rs b/crates/store/re_chunk/src/transport.rs index 69350f685d71..f8dcbcbcd2ad 100644 --- a/crates/store/re_chunk/src/transport.rs +++ b/crates/store/re_chunk/src/transport.rs @@ -1,6 +1,6 @@ -use arrow::array::ArrayRef as ArrowArrayRef; +use arrow::array::{ArrayRef as ArrowArrayRef, StructArray as ArrowStructArray}; use arrow2::{ - array::{Array as Arrow2Array, ListArray, StructArray as Arrow2StructArray}, + array::{Array as Arrow2Array, ListArray}, chunk::Chunk as Arrow2Chunk, datatypes::{ DataType as Arrow2Datatype, Field as ArrowField, Metadata as Arrow2Metadata, @@ -15,7 +15,10 @@ use re_log_types::{EntityPath, Timeline}; use re_types_core::{Component as _, ComponentDescriptor, Loggable as _}; use tap::Tap as _; -use crate::{chunk::ChunkComponents, Chunk, ChunkError, ChunkId, ChunkResult, RowId, TimeColumn}; +use crate::{ + arrow_util::into_arrow_ref, chunk::ChunkComponents, Chunk, ChunkError, ChunkId, ChunkResult, + RowId, TimeColumn, +}; // --- @@ -398,7 +401,8 @@ impl Chunk { } = self; let mut schema = Arrow2Schema::default(); - let mut columns = Vec::with_capacity(1 /* row_ids */ + timelines.len() + components.len()); + let mut columns: Vec> = + Vec::with_capacity(1 /* row_ids */ + timelines.len() + components.len()); // Chunk-level metadata { @@ -432,7 +436,7 @@ impl Chunk { schema.fields.push( ArrowField::new( RowId::descriptor().to_string(), - row_ids.data_type().clone(), + RowId::arrow_datatype().clone().into(), false, ) .with_metadata( @@ -445,7 +449,7 @@ impl Chunk { }), ), ); - columns.push(row_ids.clone().boxed()); + columns.push(into_arrow_ref(row_ids.clone()).into()); } // Timelines @@ -561,13 +565,13 @@ impl Chunk { }); }; - row_ids + ArrowArrayRef::from(row_ids.clone()) .as_any() - .downcast_ref::() + .downcast_ref::() .ok_or_else(|| ChunkError::Malformed { reason: format!( "RowId data has the wrong datatype: expected {:?} but got {:?} instead", - RowId::arrow2_datatype(), + RowId::arrow_datatype(), *row_ids.data_type(), ), })? diff --git a/crates/store/re_chunk_store/tests/snapshots/formatting__format_chunk_store.snap b/crates/store/re_chunk_store/tests/snapshots/formatting__format_chunk_store.snap index f8edb7be14e0..23ee30ee7353 100644 --- a/crates/store/re_chunk_store/tests/snapshots/formatting__format_chunk_store.snap +++ b/crates/store/re_chunk_store/tests/snapshots/formatting__format_chunk_store.snap @@ -1,13 +1,15 @@ --- source: crates/store/re_chunk_store/tests/formatting.rs +assertion_line: 45 expression: store.to_string() +snapshot_kind: text --- ChunkStore { id: test_id config: ChunkStoreConfig { enable_changelog: true, chunk_max_bytes: 393216, chunk_max_rows: 4096, chunk_max_rows_if_unsorted: 1024 } stats: { num_chunks: 1 - total_size_bytes: 1.0 KiB + total_size_bytes: 1.3 KiB num_rows: 1 num_events: 2 } @@ -15,7 +17,7 @@ ChunkStore { ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ CHUNK METADATA: │ │ * entity_path: "/this/that" │ - │ * heap_size_bytes: "838" │ + │ * heap_size_bytes: "1134" │ │ * id: "661EFDF2E3B19F7C045F15" │ │ * is_sorted: "" │ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ diff --git a/crates/store/re_dataframe/src/query.rs b/crates/store/re_dataframe/src/query.rs index e998efc7aad0..92481b4c3958 100644 --- a/crates/store/re_dataframe/src/query.rs +++ b/crates/store/re_dataframe/src/query.rs @@ -969,8 +969,8 @@ impl QueryHandle { let cur_index_row_id_at = |at: usize| { let (times, incs) = cur_index_row_ids; - let times = times.values().as_slice(); - let incs = incs.values().as_slice(); + let times = times.values(); + let incs = incs.values(); let time = *times.get(at)?; let inc = *incs.get(at)?; diff --git a/crates/store/re_types_core/src/lib.rs b/crates/store/re_types_core/src/lib.rs index c927f0197538..d8e4e38d104d 100644 --- a/crates/store/re_types_core/src/lib.rs +++ b/crates/store/re_types_core/src/lib.rs @@ -58,6 +58,7 @@ pub use self::{ DeserializationError, DeserializationResult, ResultExt, SerializationError, SerializationResult, _Backtrace, }, + tuid::tuid_arrow_fields, view::{View, ViewClassIdentifier}, }; diff --git a/crates/store/re_types_core/src/tuid.rs b/crates/store/re_types_core/src/tuid.rs index 622805a8e353..1bcbd9d6e22a 100644 --- a/crates/store/re_types_core/src/tuid.rs +++ b/crates/store/re_types_core/src/tuid.rs @@ -11,13 +11,18 @@ use crate::{DeserializationError, Loggable}; // --- +// TODO(emilk): This is a bit ugly… but good enough for now? +pub fn tuid_arrow_fields() -> Fields { + Fields::from(vec![ + Field::new("time_ns", DataType::UInt64, false), + Field::new("inc", DataType::UInt64, false), + ]) +} + impl Loggable for Tuid { #[inline] fn arrow_datatype() -> arrow::datatypes::DataType { - DataType::Struct(Fields::from(vec![ - Field::new("time_ns", DataType::UInt64, false), - Field::new("inc", DataType::UInt64, false), - ])) + DataType::Struct(tuid_arrow_fields()) } fn to_arrow_opt<'a>( diff --git a/crates/utils/re_byte_size/src/arrow_sizes.rs b/crates/utils/re_byte_size/src/arrow_sizes.rs index 7f8cba0f76dc..862af2b8b583 100644 --- a/crates/utils/re_byte_size/src/arrow_sizes.rs +++ b/crates/utils/re_byte_size/src/arrow_sizes.rs @@ -1,5 +1,5 @@ use arrow::{ - array::{Array, ArrayRef, ArrowPrimitiveType, PrimitiveArray}, + array::{Array, ArrayRef}, buffer::ScalarBuffer, datatypes::ArrowNativeType, }; @@ -13,17 +13,17 @@ impl SizeBytes for dyn Array { } } -impl SizeBytes for ArrayRef { +impl SizeBytes for &T { #[inline] fn heap_size_bytes(&self) -> u64 { self.get_array_memory_size() as u64 } } -impl SizeBytes for PrimitiveArray { +impl SizeBytes for ArrayRef { #[inline] fn heap_size_bytes(&self) -> u64 { - Array::get_array_memory_size(self) as u64 + self.get_array_memory_size() as u64 } } From fbea1eabb48a889b1890b7fcd608d6d5a7167e03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Mon, 13 Jan 2025 16:15:36 +0100 Subject: [PATCH 17/57] Fix doc comments for `query_catalog` in `rerun_bindings.pyi` (#8663) ### What Fixing the CI failure, by updating the `rerun_bindings.pyi`. --------- Co-authored-by: Jeremy Leibs --- rerun_py/rerun_bindings/rerun_bindings.pyi | 8 ++++---- rerun_py/src/remote.rs | 4 ++-- scripts/ci/build_and_upload_wheels.py | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/rerun_py/rerun_bindings/rerun_bindings.pyi b/rerun_py/rerun_bindings/rerun_bindings.pyi index 05a419764dfd..b9c4854e9602 100644 --- a/rerun_py/rerun_bindings/rerun_bindings.pyi +++ b/rerun_py/rerun_bindings/rerun_bindings.pyi @@ -581,14 +581,14 @@ class StorageNodeClient: self, columns: Optional[list[str]] = None, recording_ids: Optional[list[str]] = None ) -> pa.RecordBatchReader: """ - Get the metadata recordings in the storage node. + Get the metadata for recordings in the storage node. Parameters ---------- - columns : Optional[list[str]], optional - The columns to include in the output, by default None. + columns : Optional[list[str]] + The columns to fetch. If `None`, fetch all columns. recording_ids : Optional[list[str]] - Filter specific recordings by Recording Id + Fetch metadata of only specific recordings. If `None`, fetch for all. """ ... diff --git a/rerun_py/src/remote.rs b/rerun_py/src/remote.rs index 87073ae9bafc..2ba5b453c8a6 100644 --- a/rerun_py/src/remote.rs +++ b/rerun_py/src/remote.rs @@ -195,9 +195,9 @@ impl PyStorageNodeClient { /// Parameters /// ---------- /// columns : Optional[list[str]] - /// The columns to fetch. If `None`, fetch all columns. + /// The columns to fetch. If `None`, fetch all columns. /// recording_ids : Optional[list[str]] - /// Fetch metadata of only specific recordings. If `None`, fetch for all. + /// Fetch metadata of only specific recordings. If `None`, fetch for all. #[pyo3(signature = ( columns = None, recording_ids = None, diff --git a/scripts/ci/build_and_upload_wheels.py b/scripts/ci/build_and_upload_wheels.py index 0de8495db3f8..fa1fe628c961 100755 --- a/scripts/ci/build_and_upload_wheels.py +++ b/scripts/ci/build_and_upload_wheels.py @@ -70,7 +70,8 @@ def build_and_upload(bucket: Bucket | None, mode: BuildMode, gcs_dir: str, targe if mode is BuildMode.PYPI: maturin_feature_flags = "--no-default-features --features pypi" elif mode is BuildMode.PR: - maturin_feature_flags = "--no-default-features --features extension-module" + # Remote is necessary to fully validate the signature match on the wheels + maturin_feature_flags = "--no-default-features --features extension-module,remote" elif mode is BuildMode.EXTRA: maturin_feature_flags = "--no-default-features --features pypi,extra" From 2480a89695b2eb0ed3a56c118f778e7942daa326 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Mon, 13 Jan 2025 16:51:05 +0100 Subject: [PATCH 18/57] Filter entities in the UI (part 1): Introduce a filter widget (#8652) --- Cargo.lock | 1 + crates/viewer/re_ui/Cargo.toml | 3 +- crates/viewer/re_ui/data/icons/search.png | Bin 0 -> 407 bytes .../re_ui/examples/re_ui_example/main.rs | 29 +- crates/viewer/re_ui/src/filter_widget.rs | 289 ++++++++++++++++++ crates/viewer/re_ui/src/icons.rs | 2 + crates/viewer/re_ui/src/lib.rs | 1 + .../viewer/re_ui/tests/filter_widget_test.rs | 36 +++ .../re_ui/tests/snapshots/filter_widget.png | 3 + 9 files changed, 361 insertions(+), 3 deletions(-) create mode 100644 crates/viewer/re_ui/data/icons/search.png create mode 100644 crates/viewer/re_ui/src/filter_widget.rs create mode 100644 crates/viewer/re_ui/tests/filter_widget_test.rs create mode 100644 crates/viewer/re_ui/tests/snapshots/filter_widget.png diff --git a/Cargo.lock b/Cargo.lock index 3879fb612337..2dcf6f327137 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6587,6 +6587,7 @@ dependencies = [ "egui_extras", "egui_kittest", "egui_tiles", + "getrandom", "itertools 0.13.0", "once_cell", "parking_lot", diff --git a/crates/viewer/re_ui/Cargo.toml b/crates/viewer/re_ui/Cargo.toml index aa0abbe63646..f166efe51cf2 100644 --- a/crates/viewer/re_ui/Cargo.toml +++ b/crates/viewer/re_ui/Cargo.toml @@ -45,10 +45,10 @@ egui_commonmark = { workspace = true, features = ["pulldown_cmark"] } egui_extras.workspace = true egui_tiles.workspace = true egui.workspace = true +getrandom.workspace = true itertools.workspace = true once_cell.workspace = true parking_lot.workspace = true -rand.workspace = true serde = { workspace = true, features = ["derive"] } serde_json.workspace = true smallvec.workspace = true @@ -70,4 +70,5 @@ time = { workspace = true, features = [ [dev-dependencies] egui_kittest.workspace = true +rand.workspace = true re_types.workspace = true diff --git a/crates/viewer/re_ui/data/icons/search.png b/crates/viewer/re_ui/data/icons/search.png new file mode 100644 index 0000000000000000000000000000000000000000..b89afe1742cb584bf405bf91584ac7a1928a88a6 GIT binary patch literal 407 zcmV;I0cie-P)_~&`I*OGFzY;{3xqbvkl+0|vw}#CYISw(qmW)WfKW=yi-xqS-lAWVm=SfTHE!Na- zAco66rTA>qNK$cT^kY!)5w& z?qj~cA;yljiZpnKJ?n<|3dB0oL+70~+|$a~E8)JAnm1tAfxROw{QACoM<=ClU~dxz z;qZ6j^py2MvMio5A1|uh;50?e!^9%muwjt=FE`iKY!(@H!w>)f002ovPDHLkV1mwF Br(gg8 literal 0 HcmV?d00001 diff --git a/crates/viewer/re_ui/examples/re_ui_example/main.rs b/crates/viewer/re_ui/examples/re_ui_example/main.rs index 1a92bc219444..4e573988cfeb 100644 --- a/crates/viewer/re_ui/examples/re_ui_example/main.rs +++ b/crates/viewer/re_ui/examples/re_ui_example/main.rs @@ -4,8 +4,8 @@ mod right_panel; use re_ui::notifications; use re_ui::{ - list_item, CommandPalette, ContextExt as _, DesignTokens, UICommand, UICommandSender, - UiExt as _, + filter_widget::FilterState, list_item, CommandPalette, ContextExt as _, DesignTokens, + UICommand, UICommandSender, UiExt as _, }; /// Sender that queues up the execution of a command. @@ -86,6 +86,8 @@ pub struct ExampleApp { dummy_bool: bool, + filter_state: FilterState, + cmd_palette: CommandPalette, /// Commands to run at the end of the frame. @@ -119,6 +121,8 @@ impl ExampleApp { dummy_bool: true, + filter_state: FilterState::default(), + cmd_palette: CommandPalette::default(), command_sender, command_receiver, @@ -244,6 +248,27 @@ impl eframe::App for ExampleApp { ui.re_checkbox(&mut self.dummy_bool, "Checkbox"); }); }); + + ui.scope(|ui| { + ui.spacing_mut().item_spacing.y = 0.0; + + ui.full_span_separator(); + self.filter_state + .ui(ui, egui::RichText::new("Filter demo").strong()); + ui.full_span_separator(); + + let names = vec![ + "Andreas", "Antoine", "Clement", "Emil", "Jan", "Jeremy", "Jochen", "Katya", + "Moritz", "Niko", "Zeljko", + ]; + + let filter = self.filter_state.filter(); + for name in names { + if let Some(widget_text) = filter.matches_formatted(ui.ctx(), name) { + ui.list_item_flat_noninteractive(list_item::LabelContent::new(widget_text)); + } + } + }); }; // UI code diff --git a/crates/viewer/re_ui/src/filter_widget.rs b/crates/viewer/re_ui/src/filter_widget.rs new file mode 100644 index 000000000000..b75d8d553804 --- /dev/null +++ b/crates/viewer/re_ui/src/filter_widget.rs @@ -0,0 +1,289 @@ +use std::ops::Range; + +use egui::{Color32, NumExt as _, Widget as _}; +use itertools::Either; + +use crate::{list_item, UiExt as _}; + +/// State for the filter widget when it is toggled on. +#[derive(Debug, Clone)] +struct InnerState { + /// The filter query string. + filter_query: String, + + /// This ID is recreated every time the filter is toggled and tracks the current filtering + /// session. + /// + /// This can be useful for client code to store session-specific state (e.g., the state of tree + /// collapsed-ness). + session_id: egui::Id, +} + +impl Default for InnerState { + fn default() -> Self { + let mut random_bytes = [0u8; 8]; + getrandom::getrandom(&mut random_bytes).expect("Couldn't get random bytes"); + + Self { + filter_query: String::new(), + + // create a new session id each time the filter is toggled + session_id: egui::Id::new(random_bytes), + } + } +} + +/// State and UI for the filter widget. +/// +/// The filter widget is designed as a toggle between a title widget and the filter text field. +/// [`Self`] is responsible for storing the widget state as well as the query text typed by the +/// user. [`FilterMatcher`] performs the actual filtering. +#[derive(Debug, Clone, Default)] +pub struct FilterState { + /// The current state of the filter widget. + /// + /// This is `None` when the filter is not active. + inner_state: Option, + + /// Should the text field be focused? + /// + /// Set to `true` upon clicking on the search button. + request_focus: bool, +} + +impl FilterState { + /// Return the filter if any. + /// + /// Returns `None` if the filter is disabled. Returns `Some(query)` if the filter is enabled + /// (even if the query string is empty, in which case it should match nothing). + pub fn query(&self) -> Option<&str> { + self.inner_state + .as_ref() + .map(|state| state.filter_query.as_str()) + } + + /// Return the current session ID of the filter widget, if active. + pub fn session_id(&self) -> Option { + self.inner_state.as_ref().map(|state| state.session_id) + } + + /// Return a filter matcher for the current query. + pub fn filter(&self) -> FilterMatcher { + FilterMatcher::new(self.query()) + } + + /// Display the filter widget. + /// + /// Note: this uses [`egui::Ui::available_width`] to determine the location of the right-aligned + /// search button, as usual for [`list_item::ListItem`]-based widgets. + pub fn ui(&mut self, ui: &mut egui::Ui, section_title: impl Into) { + let mut button_clicked = false; + + let icon = if self.inner_state.is_none() { + &crate::icons::SEARCH + } else { + &crate::icons::CLOSE + }; + + // precompute the title layout such that we know the size we need for the list item content + let section_title = section_title.into(); + let galley = section_title.into_galley( + ui, + Some(egui::TextWrapMode::Extend), + f32::INFINITY, + egui::FontSelection::default(), + ); + let text_width = galley.size().x; + + list_item::list_item_scope(ui, ui.next_auto_id(), |ui| { + ui.list_item() + .interactive(false) + .with_height(30.0) + .show_flat( + ui, + list_item::CustomContent::new(|ui, _| { + if self.inner_state.is_some() + && ui.input_mut(|i| { + i.consume_key(egui::Modifiers::NONE, egui::Key::Escape) + }) + { + self.inner_state = None; + } + + if let Some(inner_state) = self.inner_state.as_mut() { + // we add additional spacing for aesthetic reasons (active text edits have a + // fat border) + ui.spacing_mut().text_edit_width = + (ui.max_rect().width() - 10.0).at_least(0.0); + + let response = + egui::TextEdit::singleline(&mut inner_state.filter_query) + .lock_focus(true) + .ui(ui); + + if self.request_focus { + self.request_focus = false; + response.request_focus(); + } + } else { + ui.label(galley); + } + }) + .with_content_width(text_width) + .action_button(icon, || { + button_clicked = true; + }), + ); + }); + + // defer button handling because we can't mutably borrow `self` in both closures above + if button_clicked { + if self.inner_state.is_none() { + self.inner_state = Some(InnerState::default()); + self.request_focus = true; + } else { + self.inner_state = None; + } + } + } +} + +// -- + +/// Full-text, case-insensitive matcher. +pub struct FilterMatcher { + /// The lowercase version of the query string. + /// + /// If this is `None`, the filter is inactive and the matcher will accept everything. If this + /// is `Some("")`, the matcher will reject any input. + lowercase_query: Option, +} + +impl FilterMatcher { + fn new(query: Option<&str>) -> Self { + Self { + lowercase_query: query.map(|s| s.to_lowercase()), + } + } + + /// Is the filter set to match everything? + /// + /// Can be used by client code to short-circuit more expansive matching logic. + pub fn matches_everything(&self) -> bool { + self.lowercase_query.is_none() + } + + /// Is the filter set to match nothing? + /// + /// Can be used by client code to short-circuit more expansive matching logic. + pub fn matches_nothing(&self) -> bool { + self.lowercase_query + .as_ref() + .is_some_and(|query| query.is_empty()) + } + + /// Does the given text match the filter? + pub fn matches(&self, text: &str) -> bool { + match self.lowercase_query.as_deref() { + None => true, + Some("") => false, + Some(query) => text.to_lowercase().contains(query), + } + } + + /// Find all matches in the given text. + /// + /// Can be used to format the text, e.g. with [`format_matching_text`]. + /// + /// 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> + '_> { + let query = match self.lowercase_query.as_deref() { + None => { + return Some(Either::Left(std::iter::empty())); + } + Some("") => { + return None; + } + Some(query) => query, + }; + + let mut start = 0; + let lower_case_text = text.to_lowercase(); + let query_len = query.len(); + + if !lower_case_text.contains(query) { + return None; + } + + Some(Either::Right(std::iter::from_fn(move || { + let index = lower_case_text[start..].find(query)?; + let start_index = start + index; + start = start_index + query_len; + Some(start_index..(start_index + query_len)) + }))) + } + + /// Returns a formatted version of the text with the matching sections highlighted. + /// + /// Returns `None` when there is no match (so nothing should be displayed). + /// Returns `Some` when the filter is inactive (and thus matches everything), or if there is an + /// 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)) + } +} + +/// Given a list of highlight sections defined by start/end indices and a string, produce a properly +/// highlighted [`egui::WidgetText`]. +pub fn format_matching_text( + ctx: &egui::Context, + text: &str, + match_iter: impl Iterator>, +) -> egui::WidgetText { + let mut current = 0; + let mut job = egui::text::LayoutJob::default(); + + for Range { start, end } in match_iter { + if current < start { + job.append( + &text[current..start], + 0.0, + egui::TextFormat { + font_id: egui::TextStyle::Body.resolve(&ctx.style()), + color: Color32::PLACEHOLDER, + ..Default::default() + }, + ); + } + + job.append( + &text[start..end], + 0.0, + egui::TextFormat { + font_id: egui::TextStyle::Body.resolve(&ctx.style()), + color: Color32::PLACEHOLDER, + background: ctx.style().visuals.selection.bg_fill, + ..Default::default() + }, + ); + + current = end; + } + + if current < text.len() { + job.append( + &text[current..], + 0.0, + egui::TextFormat { + font_id: egui::TextStyle::Body.resolve(&ctx.style()), + color: Color32::PLACEHOLDER, + ..Default::default() + }, + ); + } + + job.into() +} diff --git a/crates/viewer/re_ui/src/icons.rs b/crates/viewer/re_ui/src/icons.rs index 11c2d8c3ff42..f012e7f98a9b 100644 --- a/crates/viewer/re_ui/src/icons.rs +++ b/crates/viewer/re_ui/src/icons.rs @@ -136,3 +136,5 @@ pub const DND_MOVE: Icon = icon_from_path!("../data/icons/dnd_move.png"); /// `>` pub const BREADCRUMBS_SEPARATOR: Icon = icon_from_path!("../data/icons/breadcrumbs_separator.png"); + +pub const SEARCH: Icon = icon_from_path!("../data/icons/search.png"); diff --git a/crates/viewer/re_ui/src/lib.rs b/crates/viewer/re_ui/src/lib.rs index 6db79998d1dc..d41c88322d06 100644 --- a/crates/viewer/re_ui/src/lib.rs +++ b/crates/viewer/re_ui/src/lib.rs @@ -6,6 +6,7 @@ mod command_palette; mod context_ext; mod design_tokens; pub mod drag_and_drop; +pub mod filter_widget; pub mod icons; pub mod list_item; mod markdown_utils; diff --git a/crates/viewer/re_ui/tests/filter_widget_test.rs b/crates/viewer/re_ui/tests/filter_widget_test.rs new file mode 100644 index 000000000000..2b4909eb39b9 --- /dev/null +++ b/crates/viewer/re_ui/tests/filter_widget_test.rs @@ -0,0 +1,36 @@ +use egui::Vec2; + +use re_ui::filter_widget::FilterState; + +#[test] +pub fn test_filter_widget() { + let test_code = |ui: &mut egui::Ui| { + ui.set_width(100.0); + ui.set_max_width(100.0); + + FilterState::default().ui(ui, egui::RichText::new("Small").strong()); + + FilterState::default().ui( + ui, + egui::RichText::new("Expanding available width").strong(), + ); + + ui.set_width(600.0); + ui.set_max_width(600.0); + FilterState::default().ui(ui, egui::RichText::new("Lots of space").strong()); + }; + + let mut harness = egui_kittest::Harness::builder() + .with_size(Vec2::new(700.0, 150.0)) + .build(|ctx| { + egui::SidePanel::right("right_panel").show(ctx, |ui| { + re_ui::apply_style_and_install_loaders(ui.ctx()); + + test_code(ui); + }); + }); + + harness.run(); + + harness.snapshot("filter_widget"); +} diff --git a/crates/viewer/re_ui/tests/snapshots/filter_widget.png b/crates/viewer/re_ui/tests/snapshots/filter_widget.png new file mode 100644 index 000000000000..d6a3bc390738 --- /dev/null +++ b/crates/viewer/re_ui/tests/snapshots/filter_widget.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73136b6632393d094da0165a6983c42068275c6b92bc69030c0bfb081db4ce64 +size 10226 From 7ddc4807b10bc6340af20413c6dced6c084da810 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:42:16 +0100 Subject: [PATCH 19/57] Filter entities in the UI (part 2): Introduce entity filtering in the time panel (#8654) Co-authored-by: Andreas Reich --- Cargo.lock | 1 - .../src/actions/collapse_expand_all.rs | 27 ++- crates/viewer/re_time_panel/Cargo.toml | 3 +- crates/viewer/re_time_panel/src/lib.rs | 170 +++++++++++++----- .../tests/snapshots/time_panel_dense_data.png | 4 +- .../snapshots/time_panel_two_sections.png | 4 +- .../re_viewer_context/src/collapsed_id.rs | 6 + .../re_viewer_context/src/selection_state.rs | 2 + 8 files changed, 167 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2dcf6f327137..b6db2dfeb715 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6428,7 +6428,6 @@ dependencies = [ "anyhow", "criterion", "egui", - "egui_kittest", "itertools 0.13.0", "nohash-hasher", "once_cell", diff --git a/crates/viewer/re_context_menu/src/actions/collapse_expand_all.rs b/crates/viewer/re_context_menu/src/actions/collapse_expand_all.rs index 700c804e62e8..e92c6d11fa32 100644 --- a/crates/viewer/re_context_menu/src/actions/collapse_expand_all.rs +++ b/crates/viewer/re_context_menu/src/actions/collapse_expand_all.rs @@ -100,24 +100,43 @@ impl ContextMenuAction for CollapseExpandAllAction { } fn process_instance_path(&self, ctx: &ContextMenuContext<'_>, instance_path: &InstancePath) { - #[expect(clippy::match_same_arms)] let (db, scope) = match ctx .selection .context_for_item(&Item::InstancePath(instance_path.clone())) { + Some(&ItemContext::StreamsTree { + store_kind: StoreKind::Recording, + filter_session_id: None, + }) => (ctx.viewer_context.recording(), CollapseScope::StreamsTree), + + Some(&ItemContext::StreamsTree { + store_kind: StoreKind::Recording, + filter_session_id: Some(session_id), + }) => ( + ctx.viewer_context.recording(), + CollapseScope::StreamsTreeFiltered { session_id }, + ), + Some(&ItemContext::StreamsTree { store_kind: StoreKind::Blueprint, + filter_session_id: None, }) => ( ctx.viewer_context.blueprint_db(), CollapseScope::BlueprintStreamsTree, ), Some(&ItemContext::StreamsTree { - store_kind: StoreKind::Recording, - }) => (ctx.viewer_context.recording(), CollapseScope::StreamsTree), + store_kind: StoreKind::Blueprint, + filter_session_id: Some(session_id), + }) => ( + ctx.viewer_context.blueprint_db(), + CollapseScope::BlueprintStreamsTreeFiltered { session_id }, + ), // default to recording if we don't have more specific information - _ => (ctx.viewer_context.recording(), CollapseScope::StreamsTree), + Some(&ItemContext::TwoD { .. } | &ItemContext::ThreeD { .. }) | None => { + (ctx.viewer_context.recording(), CollapseScope::StreamsTree) + } }; let Some(subtree) = db.tree().subtree(&instance_path.entity_path) else { diff --git a/crates/viewer/re_time_panel/Cargo.toml b/crates/viewer/re_time_panel/Cargo.toml index 307898a5982e..626c8fa8b575 100644 --- a/crates/viewer/re_time_panel/Cargo.toml +++ b/crates/viewer/re_time_panel/Cargo.toml @@ -41,9 +41,10 @@ serde.workspace = true vec1.workspace = true [dev-dependencies] +re_viewer_context = { workspace = true, features = ["testing"] } + anyhow.workspace = true criterion.workspace = true -egui_kittest.workspace = true rand.workspace = true [lib] diff --git a/crates/viewer/re_time_panel/src/lib.rs b/crates/viewer/re_time_panel/src/lib.rs index 00f715e00147..fafc93f5287f 100644 --- a/crates/viewer/re_time_panel/src/lib.rs +++ b/crates/viewer/re_time_panel/src/lib.rs @@ -1,10 +1,10 @@ //! Rerun Time Panel //! -//! This crate provides a panel that shows allows to control time & timelines, -//! as well as all necessary ui elements that make it up. +//! This crate provides a panel that shows all entities in the store and allows control of time and +//! timelines, as well as all necessary ui elements that make it up. // TODO(#6330): remove unwrap() -#![allow(clippy::unwrap_used)] +#![expect(clippy::unwrap_used)] mod data_density_graph; mod paint_ticks; @@ -26,11 +26,11 @@ use re_data_ui::DataUi as _; use re_data_ui::{item_ui::guess_instance_path_icon, sorted_component_list_for_ui}; use re_entity_db::{EntityDb, EntityTree, InstancePath}; use re_log_types::{ - external::re_types_core::ComponentName, ComponentPath, EntityPath, EntityPathPart, + external::re_types_core::ComponentName, ApplicationId, ComponentPath, EntityPath, ResolvedTimeRange, TimeInt, TimeReal, TimeType, }; use re_types::blueprint::components::PanelState; -use re_ui::{list_item, ContextExt as _, DesignTokens, UiExt as _}; +use re_ui::{filter_widget, list_item, ContextExt as _, DesignTokens, UiExt as _}; use re_viewer_context::{ CollapseScope, HoverHighlight, Item, ItemContext, RecordingConfig, TimeControl, TimeView, UiLayout, ViewerContext, @@ -135,8 +135,19 @@ pub struct TimePanel { /// Ui elements for controlling time. time_control_ui: TimeControlUi, - /// Which source is the time panel controlling + /// Which source is the time panel controlling? source: TimePanelSource, + + /// Filtering of entity paths shown in the panel (when expanded). + #[serde(skip)] + filter_state: filter_widget::FilterState, + + /// The store id the filter widget relates to. + /// + /// Used to invalidate the filter state (aka deactivate it) when the user switches to a + /// recording with a different application id. + #[serde(skip)] + filter_state_app_id: Option, } impl Default for TimePanel { @@ -150,6 +161,8 @@ impl Default for TimePanel { time_ranges_ui: Default::default(), time_control_ui: TimeControlUi, source: TimePanelSource::Recording, + filter_state: Default::default(), + filter_state_app_id: None, } } } @@ -185,6 +198,12 @@ impl TimePanel { return; } + // 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(); + self.filter_state_app_id = Some(ctx.store_context.app_id.clone()); + } + self.data_density_graph_painter.begin_frame(ui.ctx()); // Naturally, many parts of the time panel need the time control. @@ -391,7 +410,10 @@ impl TimePanel { // ▲ // └ tree_max_y (= time_x_left) - self.next_col_right = ui.min_rect().left(); // next_col_right will expand during the call + // We use this to track what the rightmost coordinate for the tree section should be. We + // clamp it to a minimum of 150.0px for the filter widget to behave correctly even when the + // tree is fully collapsed (and thus narrow). + self.next_col_right = ui.min_rect().left() + 150.0; let time_x_left = (ui.min_rect().left() + self.prev_col_width + ui.spacing().item_spacing.x) @@ -422,16 +444,27 @@ impl TimePanel { let timeline_rect = { let top = ui.min_rect().bottom(); + ui.add_space(-4.0); // hack to vertically center the text + let size = egui::vec2(self.prev_col_width, 28.0); ui.allocate_ui_with_layout(size, egui::Layout::top_down(egui::Align::LEFT), |ui| { ui.set_min_size(size); ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Extend); - ui.add_space(4.0); // hack to vertically center the text - if self.source == TimePanelSource::Blueprint { - ui.strong("Blueprint Streams"); - } else { - ui.strong("Streams"); - } + ui.spacing_mut().item_spacing.y = 0.0; + + ui.full_span_scope(0.0..=time_x_left, |ui| { + self.filter_state.ui( + ui, + egui::RichText::new(if self.source == TimePanelSource::Blueprint { + "Blueprint Streams" + } else { + "Streams" + }) + .strong(), + ); + }); + + ui.add_space(2.0); // hack to vertically center the text }) .response .on_hover_text( @@ -558,7 +591,7 @@ impl TimePanel { } // All the entity rows and their data density graphs: - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] fn tree_ui( &mut self, ctx: &ViewerContext<'_>, @@ -590,6 +623,8 @@ impl TimePanel { // stores, due to `Item::*` not tracking stores for entity paths. let show_root = self.source == TimePanelSource::Recording; + let filter_matcher = self.filter_state.filter(); + if show_root { self.show_tree( ctx, @@ -598,10 +633,9 @@ impl TimePanel { time_ctrl, time_area_response, time_area_painter, - None, entity_db.tree(), + &filter_matcher, ui, - "/", ); } else { self.show_children( @@ -612,13 +646,14 @@ impl TimePanel { time_area_response, time_area_painter, entity_db.tree(), + &filter_matcher, ui, ); } }); } - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] fn show_tree( &mut self, ctx: &ViewerContext<'_>, @@ -627,30 +662,67 @@ impl TimePanel { time_ctrl: &mut TimeControl, time_area_response: &egui::Response, time_area_painter: &egui::Painter, - last_path_part: Option<&EntityPathPart>, tree: &EntityTree, + filter_matcher: &filter_widget::FilterMatcher, ui: &mut egui::Ui, - show_root_as: &str, ) { + // We traverse and display this tree only if it contains a matching entity part. + 'early_exit: { + if filter_matcher.matches_nothing() { + return; + } + + // Filter is inactive or otherwise whitelisting everything. + if filter_matcher.matches_everything() { + break 'early_exit; + } + + // The current path is a match. + if tree + .path + .iter() + .any(|entity_part| filter_matcher.matches(&entity_part.ui_string())) + { + break 'early_exit; + } + + // Our subtree contains a match. + if tree + .find_first_child_recursive(|entity_path| { + entity_path + .last() + .is_some_and(|entity_part| filter_matcher.matches(&entity_part.ui_string())) + }) + .is_some() + { + break 'early_exit; + } + + // No match to be found, so nothing to display. + return; + } + let db = match self.source { TimePanelSource::Recording => ctx.recording(), TimePanelSource::Blueprint => ctx.store_context.blueprint, }; // The last part of the path component + let last_path_part = tree.path.last(); let text = if let Some(last_path_part) = last_path_part { - let stem = last_path_part.ui_string(); - if tree.is_leaf() { - stem + let part_text = if tree.is_leaf() { + last_path_part.ui_string() } else { - format!("{stem}/") // show we have children with a / - } + format!("{}/", last_path_part.ui_string()) // show we have children with a / + }; + + filter_matcher + .matches_formatted(ui.ctx(), &part_text) + .unwrap_or_else(|| part_text.into()) } else { - show_root_as.to_owned() + "/".into() }; - let default_open = tree.path.len() <= 1 && !tree.is_leaf(); - let item = TimePanelItem::entity_path(tree.path.clone()); let is_selected = ctx.selection().contains_item(&item.to_item()); let is_item_hovered = ctx @@ -658,6 +730,8 @@ impl TimePanel { .highlight_for_ui_element(&item.to_item()) == HoverHighlight::Hovered; + let collapse_scope = self.collapse_scope(); + // expand if children is focused let focused_entity_path = ctx .focused_item @@ -665,19 +739,17 @@ impl TimePanel { .and_then(|item| item.entity_path()); if focused_entity_path.is_some_and(|entity_path| entity_path.is_descendant_of(&tree.path)) { - CollapseScope::StreamsTree + collapse_scope .entity(tree.path.clone()) .set_open(ui.ctx(), true); } - // 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(match self.source { - TimePanelSource::Recording => CollapseScope::StreamsTree.entity(tree.path.clone()), - TimePanelSource::Blueprint => { - CollapseScope::BlueprintStreamsTree.entity(tree.path.clone()) - } - }); + // Globally unique id that is dependent on the "nature" of the tree (recording or blueprint, + // in a filter session or not) + let id = collapse_scope.entity(tree.path.clone()).into(); + + let is_short_path = tree.path.len() <= 1 && !tree.is_leaf(); + let default_open = self.filter_state.session_id().is_some() || is_short_path; let list_item::ShowCollapsingResponse { item_response: response, @@ -707,6 +779,7 @@ impl TimePanel { time_area_response, time_area_painter, tree, + filter_matcher, ui, ); }, @@ -740,6 +813,7 @@ impl TimePanel { // expand/collapse context menu actions need this information ItemContext::StreamsTree { store_kind: self.source.into(), + filter_session_id: self.filter_state.session_id(), }, &response, SelectionUpdateBehavior::UseSelection, @@ -790,7 +864,7 @@ impl TimePanel { } } - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] fn show_children( &mut self, ctx: &ViewerContext<'_>, @@ -800,9 +874,10 @@ impl TimePanel { time_area_response: &egui::Response, time_area_painter: &egui::Painter, tree: &EntityTree, + filter_matcher: &filter_widget::FilterMatcher, ui: &mut egui::Ui, ) { - for (last_component, child) in &tree.children { + for child in tree.children.values() { self.show_tree( ctx, viewport_blueprint, @@ -810,10 +885,9 @@ impl TimePanel { time_ctrl, time_area_response, time_area_painter, - Some(last_component), child, + filter_matcher, ui, - "/", ); } @@ -1017,6 +1091,22 @@ impl TimePanel { }); } } + + fn collapse_scope(&self) -> CollapseScope { + match (self.source, self.filter_state.session_id()) { + (TimePanelSource::Recording, None) => CollapseScope::StreamsTree, + + (TimePanelSource::Blueprint, None) => CollapseScope::BlueprintStreamsTree, + + (TimePanelSource::Recording, Some(session_id)) => { + CollapseScope::StreamsTreeFiltered { session_id } + } + + (TimePanelSource::Blueprint, Some(session_id)) => { + CollapseScope::BlueprintStreamsTreeFiltered { session_id } + } + } + } } /// Draw the hovered/selected highlight background for a timeline row. diff --git a/crates/viewer/re_time_panel/tests/snapshots/time_panel_dense_data.png b/crates/viewer/re_time_panel/tests/snapshots/time_panel_dense_data.png index 0afc9600de09..2d30e99a20b8 100644 --- a/crates/viewer/re_time_panel/tests/snapshots/time_panel_dense_data.png +++ b/crates/viewer/re_time_panel/tests/snapshots/time_panel_dense_data.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f1ef5ede53c243b9d9986f4a502f3b232da202815a24a325bab737b07a69e64e -size 27223 +oid sha256:da37f484f89f6e385fadfc6ffcbd8d4119dcbc6236bf5f91d16cc711074d5189 +size 25965 diff --git a/crates/viewer/re_time_panel/tests/snapshots/time_panel_two_sections.png b/crates/viewer/re_time_panel/tests/snapshots/time_panel_two_sections.png index 857e28cef367..ef2c4cc7a969 100644 --- a/crates/viewer/re_time_panel/tests/snapshots/time_panel_two_sections.png +++ b/crates/viewer/re_time_panel/tests/snapshots/time_panel_two_sections.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:877df4e6bc5be8caa89fb5e721e32527701260ba249fa8313cb78d7828573be9 -size 32092 +oid sha256:7e2086ecac13e41e291aa7780e006faf05a9cc9e9f26c3410f67af152603c963 +size 32001 diff --git a/crates/viewer/re_viewer_context/src/collapsed_id.rs b/crates/viewer/re_viewer_context/src/collapsed_id.rs index 9358c8ddc5cc..2eec7eb4c3d2 100644 --- a/crates/viewer/re_viewer_context/src/collapsed_id.rs +++ b/crates/viewer/re_viewer_context/src/collapsed_id.rs @@ -14,9 +14,15 @@ pub enum CollapseScope { /// Stream tree from the time panel StreamsTree, + /// Stream tree from the time panel, when the filter is active + StreamsTreeFiltered { session_id: egui::Id }, + /// The stream tree from the blueprint debug time panel BlueprintStreamsTree, + /// The stream tree from the blueprint debug time panel, when the filter is active + BlueprintStreamsTreeFiltered { session_id: egui::Id }, + /// Blueprint tree from the blueprint panel (left panel) BlueprintTree, } diff --git a/crates/viewer/re_viewer_context/src/selection_state.rs b/crates/viewer/re_viewer_context/src/selection_state.rs index 4f60c4bfeaad..14c9009370aa 100644 --- a/crates/viewer/re_viewer_context/src/selection_state.rs +++ b/crates/viewer/re_viewer_context/src/selection_state.rs @@ -40,6 +40,8 @@ pub enum ItemContext { StreamsTree { /// Which store does this streams tree correspond to? store_kind: StoreKind, + + filter_session_id: Option, }, } From d99df0145453b69032ec7c4beb5e1c62a18df251 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Mon, 13 Jan 2025 18:35:11 +0100 Subject: [PATCH 20/57] Update to flatbuffers 24 (#8670) In order to avoid duplicated versions when we start using `arrow_ipc` --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6db2dfeb715..ed5203113c31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2476,9 +2476,9 @@ checksum = "c1671b620ba6e60c11c62b0ea5fec4f8621991e7b1229fa13c010a2cd04e4342" [[package]] name = "flatbuffers" -version = "23.5.26" +version = "24.12.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dac53e22462d78c16d64a1cd22371b54cc3fe94aa15e7886a2fa6e5d1ab8640" +checksum = "4f1baf0dbf96932ec9a3038d57900329c015b0bfb7b63d904f3bc27e2b02a096" dependencies = [ "bitflags 1.3.2", "rustc_version", diff --git a/Cargo.toml b/Cargo.toml index 7f5ca6092ce4..85b4d748085e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -184,7 +184,7 @@ env_logger = { version = "0.10", default-features = false } ffmpeg-sidecar = { version = "2.0.2", default-features = false } fixed = { version = "1.28", default-features = false } fjadra = "0.2.1" -flatbuffers = "23.0" +flatbuffers = "24.12.23" futures-channel = "0.3" futures-util = { version = "0.3", default-features = false } getrandom = "0.2" From 74c4f7f8aa456fc356436f710cdbfbfad57a3b09 Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Tue, 14 Jan 2025 09:03:42 +0100 Subject: [PATCH 21/57] Fix: rename `depends_on` to `depends-on` in `pixi.toml` (#8667) --- pixi.toml | 64 +++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/pixi.toml b/pixi.toml index 72217e1239c9..aeefdea6dacf 100644 --- a/pixi.toml +++ b/pixi.toml @@ -150,12 +150,12 @@ rerun-build-release = "cargo build --package rerun-cli --release --no-default-fe rerun-release = "cargo run --package rerun-cli --no-default-features --features grpc,map_view,nasm,native_viewer --release --" # Compile `rerun-cli` with the same feature set as we build for releases. -rerun-build-native-and-web = { cmd = "cargo build --package rerun-cli --no-default-features --features release --", depends_on = [ +rerun-build-native-and-web = { cmd = "cargo build --package rerun-cli --no-default-features --features release --", depends-on = [ "rerun-build-web", ] } # Compile `rerun-cli` with the same feature set as we build for releases. -rerun-build-native-and-web-release = { cmd = "cargo build --package rerun-cli --no-default-features --features release --release --", depends_on = [ +rerun-build-native-and-web-release = { cmd = "cargo build --package rerun-cli --no-default-features --features release --release --", depends-on = [ "rerun-build-web-release", ] } @@ -165,7 +165,7 @@ rerun-build-native-and-web-release = { cmd = "cargo build --package rerun-cli -- # # This installs the `wasm32-unknown-unknown` rust target if it's not already installed. # (this looks heavy but takes typically below 0.1s!) -rerun-web = { cmd = "cargo run --package rerun-cli --no-default-features --features web_viewer -- --web-viewer", depends_on = [ +rerun-web = { cmd = "cargo run --package rerun-cli --no-default-features --features web_viewer -- --web-viewer", depends-on = [ "rerun-build-web", ] } @@ -187,7 +187,7 @@ rerun-build-web-cli = "rustup target add wasm32-unknown-unknown && cargo run -p # # This installs the `wasm32-unknown-unknown` rust target if it's not already installed. # (this looks heavy but takes typically below 0.1s!) -rerun-web-release = { cmd = "cargo run --package rerun-cli --no-default-features --features web_viewer,map_view,grpc --release -- --web-viewer", depends_on = [ +rerun-web-release = { cmd = "cargo run --package rerun-cli --no-default-features --features web_viewer,map_view,grpc --release -- --web-viewer", depends-on = [ "rerun-build-web-release", ] } @@ -197,21 +197,21 @@ rerun-web-release = { cmd = "cargo run --package rerun-cli --no-default-features # (this looks heavy but takes typically below 0.1s!) rerun-build-web-release = "rustup target add wasm32-unknown-unknown && cargo run -p re_dev_tools -- build-web-viewer --no-default-features --features analytics,grpc,map_view --release -g" -rs-check = { cmd = "rustup target add wasm32-unknown-unknown && python scripts/ci/rust_checks.py", depends_on = [ +rs-check = { cmd = "rustup target add wasm32-unknown-unknown && python scripts/ci/rust_checks.py", depends-on = [ "rerun-build-web", # The checks require the web viewer wasm to be around. ] } rs-fmt = "cargo fmt --all" # Code formatting for all languages. -format = { depends_on = [ +format = { depends-on = [ "py-fmt", "cpp-fmt", "rs-fmt", "toml-fmt", "misc-fmt", ] } -fmt = { depends_on = ["format"] } +fmt = { depends-on = ["format"] } # Assorted linting tasks fast-lint = "python scripts/fast_lint.py" @@ -277,13 +277,13 @@ mdlint = "python scripts/ci/mdlint.py" js-setup = "npm i -g yarn" # Install JS package dependencies -js-install = { cmd = "yarn install --cwd rerun_js", depends_on = ["js-setup"] } +js-install = { cmd = "yarn install --cwd rerun_js", depends-on = ["js-setup"] } # Build JS packages -js-build-base = { cmd = "yarn --cwd rerun_js/web-viewer run build", depends_on = [ +js-build-base = { cmd = "yarn --cwd rerun_js/web-viewer run build", depends-on = [ "js-install", ] } -js-build-all = { cmd = "yarn --cwd rerun_js workspaces run build", depends_on = [ +js-build-all = { cmd = "yarn --cwd rerun_js workspaces run build", depends-on = [ "js-install", ] } @@ -298,27 +298,27 @@ js-build-all = { cmd = "yarn --cwd rerun_js workspaces run build", depends_on = # configured to not install outside venv (which is a good practice). PIP_REQUIRE_VIRTUALENV=0 disables this check. # - RERUN_ALLOW_MISSING_BIN is needed to allow maturin to run without the `rerun` binary being part of the rerun-sdk # package. -py-build-common = { cmd = "PIP_REQUIRE_VIRTUALENV=0 RERUN_ALLOW_MISSING_BIN=1 maturin develop --manifest-path rerun_py/Cargo.toml --extras=tests", depends_on = [ +py-build-common = { cmd = "PIP_REQUIRE_VIRTUALENV=0 RERUN_ALLOW_MISSING_BIN=1 maturin develop --manifest-path rerun_py/Cargo.toml --extras=tests", depends-on = [ "rerun-build", # We need to build rerun-cli since it is bundled in the python package. ] } -py-build-common-release = { cmd = "PIP_REQUIRE_VIRTUALENV=0 RERUN_ALLOW_MISSING_BIN=1 maturin develop --release --manifest-path rerun_py/Cargo.toml --extras=tests", depends_on = [ +py-build-common-release = { cmd = "PIP_REQUIRE_VIRTUALENV=0 RERUN_ALLOW_MISSING_BIN=1 maturin develop --release --manifest-path rerun_py/Cargo.toml --extras=tests", depends-on = [ "rerun-build-release", # We need to build rerun-cli since it is bundled in the python package. ] } # Build and install the `rerun-sdk` package with the `web_viewer` feature. -py-build-common-web-viewer = { cmd = "PIP_REQUIRE_VIRTUALENV=0 RERUN_ALLOW_MISSING_BIN=1 maturin develop --manifest-path rerun_py/Cargo.toml --features web_viewer,nasm --extras=tests", depends_on = [ +py-build-common-web-viewer = { cmd = "PIP_REQUIRE_VIRTUALENV=0 RERUN_ALLOW_MISSING_BIN=1 maturin develop --manifest-path rerun_py/Cargo.toml --features web_viewer,nasm --extras=tests", depends-on = [ "rerun-build-native-and-web", # We need to build rerun-cli since it is bundled in the python package. ] } # Build and install the `rerun-sdk` package with the `web_viewer` feature. -py-build-common-web-viewer-release = { cmd = "PIP_REQUIRE_VIRTUALENV=0 RERUN_ALLOW_MISSING_BIN=1 maturin develop --release --manifest-path rerun_py/Cargo.toml --features web_viewer,nasm --extras=tests", depends_on = [ +py-build-common-web-viewer-release = { cmd = "PIP_REQUIRE_VIRTUALENV=0 RERUN_ALLOW_MISSING_BIN=1 maturin develop --release --manifest-path rerun_py/Cargo.toml --features web_viewer,nasm --extras=tests", depends-on = [ "rerun-build-native-and-web-release", # We need to build rerun-cli since it is bundled in the python package. ] } # Build the `rerun-notebook` package. -py-build-notebook = { cmd = "pip install -e rerun_notebook", depends_on = [ +py-build-notebook = { cmd = "pip install -e rerun_notebook", depends-on = [ "js-build-base", ] } @@ -340,17 +340,17 @@ py-check-signatures = "python scripts/ci/python_check_signatures.py" # Helper alias to run the python interpreter in the context of the python environment rrpy = "python" -py-bench = { cmd = "python -m pytest -c rerun_py/pyproject.toml --benchmark-only", depends_on = [ +py-bench = { cmd = "python -m pytest -c rerun_py/pyproject.toml --benchmark-only", depends-on = [ "py-build-release", ] } -py-plot-dashboard = { cmd = "python tests/python/plot_dashboard_stress/main.py", depends_on = [ +py-plot-dashboard = { cmd = "python tests/python/plot_dashboard_stress/main.py", depends-on = [ "py-build", ] } # Run the Python tests. -py-test = { cmd = "python -m pytest -vv rerun_py/tests/unit", depends_on = [ +py-test = { cmd = "python -m pytest -vv rerun_py/tests/unit", depends-on = [ "py-build", ] } @@ -374,10 +374,10 @@ rerun-from-path = "rerun" py-build-examples = "pixi run -e examples py-build-common" # Python example utilities -py-run-all-examples = { cmd = "python scripts/run_all.py --skip-build", depends_on = [ +py-run-all-examples = { cmd = "python scripts/run_all.py --skip-build", depends-on = [ "py-build-examples", ] } -py-run-all-examples-web = { cmd = "python scripts/run_all.py --web --skip-build", depends_on = [ +py-run-all-examples-web = { cmd = "python scripts/run_all.py --web --skip-build", depends-on = [ "rerun-build-web-cli", "py-build-examples", ] } @@ -386,42 +386,42 @@ py-run-all-examples-web = { cmd = "python scripts/run_all.py --web --skip-build" # All the cpp-* tasks can be configured with environment variables, e.g.: RERUN_WERROR=ON CXX=clang++ cpp-prepare-release = "cmake -G 'Ninja' -B build/release -S . -DCMAKE_BUILD_TYPE=Release" cpp-prepare = "cmake -G 'Ninja' -B build/debug -S . -DCMAKE_BUILD_TYPE=Debug" -cpp-build-all = { cmd = "cmake --build build/debug --config Debug --target ALL", depends_on = [ +cpp-build-all = { cmd = "cmake --build build/debug --config Debug --target ALL", depends-on = [ "cpp-prepare", ] } cpp-prepare-shared-libs = "cmake -G 'Ninja' -B build/debug -S . -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=ON" -cpp-build-all-shared-libs = { cmd = "cmake --build build/debug --config Debug --target ALL", depends_on = [ +cpp-build-all-shared-libs = { cmd = "cmake --build build/debug --config Debug --target ALL", depends-on = [ "cpp-prepare-shared-libs", ] } cpp-clean = "rm -rf build CMakeCache.txt CMakeFiles" -cpp-build-tests = { cmd = "cmake --build build/debug --config Debug --target rerun_sdk_tests", depends_on = [ +cpp-build-tests = { cmd = "cmake --build build/debug --config Debug --target rerun_sdk_tests", depends-on = [ "cpp-prepare", ] } -cpp-build-roundtrips = { cmd = "cmake --build build/debug --config Debug --target roundtrips", depends_on = [ +cpp-build-roundtrips = { cmd = "cmake --build build/debug --config Debug --target roundtrips", depends-on = [ "cpp-prepare", ] } -cpp-build-examples = { cmd = "cmake --build build/debug --config Debug --target examples", depends_on = [ +cpp-build-examples = { cmd = "cmake --build build/debug --config Debug --target examples", depends-on = [ "cpp-prepare", ] } -cpp-build-snippets = { cmd = "cmake --build build/debug --config Debug --target snippets", depends_on = [ +cpp-build-snippets = { cmd = "cmake --build build/debug --config Debug --target snippets", depends-on = [ "cpp-prepare", ] } -cpp-build-log-benchmark = { cmd = "cmake --build build/release --config Release --target log_benchmark", depends_on = [ +cpp-build-log-benchmark = { cmd = "cmake --build build/release --config Release --target log_benchmark", depends-on = [ "cpp-prepare-release", ] } -cpp-build-plot-dashboard-stress = { cmd = "cmake --build build/release --config Release --target plot_dashboard_stress", depends_on = [ +cpp-build-plot-dashboard-stress = { cmd = "cmake --build build/release --config Release --target plot_dashboard_stress", depends-on = [ "cpp-prepare-release", ] } -cpp-test = { cmd = "export RERUN_STRICT=1 && ./build/debug/rerun_cpp/tests/rerun_sdk_tests", depends_on = [ +cpp-test = { cmd = "export RERUN_STRICT=1 && ./build/debug/rerun_cpp/tests/rerun_sdk_tests", depends-on = [ "cpp-build-tests", ] } -cpp-log-benchmark = { cmd = "export RERUN_STRICT=1 && ./build/release/tests/cpp/log_benchmark/log_benchmark", depends_on = [ +cpp-log-benchmark = { cmd = "export RERUN_STRICT=1 && ./build/release/tests/cpp/log_benchmark/log_benchmark", depends-on = [ "cpp-build-log-benchmark", ] } -cpp-plot-dashboard = { cmd = "export RERUN_STRICT=1 && ./build/release/tests/cpp/plot_dashboard_stress/plot_dashboard_stress", depends_on = [ +cpp-plot-dashboard = { cmd = "export RERUN_STRICT=1 && ./build/release/tests/cpp/plot_dashboard_stress/plot_dashboard_stress", depends-on = [ "cpp-build-plot-dashboard-stress", ] } -cpp-build-and-test-all = { depends_on = ["cpp-build-all", "cpp-test"] } +cpp-build-and-test-all = { depends-on = ["cpp-build-all", "cpp-test"] } cpp-docs = { cmd = "doxygen docs/Doxyfile && echo '***************\nSuccess!\nOpen ./rerun_cpp/docs/html/index.html in your browser.'", cwd = "rerun_cpp" } cpp-fmt = "fd --extension h --extension hpp --extension c --extension cpp --exec clang-format -i" From 1ffe5862a912fea313d420f97d421ab23cf9c77a Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 14 Jan 2025 09:55:51 +0100 Subject: [PATCH 22/57] Refactor `TimeColumnDescriptor` (#8658) * Part of #3741 --- crates/store/re_chunk_store/src/dataframe.rs | 59 +++++-- crates/store/re_dataframe/src/query.rs | 149 ++++++++---------- .../re_view_dataframe/src/dataframe_ui.rs | 36 ++--- .../src/display_record_batch.rs | 2 +- .../src/view_query/blueprint.rs | 4 +- .../re_view_dataframe/src/view_query/ui.rs | 2 +- rerun_py/src/dataframe.rs | 6 +- 7 files changed, 135 insertions(+), 123 deletions(-) diff --git a/crates/store/re_chunk_store/src/dataframe.rs b/crates/store/re_chunk_store/src/dataframe.rs index 0297f77225ed..95b70a779ecc 100644 --- a/crates/store/re_chunk_store/src/dataframe.rs +++ b/crates/store/re_chunk_store/src/dataframe.rs @@ -4,6 +4,7 @@ use std::collections::{BTreeMap, BTreeSet}; use std::ops::Deref; use std::ops::DerefMut; +use arrow::datatypes::DataType as ArrowDatatype; use arrow2::{ array::ListArray as ArrowListArray, datatypes::{DataType as Arrow2Datatype, Field as Arrow2Field}, @@ -45,7 +46,7 @@ impl ColumnDescriptor { #[inline] pub fn datatype(&self) -> Arrow2Datatype { match self { - Self::Time(descr) => descr.datatype.clone(), + Self::Time(descr) => descr.datatype().into(), Self::Component(descr) => descr.returned_datatype(), } } @@ -79,10 +80,9 @@ impl ColumnDescriptor { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct TimeColumnDescriptor { /// The timeline this column is associated with. - pub timeline: Timeline, + timeline: Timeline, - /// The Arrow datatype of the column. - pub datatype: Arrow2Datatype, + is_null: bool, } impl PartialOrd for TimeColumnDescriptor { @@ -97,17 +97,49 @@ impl Ord for TimeColumnDescriptor { fn cmp(&self, other: &Self) -> std::cmp::Ordering { let Self { timeline, - datatype: _, + is_null: _, } = self; timeline.cmp(&other.timeline) } } impl TimeColumnDescriptor { + /// Used when returning a null column, i.e. when a lookup failed. + pub fn new_null(name: TimelineName) -> Self { + Self { + // TODO(cmc): I picked a sequence here because I have to pick something. + // It doesn't matter, only the name will remain in the Arrow schema anyhow. + timeline: Timeline::new_sequence(name), + is_null: true, + } + } + + pub fn timeline(&self) -> Timeline { + self.timeline + } + + pub fn name(&self) -> &TimelineName { + self.timeline.name() + } + + pub fn typ(&self) -> re_log_types::TimeType { + self.timeline.typ() + } + + #[inline] + pub fn datatype(&self) -> ArrowDatatype { + let Self { timeline, is_null } = self; + if *is_null { + ArrowDatatype::Null + } else { + timeline.typ().datatype() + } + } + fn metadata(&self) -> arrow2::datatypes::Metadata { let Self { timeline, - datatype: _, + is_null: _, } = self; std::iter::once(Some(( @@ -119,15 +151,10 @@ impl TimeColumnDescriptor { } #[inline] - // Time column must be nullable since static data doesn't have a time. pub fn to_arrow_field(&self) -> Arrow2Field { - let Self { timeline, datatype } = self; - Arrow2Field::new( - timeline.name().to_string(), - datatype.clone(), - true, /* nullable */ - ) - .with_metadata(self.metadata()) + let nullable = true; // Time column must be nullable since static data doesn't have a time. + Arrow2Field::new(self.name().to_string(), self.datatype().into(), nullable) + .with_metadata(self.metadata()) } } @@ -708,7 +735,7 @@ impl ChunkStore { let timelines = self.all_timelines_sorted().into_iter().map(|timeline| { ColumnDescriptor::Time(TimeColumnDescriptor { timeline, - datatype: timeline.datatype().into(), + is_null: false, }) }); @@ -782,7 +809,7 @@ impl ChunkStore { TimeColumnDescriptor { timeline, - datatype: timeline.datatype().into(), + is_null: false, } } diff --git a/crates/store/re_dataframe/src/query.rs b/crates/store/re_dataframe/src/query.rs index 92481b4c3958..8a1f76e2ce00 100644 --- a/crates/store/re_dataframe/src/query.rs +++ b/crates/store/re_dataframe/src/query.rs @@ -373,82 +373,73 @@ impl QueryHandle { ) -> Vec<(usize, ColumnDescriptor)> { selection .iter() - .map(|column| { - match column { - ColumnSelector::Time(selected_column) => { - let TimeColumnSelector { - timeline: selected_timeline, - } = selected_column; - - view_contents - .iter() - .enumerate() - .filter_map(|(idx, view_column)| match view_column { - ColumnDescriptor::Time(view_descr) => Some((idx, view_descr)), - ColumnDescriptor::Component(_) => None, - }) - .find(|(_idx, view_descr)| { - *view_descr.timeline.name() == *selected_timeline - }) - .map_or_else( - || { - ( - usize::MAX, - ColumnDescriptor::Time(TimeColumnDescriptor { - // TODO(cmc): I picked a sequence here because I have to pick something. - // It doesn't matter, only the name will remain in the Arrow schema anyhow. - timeline: Timeline::new_sequence(*selected_timeline), - datatype: arrow2::datatypes::DataType::Null, - }), - ) - }, - |(idx, view_descr)| { - (idx, ColumnDescriptor::Time(view_descr.clone())) - }, - ) - } + .map(|column| match column { + ColumnSelector::Time(selected_column) => { + let TimeColumnSelector { + timeline: selected_timeline, + } = selected_column; + + view_contents + .iter() + .enumerate() + .filter_map(|(idx, view_column)| match view_column { + ColumnDescriptor::Time(view_descr) => Some((idx, view_descr)), + ColumnDescriptor::Component(_) => None, + }) + .find(|(_idx, view_descr)| *view_descr.name() == *selected_timeline) + .map_or_else( + || { + ( + usize::MAX, + ColumnDescriptor::Time(TimeColumnDescriptor::new_null( + *selected_timeline, + )), + ) + }, + |(idx, view_descr)| (idx, ColumnDescriptor::Time(view_descr.clone())), + ) + } - ColumnSelector::Component(selected_column) => { - let ComponentColumnSelector { - entity_path: selected_entity_path, - component_name: selected_component_name, - } = selected_column; - - view_contents - .iter() - .enumerate() - .filter_map(|(idx, view_column)| match view_column { - ColumnDescriptor::Component(view_descr) => Some((idx, view_descr)), - ColumnDescriptor::Time(_) => None, - }) - .find(|(_idx, view_descr)| { - view_descr.entity_path == *selected_entity_path - && view_descr.component_name.matches(selected_component_name) - }) - .map_or_else( - || { - ( - usize::MAX, - ColumnDescriptor::Component(ComponentColumnDescriptor { - entity_path: selected_entity_path.clone(), - archetype_name: None, - archetype_field_name: None, - component_name: ComponentName::from( - selected_component_name.clone(), - ), - store_datatype: arrow2::datatypes::DataType::Null, - is_static: false, - is_indicator: false, - is_tombstone: false, - is_semantically_empty: false, - }), - ) - }, - |(idx, view_descr)| { - (idx, ColumnDescriptor::Component(view_descr.clone())) - }, - ) - } + ColumnSelector::Component(selected_column) => { + let ComponentColumnSelector { + entity_path: selected_entity_path, + component_name: selected_component_name, + } = selected_column; + + view_contents + .iter() + .enumerate() + .filter_map(|(idx, view_column)| match view_column { + ColumnDescriptor::Component(view_descr) => Some((idx, view_descr)), + ColumnDescriptor::Time(_) => None, + }) + .find(|(_idx, view_descr)| { + view_descr.entity_path == *selected_entity_path + && view_descr.component_name.matches(selected_component_name) + }) + .map_or_else( + || { + ( + usize::MAX, + ColumnDescriptor::Component(ComponentColumnDescriptor { + entity_path: selected_entity_path.clone(), + archetype_name: None, + archetype_field_name: None, + component_name: ComponentName::from( + selected_component_name.clone(), + ), + store_datatype: arrow2::datatypes::DataType::Null, + is_static: false, + is_indicator: false, + is_tombstone: false, + is_semantically_empty: false, + }), + ) + }, + |(idx, view_descr)| { + (idx, ColumnDescriptor::Component(view_descr.clone())) + }, + ) } }) .collect_vec() @@ -1248,14 +1239,10 @@ impl QueryHandle { .iter() .map(|(view_idx, column)| match column { ColumnDescriptor::Time(descr) => { - max_value_per_index.get(&descr.timeline).map_or_else( + max_value_per_index.get(&descr.timeline()).map_or_else( || arrow2::array::new_null_array(column.datatype(), 1), |(_time, time_sliced)| { - descr - .timeline - .typ() - .make_arrow_array(time_sliced.clone()) - .into() + descr.typ().make_arrow_array(time_sliced.clone()).into() }, ) } diff --git a/crates/viewer/re_view_dataframe/src/dataframe_ui.rs b/crates/viewer/re_view_dataframe/src/dataframe_ui.rs index 79c060191eb7..ecc7cffc835b 100644 --- a/crates/viewer/re_view_dataframe/src/dataframe_ui.rs +++ b/crates/viewer/re_view_dataframe/src/dataframe_ui.rs @@ -166,7 +166,7 @@ impl RowsDisplayData { .iter() .find_position(|desc| match desc { ColumnDescriptor::Time(time_column_desc) => { - &time_column_desc.timeline == query_timeline + &time_column_desc.timeline() == query_timeline } ColumnDescriptor::Component(_) => false, }) @@ -283,29 +283,27 @@ impl egui_table::TableDelegate for DataframeTableDelegate<'_> { .unwrap_or_else(|| Timeline::new("", TimeType::Sequence)); // if this column can actually be hidden, then that's the corresponding action - let hide_action = match column { - ColumnDescriptor::Time(desc) => { - (desc.timeline != filtered_index).then(|| { - HideColumnAction::HideTimeColumn { - timeline_name: *desc.timeline.name(), - } - }) - } - - ColumnDescriptor::Component(desc) => { - Some(HideColumnAction::HideComponentColumn { - entity_path: desc.entity_path.clone(), - component_name: desc.component_name, - }) - } - }; + let hide_action = + match column { + ColumnDescriptor::Time(desc) => (desc.timeline() != filtered_index) + .then(|| HideColumnAction::HideTimeColumn { + timeline_name: *desc.name(), + }), + + ColumnDescriptor::Component(desc) => { + Some(HideColumnAction::HideComponentColumn { + entity_path: desc.entity_path.clone(), + component_name: desc.component_name, + }) + } + }; let header_ui = |ui: &mut egui::Ui| { let text = egui::RichText::new(column.short_name()).strong(); let is_selected = match column { ColumnDescriptor::Time(descr) => { - &descr.timeline == self.ctx.rec_cfg.time_ctrl.read().timeline() + &descr.timeline() == self.ctx.rec_cfg.time_ctrl.read().timeline() } ColumnDescriptor::Component(component_column_descriptor) => self .ctx @@ -323,7 +321,7 @@ impl egui_table::TableDelegate for DataframeTableDelegate<'_> { self.ctx.command_sender.send_system( re_viewer_context::SystemCommand::SetActiveTimeline { rec_id: self.ctx.recording_id().clone(), - timeline: descr.timeline, + timeline: descr.timeline(), }, ); } diff --git a/crates/viewer/re_view_dataframe/src/display_record_batch.rs b/crates/viewer/re_view_dataframe/src/display_record_batch.rs index a1eddc1c3dd5..b774c5f80f90 100644 --- a/crates/viewer/re_view_dataframe/src/display_record_batch.rs +++ b/crates/viewer/re_view_dataframe/src/display_record_batch.rs @@ -185,7 +185,7 @@ impl DisplayColumn { ) -> Result { match column_descriptor { ColumnDescriptor::Time(desc) => { - let timeline = desc.timeline; + let timeline = desc.timeline(); let time_data = TimeColumn::read_array(column_data).map_err(|err| { DisplayRecordBatchError::BadTimeColumn { diff --git a/crates/viewer/re_view_dataframe/src/view_query/blueprint.rs b/crates/viewer/re_view_dataframe/src/view_query/blueprint.rs index abb1f508fd43..5f229cfc58e7 100644 --- a/crates/viewer/re_view_dataframe/src/view_query/blueprint.rs +++ b/crates/viewer/re_view_dataframe/src/view_query/blueprint.rs @@ -204,8 +204,8 @@ impl Query { .filter(|column| match column { ColumnDescriptor::Time(desc) => { // we always include the query timeline column because we need it for the dataframe ui - desc.timeline.name() == &query_timeline_name - || selected_time_columns.contains(desc.timeline.name()) + desc.name() == &query_timeline_name + || selected_time_columns.contains(desc.name()) } ColumnDescriptor::Component(desc) => { diff --git a/crates/viewer/re_view_dataframe/src/view_query/ui.rs b/crates/viewer/re_view_dataframe/src/view_query/ui.rs index 795e8506067c..8880c179cd67 100644 --- a/crates/viewer/re_view_dataframe/src/view_query/ui.rs +++ b/crates/viewer/re_view_dataframe/src/view_query/ui.rs @@ -314,7 +314,7 @@ impl Query { // The query timeline is always active because it's necessary for the dataframe ui // (for tooltips). - let is_query_timeline = time_column_descriptor.timeline.name() == timeline.name(); + let is_query_timeline = time_column_descriptor.name() == timeline.name(); let is_enabled = !is_query_timeline; let mut is_visible = is_query_timeline || selected_columns.contains(&column_selector); diff --git a/rerun_py/src/dataframe.rs b/rerun_py/src/dataframe.rs index 81c1f5ea7aa7..c7885138d3c0 100644 --- a/rerun_py/src/dataframe.rs +++ b/rerun_py/src/dataframe.rs @@ -74,7 +74,7 @@ struct PyIndexColumnDescriptor(TimeColumnDescriptor); #[pymethods] impl PyIndexColumnDescriptor { fn __repr__(&self) -> String { - format!("Index(timeline:{})", self.0.timeline.name()) + format!("Index(timeline:{})", self.0.name()) } /// The name of the index. @@ -82,7 +82,7 @@ impl PyIndexColumnDescriptor { /// This property is read-only. #[getter] fn name(&self) -> &str { - self.0.timeline.name() + self.0.name() } /// Part of generic ColumnDescriptor interface: always False for Index. @@ -1371,7 +1371,7 @@ impl PyRecording { include_semantically_empty_columns, include_indicator_columns, include_tombstone_columns, - filtered_index: Some(timeline.timeline), + filtered_index: Some(timeline.timeline()), filtered_index_range: None, filtered_index_values: None, using_index_values: None, From e4f8df4f28a986d1d05876230c2599b1901656c8 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 14 Jan 2025 09:56:02 +0100 Subject: [PATCH 23/57] Port `re_format_arrow` to `arrow-rs` (#8664) * Part of #3741 The "Print Datastore" feature will produce a slightly different result. --- Cargo.lock | 2 +- crates/store/re_chunk/src/transport.rs | 20 +- .../formatting__format_chunk_store.snap | 4 +- crates/store/re_format_arrow/Cargo.toml | 2 +- crates/store/re_format_arrow/src/lib.rs | 215 +++++++++--------- 5 files changed, 125 insertions(+), 118 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ed5203113c31..461ddf90e8b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5980,9 +5980,9 @@ dependencies = [ name = "re_format_arrow" version = "0.22.0-alpha.1+dev" dependencies = [ + "arrow", "comfy-table", "itertools 0.13.0", - "re_arrow2", "re_tuid", "re_types_core", ] diff --git a/crates/store/re_chunk/src/transport.rs b/crates/store/re_chunk/src/transport.rs index f8dcbcbcd2ad..b10cd1ad1b14 100644 --- a/crates/store/re_chunk/src/transport.rs +++ b/crates/store/re_chunk/src/transport.rs @@ -1,4 +1,6 @@ -use arrow::array::{ArrayRef as ArrowArrayRef, StructArray as ArrowStructArray}; +use arrow::array::{ + Array as ArrowArray, ArrayRef as ArrowArrayRef, StructArray as ArrowStructArray, +}; use arrow2::{ array::{Array as Arrow2Array, ListArray}, chunk::Chunk as Arrow2Chunk, @@ -48,10 +50,20 @@ pub struct TransportChunk { impl std::fmt::Display for TransportChunk { #[inline] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // TODO(#3741): simplify code when we have migrated to arrow-rs re_format_arrow::format_dataframe( - &self.schema.metadata, - &self.schema.fields, - self.data.iter().map(|list_array| &**list_array), + &self.schema.metadata.clone().into_iter().collect(), + &self + .schema + .fields + .iter() + .map(|field| arrow::datatypes::Field::from(field.clone())) + .collect(), + &self + .data + .iter() + .map(|list_array| ArrowArrayRef::from(list_array.clone())) + .collect_vec(), ) .fmt(f) } diff --git a/crates/store/re_chunk_store/tests/snapshots/formatting__format_chunk_store.snap b/crates/store/re_chunk_store/tests/snapshots/formatting__format_chunk_store.snap index 23ee30ee7353..af14c5c661cc 100644 --- a/crates/store/re_chunk_store/tests/snapshots/formatting__format_chunk_store.snap +++ b/crates/store/re_chunk_store/tests/snapshots/formatting__format_chunk_store.snap @@ -24,11 +24,11 @@ ChunkStore { │ ┌──────────────────────────────────┬───────────────┬───────────────────────────────┬───────────────────┬───────────────────┐ │ │ │ RowId ┆ frame_nr ┆ log_time ┆ example.MyColor ┆ example.MyIndex │ │ │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ - │ │ type: "struct[2]" ┆ type: "i64" ┆ type: "timestamp(ns)" ┆ type: "list[u32]" ┆ type: "list[u64]" │ │ + │ │ type: "Struct[2]" ┆ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[u64]" │ │ │ │ ARROW:extension:name: "TUID" ┆ is_sorted: "" ┆ is_sorted: "" ┆ kind: "data" ┆ kind: "data" │ │ │ │ kind: "control" ┆ kind: "time" ┆ kind: "time" ┆ ┆ │ │ │ ╞══════════════════════════════════╪═══════════════╪═══════════════════════════════╪═══════════════════╪═══════════════════╡ │ - │ │ 0000000067816A6BB4B8C1254D40007B ┆ 1 ┆ 2025-01-10 18:43:42.123456789 ┆ [0, 1, 2] ┆ [0, 1, 2] │ │ + │ │ 0000000067816A6BB4B8C1254D40007B ┆ 1 ┆ 2025-01-10T18:43:42.123456789 ┆ [0, 1, 2] ┆ [0, 1, 2] │ │ │ └──────────────────────────────────┴───────────────┴───────────────────────────────┴───────────────────┴───────────────────┘ │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ] diff --git a/crates/store/re_format_arrow/Cargo.toml b/crates/store/re_format_arrow/Cargo.toml index f2d76dd0f8e4..1801d1154b3d 100644 --- a/crates/store/re_format_arrow/Cargo.toml +++ b/crates/store/re_format_arrow/Cargo.toml @@ -20,7 +20,7 @@ all-features = true [dependencies] -arrow2.workspace = true +arrow.workspace = true itertools.workspace = true re_tuid.workspace = true re_types_core.workspace = true # tuid serialization diff --git a/crates/store/re_format_arrow/src/lib.rs b/crates/store/re_format_arrow/src/lib.rs index a6b143053067..423f1d8db865 100644 --- a/crates/store/re_format_arrow/src/lib.rs +++ b/crates/store/re_format_arrow/src/lib.rs @@ -1,13 +1,15 @@ //! Formatting for tables of Arrow arrays -use std::{borrow::Borrow, fmt::Formatter}; +use std::fmt::Formatter; -use arrow2::{ - array::{get_display, Array, ListArray}, - datatypes::{DataType, Field, IntervalUnit, Metadata, TimeUnit}, +use arrow::{ + array::{Array, ArrayRef, ListArray}, + datatypes::{DataType, Field, Fields, IntervalUnit, TimeUnit}, + util::display::{ArrayFormatter, FormatOptions}, }; use comfy_table::{presets, Cell, Row, Table}; +use itertools::Itertools as _; use re_tuid::Tuid; use re_types_core::Loggable as _; @@ -18,52 +20,52 @@ use re_types_core::Loggable as _; // B) Because how to deserialize and inspect some type is a private implementation detail of that // type, re_format shouldn't know how to deserialize a TUID… -type CustomFormatter<'a, F> = Box std::fmt::Result + 'a>; +/// Format the given row as a string +type CustomArrayFormatter<'a> = Box Result + 'a>; -fn get_custom_display<'a, F: std::fmt::Write + 'a>( - field: &Field, - array: &'a dyn Array, - null: &'static str, -) -> CustomFormatter<'a, F> { - if let Some(extension_name) = field.metadata.get("ARROW:extension:name") { +/// This is a `BTreeMap`, and not a `HashMap`, because we want a predictable order. +type Metadata = std::collections::BTreeMap; + +fn custom_array_formatter<'a>(field: &Field, array: &'a dyn Array) -> CustomArrayFormatter<'a> { + if let Some(extension_name) = field.metadata().get("ARROW:extension:name") { // TODO(#1775): This should be registered dynamically. if extension_name.as_str() == Tuid::ARROW_EXTENSION_NAME { - return Box::new(|w, index| { + return Box::new(|index| { if let Some(tuid) = parse_tuid(array, index) { - w.write_fmt(format_args!("{tuid}")) + Ok(format!("{tuid}")) } else { - w.write_str("") + Err("Invalid RowId".to_owned()) } }); } } - get_display(array, null) + match ArrayFormatter::try_new(array, &FormatOptions::default()) { + Ok(formatter) => Box::new(move |index| Ok(format!("{}", formatter.value(index)))), + Err(err) => Box::new(move |_| Err(format!("Failed to format array: {err}"))), + } } // TODO(#1775): This should be defined and registered by the `re_tuid` crate. fn parse_tuid(array: &dyn Array, index: usize) -> Option { - let (array, index) = match array.data_type().to_logical_type() { + fn parse_inner(array: &dyn Array, index: usize) -> Option { + let tuids = Tuid::from_arrow(array).ok()?; + tuids.get(index).copied() + } + + match array.data_type() { // Legacy MsgId lists: just grab the first value, they're all identical - DataType::List(_) => ( - array - .as_any() - .downcast_ref::>()? - .value(index), - 0, - ), + DataType::List(_) => { + parse_inner(&array.as_any().downcast_ref::()?.value(index), 0) + } // New control columns: it's not a list to begin with! - _ => (array.to_boxed(), index), - }; - - let array = re_types_core::external::arrow::array::ArrayRef::from(array); - let tuids = Tuid::from_arrow(&array).ok()?; - tuids.get(index).copied() + _ => parse_inner(array, index), + } } // --- -//TODO(john) move this and the Display impl upstream into arrow2 +// arrow has `ToString` implemented, but it is way too verbose. #[repr(transparent)] struct DisplayTimeUnit(TimeUnit); @@ -79,7 +81,7 @@ impl std::fmt::Display for DisplayTimeUnit { } } -//TODO(john) move this and the Display impl upstream into arrow2 +// arrow has `ToString` implemented, but it is way too verbose. #[repr(transparent)] struct DisplayIntervalUnit(IntervalUnit); @@ -94,7 +96,7 @@ impl std::fmt::Display for DisplayIntervalUnit { } } -//TODO(john) move this and the Display impl upstream into arrow2 +// arrow has `ToString` implemented, but it is way too verbose. #[repr(transparent)] struct DisplayDatatype<'a>(&'a DataType); @@ -116,72 +118,83 @@ impl std::fmt::Display for DisplayDatatype<'_> { DataType::Float64 => "f64", DataType::Timestamp(unit, timezone) => { let s = if let Some(tz) = timezone { - format!("timestamp({}, {tz})", DisplayTimeUnit(*unit)) + format!("Timestamp({}, {tz})", DisplayTimeUnit(*unit)) } else { - format!("timestamp({})", DisplayTimeUnit(*unit)) + format!("Timestamp({})", DisplayTimeUnit(*unit)) }; return f.write_str(&s); } - DataType::Date32 => "date32", - DataType::Date64 => "date64", + DataType::Date32 => "Date32", + DataType::Date64 => "Date64", DataType::Time32(unit) => { - let s = format!("time32({})", DisplayTimeUnit(*unit)); + let s = format!("Time32({})", DisplayTimeUnit(*unit)); return f.write_str(&s); } DataType::Time64(unit) => { - let s = format!("time64({})", DisplayTimeUnit(*unit)); + let s = format!("Time64({})", DisplayTimeUnit(*unit)); return f.write_str(&s); } DataType::Duration(unit) => { - let s = format!("duration({})", DisplayTimeUnit(*unit)); + let s = format!("Duration({})", DisplayTimeUnit(*unit)); return f.write_str(&s); } DataType::Interval(unit) => { - let s = format!("interval({})", DisplayIntervalUnit(*unit)); + let s = format!("Interval({})", DisplayIntervalUnit(*unit)); return f.write_str(&s); } - DataType::Binary => "bin", - DataType::FixedSizeBinary(size) => return write!(f, "fixed-bin[{size}]"), - DataType::LargeBinary => "large-bin", - DataType::Utf8 => "str", - DataType::LargeUtf8 => "large-string", + DataType::Binary => "Binary", + DataType::FixedSizeBinary(size) => return write!(f, "FixedSizeBinary[{size}]"), + DataType::LargeBinary => "LargeBinary", + DataType::Utf8 => "Utf8", + DataType::LargeUtf8 => "LargeUtf8", DataType::List(ref field) => { - let s = format!("list[{}]", Self(field.data_type())); + let s = format!("List[{}]", Self(field.data_type())); return f.write_str(&s); } DataType::FixedSizeList(field, len) => { - let s = format!("fixed-list[{}; {len}]", Self(field.data_type())); + let s = format!("FixedSizeList[{}; {len}]", Self(field.data_type())); return f.write_str(&s); } DataType::LargeList(field) => { - let s = format!("large-list[{}]", Self(field.data_type())); + let s = format!("LargeList[{}]", Self(field.data_type())); return f.write_str(&s); } - DataType::Struct(fields) => return write!(f, "struct[{}]", fields.len()), - DataType::Union(fields, _, _) => return write!(f, "union[{}]", fields.len()), - DataType::Map(field, _) => return write!(f, "map[{}]", Self(field.data_type())), - DataType::Dictionary(_, _, _) => "dict", - DataType::Decimal(_, _) => "decimal", - DataType::Decimal256(_, _) => "decimal256", - DataType::Extension(name, _, _) => { - return f.write_str(trim_name(name)); + DataType::Struct(fields) => return write!(f, "Struct[{}]", fields.len()), + DataType::Union(fields, _) => return write!(f, "Union[{}]", fields.len()), + DataType::Map(field, _) => return write!(f, "Map[{}]", Self(field.data_type())), + DataType::Dictionary(key, value) => { + return write!(f, "Dictionary{{{}: {}}}", Self(key), Self(value)) + } + DataType::Decimal128(_, _) => "Decimal128", + DataType::Decimal256(_, _) => "Decimal256", + DataType::BinaryView => "BinaryView", + DataType::Utf8View => "Utf8View", + DataType::ListView(field) => return write!(f, "ListView[{}]", Self(field.data_type())), + DataType::LargeListView(field) => { + return write!(f, "LargeListView[{}]", Self(field.data_type())) + } + DataType::RunEndEncoded(_run_ends, values) => { + return write!(f, "RunEndEncoded[{}]", Self(values.data_type())) } }; f.write_str(s) } } -struct DisplayMetadata<'a>(&'a Metadata, &'a str); +struct DisplayMetadata { + prefix: &'static str, + metadata: Metadata, +} -impl std::fmt::Display for DisplayMetadata<'_> { +impl std::fmt::Display for DisplayMetadata { #[inline] fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let Self(metadata, prefix) = self; + let Self { prefix, metadata } = self; f.write_str( &metadata .iter() .map(|(key, value)| format!("{prefix}{}: {:?}", trim_name(key), trim_name(value))) - .collect::>() + .collect_vec() .join("\n"), ) } @@ -200,29 +213,7 @@ fn trim_name(name: &str) -> &str { .trim_start_matches("rerun.") } -pub fn format_dataframe( - metadata: impl Borrow, - fields: impl IntoIterator, - columns: impl IntoIterator, -) -> Table -where - F: Borrow, - C: Borrow, -{ - let metadata = metadata.borrow(); - - let fields = fields.into_iter().collect::>(); - let fields = fields - .iter() - .map(|field| field.borrow()) - .collect::>(); - - let columns = columns.into_iter().collect::>(); - let columns = columns - .iter() - .map(|column| column.borrow()) - .collect::>(); - +pub fn format_dataframe(metadata: &Metadata, fields: &Fields, columns: &[ArrayRef]) -> Table { const MAXIMUM_CELL_CONTENT_WIDTH: u16 = 100; let mut outer_table = Table::new(); @@ -235,59 +226,63 @@ where let mut row = Row::new(); row.add_cell(Cell::new(format!( "CHUNK METADATA:\n{}", - DisplayMetadata(metadata, "* ") + DisplayMetadata { + prefix: "* ", + metadata: metadata.clone() + } ))); row }); let header = fields.iter().map(|field| { - if field.metadata.is_empty() { + if field.metadata().is_empty() { Cell::new(format!( "{}\n---\ntype: \"{}\"", // NOLINT - trim_name(&field.name), + trim_name(field.name()), DisplayDatatype(field.data_type()), )) } else { Cell::new(format!( "{}\n---\ntype: \"{}\"\n{}", // NOLINT - trim_name(&field.name), + trim_name(field.name()), DisplayDatatype(field.data_type()), - DisplayMetadata(&field.metadata, ""), + DisplayMetadata { + prefix: "", + metadata: field.metadata().clone().into_iter().collect() + }, )) } }); table.set_header(header); - let displays = itertools::izip!(fields.iter(), columns.iter()) - .map(|(field, array)| get_custom_display(field, &**array, "-")) - .collect::>(); + let formatters = itertools::izip!(fields.iter(), columns.iter()) + .map(|(field, array)| custom_array_formatter(field, &**array)) + .collect_vec(); let num_rows = columns.first().map_or(0, |list_array| list_array.len()); - if displays.is_empty() || num_rows == 0 { + if formatters.is_empty() || num_rows == 0 { return table; } for row in 0..num_rows { - let cells: Vec<_> = displays + let cells: Vec<_> = formatters .iter() - .map(|disp| { - let mut string = String::new(); - if (disp)(&mut string, row).is_err() { - // Seems to be okay to silently ignore errors here, but reset the string just in case - string.clear(); - } - let chars: Vec<_> = string.chars().collect(); - if chars.len() > MAXIMUM_CELL_CONTENT_WIDTH as usize { - Cell::new( - chars - .into_iter() - .take(MAXIMUM_CELL_CONTENT_WIDTH.saturating_sub(1).into()) - .chain(['…']) - .collect::(), - ) - } else { - Cell::new(string) + .map(|formatter| match formatter(row) { + Ok(string) => { + let chars: Vec<_> = string.chars().collect(); + if chars.len() > MAXIMUM_CELL_CONTENT_WIDTH as usize { + Cell::new( + chars + .into_iter() + .take(MAXIMUM_CELL_CONTENT_WIDTH.saturating_sub(1).into()) + .chain(['…']) + .collect::(), + ) + } else { + Cell::new(string) + } } + Err(err) => Cell::new(err), }) .collect(); table.add_row(cells); From f779d8befbdbdf97925def48f6dfc7b5c4a34e12 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Tue, 14 Jan 2025 11:02:44 +0100 Subject: [PATCH 24/57] Filter entities in the UI (part 3): Move action to a menu in the blueprint panel and keep default blueprint when using heuristics (#8672) Co-authored-by: Emil Ernerfeldt --- .../re_blueprint_tree/src/blueprint_tree.rs | 148 +++++++++++------- crates/viewer/re_data_ui/src/app_id.rs | 48 +----- crates/viewer/re_ui/src/command.rs | 15 +- crates/viewer/re_ui/src/ui_ext.rs | 10 ++ crates/viewer/re_view_graph/tests/basic.rs | 1 + crates/viewer/re_viewer/src/app.rs | 12 +- crates/viewer/re_viewer/src/app_state.rs | 7 + .../re_viewer_context/src/command_sender.rs | 18 ++- .../re_viewer_context/src/store_context.rs | 3 + .../viewer/re_viewer_context/src/store_hub.rs | 39 +++-- .../re_viewer_context/src/test_context.rs | 3 +- .../viewer/re_viewport_blueprint/src/view.rs | 1 + .../src/view_contents.rs | 1 + 13 files changed, 172 insertions(+), 134 deletions(-) diff --git a/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs b/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs index 855f058e2bfb..f88326f5ae72 100644 --- a/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs +++ b/crates/viewer/re_blueprint_tree/src/blueprint_tree.rs @@ -49,14 +49,25 @@ impl BlueprintTree { ui: &mut egui::Ui, ) { ui.panel_content(|ui| { - ui.panel_title_bar_with_buttons( - "Blueprint", - Some("The blueprint is where you can configure the Rerun Viewer"), - |ui| { - self.add_new_view_button_ui(ctx, viewport, ui); - reset_blueprint_button_ui(ctx, ui); - }, - ); + ui.full_span_separator(); + ui.add_space(-1.); + + ui.list_item_scope("blueprint_section_title", |ui| { + ui.list_item_flat_noninteractive( + list_item::CustomContent::new(|ui, _| { + ui.strong("Blueprint").on_hover_text( + "The blueprint is where you can configure the Rerun Viewer", + ); + }) + .menu_button(&re_ui::icons::MORE, |ui| { + add_new_view_or_container_menu_button(ctx, viewport, ui); + set_blueprint_to_default_menu_buttons(ctx, ui); + set_blueprint_to_auto_menu_button(ctx, viewport, ui); + }), + ); + }); + + ui.full_span_separator(); }); // This call is excluded from `panel_content` because it has a ScrollArea, which should not be @@ -602,32 +613,6 @@ impl BlueprintTree { ctx.handle_select_hover_drag_interactions(&response, item, true); } - /// Add a button to trigger the addition of a new view or container. - #[allow(clippy::unused_self)] - fn add_new_view_button_ui( - &self, - ctx: &ViewerContext<'_>, - viewport: &ViewportBlueprint, - ui: &mut egui::Ui, - ) { - if ui - .small_icon_button(&re_ui::icons::ADD) - .on_hover_text("Add a new view or container") - .clicked() - { - // If a single container is selected, we use it as target. Otherwise, we target the - // root container. - let target_container_id = - if let Some(Item::Container(container_id)) = ctx.selection().single_item() { - *container_id - } else { - viewport.root_container - }; - - show_add_view_or_container_modal(target_container_id); - } - } - // ---------------------------------------------------------------------------- // drag and drop support @@ -868,7 +853,35 @@ impl BlueprintTree { // ---------------------------------------------------------------------------- -fn reset_blueprint_button_ui(ctx: &ViewerContext<'_>, ui: &mut egui::Ui) { +/// Add a button to trigger the addition of a new view or container. +fn add_new_view_or_container_menu_button( + ctx: &ViewerContext<'_>, + viewport: &ViewportBlueprint, + ui: &mut egui::Ui, +) { + if ui + .add(egui::Button::image_and_text( + &re_ui::icons::ADD, + "Add view or container…", + )) + .clicked() + { + ui.close_menu(); + + // If a single container is selected, we use it as target. Otherwise, we target the + // root container. + let target_container_id = + if let Some(Item::Container(container_id)) = ctx.selection().single_item() { + *container_id + } else { + viewport.root_container + }; + + show_add_view_or_container_modal(target_container_id); + } +} + +fn set_blueprint_to_default_menu_buttons(ctx: &ViewerContext<'_>, ui: &mut egui::Ui) { let default_blueprint_id = ctx .store_context .hub @@ -876,38 +889,61 @@ fn reset_blueprint_button_ui(ctx: &ViewerContext<'_>, ui: &mut egui::Ui) { let default_blueprint = default_blueprint_id.and_then(|id| ctx.store_context.bundle.get(id)); - let mut disabled_reason = None; - - if let Some(default_blueprint) = default_blueprint { - let active_is_clone_of_default = Some(default_blueprint.store_id()).as_ref() - == ctx.store_context.blueprint.cloned_from(); - let last_modified_at_the_same_time = - default_blueprint.latest_row_id() == ctx.store_context.blueprint.latest_row_id(); - if active_is_clone_of_default && last_modified_at_the_same_time { - disabled_reason = Some("No modifications have been made"); + let disabled_reason = match default_blueprint { + None => Some("No default blueprint is set for this app"), + Some(default_blueprint) => { + let active_is_clone_of_default = Some(default_blueprint.store_id()).as_ref() + == ctx.store_context.blueprint.cloned_from(); + let last_modified_at_the_same_time = + default_blueprint.latest_row_id() == ctx.store_context.blueprint.latest_row_id(); + if active_is_clone_of_default && last_modified_at_the_same_time { + Some("No modifications have been made") + } else { + None // it is valid to reset to default + } } - } + }; let enabled = disabled_reason.is_none(); - let response = ui.add_enabled(enabled, ui.small_icon_button_widget(&re_ui::icons::RESET)); - - let response = if let Some(disabled_reason) = disabled_reason { - response.on_disabled_hover_text(disabled_reason) - } else { - let hover_text = if default_blueprint_id.is_some() { - "Reset to the default blueprint for this app" - } else { - "Re-populate viewport with automatically chosen views" - }; - response.on_hover_text(hover_text) + let mut response = ui + .add_enabled( + enabled, + egui::Button::image_and_text(&re_ui::icons::RESET, "Reset to default blueprint"), + ) + .on_hover_text("Reset to the default blueprint for this app"); + + if let Some(disabled_reason) = disabled_reason { + response = response.on_disabled_hover_text(disabled_reason); }; if response.clicked() { + ui.close_menu(); ctx.command_sender .send_system(re_viewer_context::SystemCommand::ClearActiveBlueprint); } } +fn set_blueprint_to_auto_menu_button( + ctx: &ViewerContext<'_>, + viewport: &ViewportBlueprint, + ui: &mut egui::Ui, +) { + let enabled = !viewport.auto_layout() || !viewport.auto_views(); + + if ui + .add_enabled( + enabled, + egui::Button::image_and_text(&re_ui::icons::RESET, "Reset to heuristic blueprint"), + ) + .on_hover_text("Re-populate viewport with automatically chosen views") + .clicked() + { + ui.close_menu(); + ctx.command_sender + .send_system(re_viewer_context::SystemCommand::ClearActiveBlueprintAndEnableHeuristics); + } +} + /// Expand all required items and compute which item we should scroll to. fn handle_focused_item( ctx: &ViewerContext<'_>, diff --git a/crates/viewer/re_data_ui/src/app_id.rs b/crates/viewer/re_data_ui/src/app_id.rs index 512289c0b63b..e5c888cc8b0e 100644 --- a/crates/viewer/re_data_ui/src/app_id.rs +++ b/crates/viewer/re_data_ui/src/app_id.rs @@ -2,7 +2,7 @@ use itertools::Itertools as _; use re_entity_db::EntityDb; use re_log_types::ApplicationId; -use re_viewer_context::{SystemCommandSender as _, UiLayout, ViewerContext}; +use re_viewer_context::{UiLayout, ViewerContext}; use crate::item_ui::entity_db_button_ui; @@ -54,51 +54,5 @@ impl crate::DataUi for ApplicationId { } }); } - - // --------------------------------------------------------------------- - // do not show UI code in tooltips - - if ui_layout != UiLayout::Tooltip { - ui.add_space(8.0); - - // --------------------------------------------------------------------- - - // Blueprint section. - let active_blueprint = ctx.store_context.blueprint; - let default_blueprint = ctx.store_context.hub.default_blueprint_for_app(self); - - let button = - egui::Button::image_and_text(&re_ui::icons::RESET, "Reset to default blueprint"); - - let is_same_as_default = default_blueprint.is_some_and(|default_blueprint| { - default_blueprint.latest_row_id() == active_blueprint.latest_row_id() - }); - - if is_same_as_default { - ui.add_enabled(false, button) - .on_disabled_hover_text("No modifications have been made"); - } else if default_blueprint.is_none() { - ui.add_enabled(false, button) - .on_disabled_hover_text("There's no default blueprint"); - } else { - // The active blueprint is different from the default blueprint - if ui - .add(button) - .on_hover_text("Reset to the default blueprint for this app") - .clicked() - { - ctx.command_sender - .send_system(re_viewer_context::SystemCommand::ClearActiveBlueprint); - } - } - - if ui.add(egui::Button::image_and_text( - &re_ui::icons::RESET, - "Reset to heuristic blueprint", - )).on_hover_text("Clear both active and default blueprint, and auto-generate a new blueprint based on heuristics").clicked() { - ctx.command_sender - .send_system(re_viewer_context::SystemCommand::ClearAndGenerateBlueprint); - } - } } } diff --git a/crates/viewer/re_ui/src/command.rs b/crates/viewer/re_ui/src/command.rs index 6781a2978feb..9b5863a79f1e 100644 --- a/crates/viewer/re_ui/src/command.rs +++ b/crates/viewer/re_ui/src/command.rs @@ -32,7 +32,7 @@ pub enum UICommand { OpenRerunDiscord, ResetViewer, - ClearAndGenerateBlueprint, + ClearActiveBlueprintAndEnableHeuristics, #[cfg(not(target_arch = "wasm32"))] OpenProfiler, @@ -121,7 +121,7 @@ impl UICommand { ), Self::CloseAllRecordings => ("Close all recordings", - "Close all open current recording (unsaved data will be lost)"), + "Close all open current recording (unsaved data will be lost)"), Self::Undo => ("Undo", "Undo the last blueprint edit for the open recording"), Self::Redo => ("Redo", "Redo the last undone thing"), @@ -137,12 +137,11 @@ impl UICommand { "Reset the Viewer to how it looked the first time you ran it, forgetting all stored blueprints and UI state", ), - Self::ClearAndGenerateBlueprint => ( - "Clear and generate new blueprint", - "Clear the current blueprint and generate a new one based on heuristics." + Self::ClearActiveBlueprintAndEnableHeuristics => ( + "Reset to heuristic blueprint", + "Re-populate viewport with automatically chosen views" ), - #[cfg(not(target_arch = "wasm32"))] Self::OpenProfiler => ( "Open profiler", @@ -174,7 +173,6 @@ impl UICommand { "View and change global egui style settings", ), - #[cfg(not(target_arch = "wasm32"))] Self::ToggleFullscreen => ( "Toggle fullscreen", @@ -256,7 +254,6 @@ impl UICommand { "Restart with WebGPU", "Reloads the webpage and force WebGPU for rendering. All data will be lost." ), - } } @@ -314,7 +311,7 @@ impl UICommand { Self::Quit => smallvec![cmd(Key::Q)], Self::ResetViewer => smallvec![ctrl_shift(Key::R)], - Self::ClearAndGenerateBlueprint => smallvec![], + Self::ClearActiveBlueprintAndEnableHeuristics => smallvec![], #[cfg(not(target_arch = "wasm32"))] Self::OpenProfiler => smallvec![ctrl_shift(Key::P)], diff --git a/crates/viewer/re_ui/src/ui_ext.rs b/crates/viewer/re_ui/src/ui_ext.rs index a4eaf864eeb9..1a645758ab38 100644 --- a/crates/viewer/re_ui/src/ui_ext.rs +++ b/crates/viewer/re_ui/src/ui_ext.rs @@ -655,6 +655,16 @@ pub trait UiExt { self.ui().painter().add(shadow); } + /// Convenience function to create a [`list_item::list_item_scope`]. + #[inline] + fn list_item_scope( + &mut self, + id_salt: impl std::hash::Hash, + content: impl FnOnce(&mut egui::Ui) -> R, + ) -> R { + list_item::list_item_scope(self.ui_mut(), id_salt, content) + } + /// Convenience function to create a [`list_item::ListItem`]. #[allow(clippy::unused_self)] fn list_item(&self) -> list_item::ListItem { diff --git a/crates/viewer/re_view_graph/tests/basic.rs b/crates/viewer/re_view_graph/tests/basic.rs index 4701354e814c..c34fb9e7fc31 100644 --- a/crates/viewer/re_view_graph/tests/basic.rs +++ b/crates/viewer/re_view_graph/tests/basic.rs @@ -188,6 +188,7 @@ fn run_graph_view_and_save_snapshot( bundle: &Default::default(), caches: &Default::default(), hub: &Default::default(), + should_enable_heuristics: false, }; // Execute the queries for every `View` diff --git a/crates/viewer/re_viewer/src/app.rs b/crates/viewer/re_viewer/src/app.rs index 934705af994b..678a21100709 100644 --- a/crates/viewer/re_viewer/src/app.rs +++ b/crates/viewer/re_viewer/src/app.rs @@ -524,12 +524,10 @@ impl App { } SystemCommand::ResetViewer => self.reset_viewer(store_hub, egui_ctx), - SystemCommand::ClearAndGenerateBlueprint => { + SystemCommand::ClearActiveBlueprintAndEnableHeuristics => { re_log::debug!("Clear and generate new blueprint"); - // By clearing the default blueprint and the active blueprint - // it will be re-generated based on the default auto behavior. - store_hub.clear_default_blueprint(); - store_hub.clear_active_blueprint(); + store_hub.clear_active_blueprint_and_generate(); + egui_ctx.request_repaint(); // Many changes take a frame delay to show up. } SystemCommand::ClearActiveBlueprint => { // By clearing the blueprint the default blueprint will be restored @@ -779,9 +777,9 @@ impl App { } UICommand::ResetViewer => self.command_sender.send_system(SystemCommand::ResetViewer), - UICommand::ClearAndGenerateBlueprint => { + UICommand::ClearActiveBlueprintAndEnableHeuristics => { self.command_sender - .send_system(SystemCommand::ClearAndGenerateBlueprint); + .send_system(SystemCommand::ClearActiveBlueprintAndEnableHeuristics); } #[cfg(not(target_arch = "wasm32"))] diff --git a/crates/viewer/re_viewer/src/app_state.rs b/crates/viewer/re_viewer/src/app_state.rs index e4bc1ad4cee2..a29e202065d2 100644 --- a/crates/viewer/re_viewer/src/app_state.rs +++ b/crates/viewer/re_viewer/src/app_state.rs @@ -282,6 +282,13 @@ impl AppState { drag_and_drop_manager: &drag_and_drop_manager, }; + // enable the heuristics if we must this frame + if store_context.should_enable_heuristics { + viewport_ui.blueprint.set_auto_layout(true, &ctx); + viewport_ui.blueprint.set_auto_views(true, &ctx); + egui_ctx.request_repaint(); + } + // We move the time at the very start of the frame, // so that we always show the latest data when we're in "follow" mode. move_time(&ctx, recording, rx); diff --git a/crates/viewer/re_viewer_context/src/command_sender.rs b/crates/viewer/re_viewer_context/src/command_sender.rs index 1f0fb34acea5..63c7a1b7fc45 100644 --- a/crates/viewer/re_viewer_context/src/command_sender.rs +++ b/crates/viewer/re_viewer_context/src/command_sender.rs @@ -27,11 +27,23 @@ pub enum SystemCommand { /// Reset the `Viewer` to the default state ResetViewer, - /// Reset the `Blueprint` to the default state + /// Clear the active blueprint. + /// + /// This may have two outcomes: + /// - If a default blueprint is set, it will be used. + /// - Otherwise, the heuristics will be enabled. + /// + /// To force using the heuristics, use [`Self::ClearActiveBlueprintAndEnableHeuristics`]. + /// + /// UI note: because of the above ambiguity, controls for this command should only be enabled if + /// a default blueprint is set. ClearActiveBlueprint, - /// Clear the blueprint and generate a new one - ClearAndGenerateBlueprint, + /// Clear the active blueprint and enable heuristics. + /// + /// The final outcome of this is to set the active blueprint to the heuristics. This command + /// does not affect the default blueprint if any was set. + ClearActiveBlueprintAndEnableHeuristics, /// If this is a recording, switch to it. ActivateRecording(StoreId), diff --git a/crates/viewer/re_viewer_context/src/store_context.rs b/crates/viewer/re_viewer_context/src/store_context.rs index a50405f6e211..659592efd311 100644 --- a/crates/viewer/re_viewer_context/src/store_context.rs +++ b/crates/viewer/re_viewer_context/src/store_context.rs @@ -29,6 +29,9 @@ pub struct StoreContext<'a> { /// The store hub, which keeps track of all the default and active blueprints, among other things. pub hub: &'a StoreHub, + + /// Should we enable the heuristics during this frame? + pub should_enable_heuristics: bool, } impl StoreContext<'_> { diff --git a/crates/viewer/re_viewer_context/src/store_hub.rs b/crates/viewer/re_viewer_context/src/store_hub.rs index 977ac4f3e167..bc01b1c98c29 100644 --- a/crates/viewer/re_viewer_context/src/store_hub.rs +++ b/crates/viewer/re_viewer_context/src/store_hub.rs @@ -45,6 +45,9 @@ pub struct StoreHub { active_blueprint_by_app_id: HashMap, store_bundle: StoreBundle, + /// These applications should enable the heuristics early next frame. + should_enable_heuristics_by_app_id: HashSet, + /// Things that need caching. caches_per_recording: HashMap, @@ -143,6 +146,8 @@ impl StoreHub { active_blueprint_by_app_id: Default::default(), store_bundle, + should_enable_heuristics_by_app_id: Default::default(), + caches_per_recording: Default::default(), blueprint_last_save: Default::default(), blueprint_last_gc: Default::default(), @@ -184,8 +189,11 @@ impl StoreHub { } } - // If there's no active blueprint for this app, try to make the current default one active. - if !self.active_blueprint_by_app_id.contains_key(&app_id) { + // If there's no active blueprint for this app, we must use the default blueprint, UNLESS + // we're about to enable heuristics for this app. + if !self.active_blueprint_by_app_id.contains_key(&app_id) + && !self.should_enable_heuristics_by_app_id.contains(&app_id) + { if let Some(blueprint_id) = self.default_blueprint_by_app_id.get(&app_id).cloned() { self.set_cloned_blueprint_active_for_app(&app_id, &blueprint_id) .unwrap_or_else(|err| { @@ -220,6 +228,7 @@ impl StoreHub { self.active_rec_id = None; } + let should_enable_heuristics = self.should_enable_heuristics_by_app_id.remove(&app_id); let caches = self.active_caches(); Some(StoreContext { @@ -230,6 +239,7 @@ impl StoreHub { bundle: &self.store_bundle, caches: caches.unwrap_or(&EMPTY_CACHES), hub: self, + should_enable_heuristics, }) } @@ -497,15 +507,6 @@ impl StoreHub { Ok(()) } - /// Clear the current default blueprint - pub fn clear_default_blueprint(&mut self) { - if let Some(app_id) = &self.active_application_id { - if let Some(blueprint_id) = self.default_blueprint_by_app_id.remove(app_id) { - self.remove(&blueprint_id); - } - } - } - // --------------------- // Active blueprint @@ -578,6 +579,22 @@ impl StoreHub { } } + /// Clear the currently active blueprint and enable the heuristics to generate a new one. + /// + /// These keeps the default blueprint as is, so the user may reset to the default blueprint + /// afterward. + pub fn clear_active_blueprint_and_generate(&mut self) { + self.clear_active_blueprint(); + + // Simply clearing the default blueprint would trigger a reset to default. Instead, we must + // actively set the blueprint to use the heuristics, so we store a flag so we do that early + // next frame. + if let Some(app_id) = self.active_app() { + self.should_enable_heuristics_by_app_id + .insert(app_id.clone()); + } + } + // --------------------- // Misc operations diff --git a/crates/viewer/re_viewer_context/src/test_context.rs b/crates/viewer/re_viewer_context/src/test_context.rs index 427e84733659..baf122c5c77b 100644 --- a/crates/viewer/re_viewer_context/src/test_context.rs +++ b/crates/viewer/re_viewer_context/src/test_context.rs @@ -281,6 +281,7 @@ impl TestContext { bundle: &Default::default(), caches: &Default::default(), hub: &Default::default(), + should_enable_heuristics: false, }; let drag_and_drop_manager = crate::DragAndDropManager::new(ItemCollection::default()); @@ -398,7 +399,7 @@ impl TestContext { | SystemCommand::AddReceiver(_) | SystemCommand::ResetViewer | SystemCommand::ClearActiveBlueprint - | SystemCommand::ClearAndGenerateBlueprint + | SystemCommand::ClearActiveBlueprintAndEnableHeuristics | SystemCommand::ActivateRecording(_) | SystemCommand::CloseStore(_) | SystemCommand::UndoBlueprint { .. } diff --git a/crates/viewer/re_viewport_blueprint/src/view.rs b/crates/viewer/re_viewport_blueprint/src/view.rs index be58f4f85116..e040eadcf27a 100644 --- a/crates/viewer/re_viewport_blueprint/src/view.rs +++ b/crates/viewer/re_viewport_blueprint/src/view.rs @@ -760,6 +760,7 @@ mod tests { bundle: &Default::default(), caches: &Default::default(), hub: &re_viewer_context::StoreHub::test_hub(), + should_enable_heuristics: false, }; let mut query_result = view.contents.execute_query( diff --git a/crates/viewer/re_viewport_blueprint/src/view_contents.rs b/crates/viewer/re_viewport_blueprint/src/view_contents.rs index ef96719299b7..d2d9068ac9e6 100644 --- a/crates/viewer/re_viewport_blueprint/src/view_contents.rs +++ b/crates/viewer/re_viewport_blueprint/src/view_contents.rs @@ -668,6 +668,7 @@ mod tests { bundle: &Default::default(), caches: &Default::default(), hub: &StoreHub::test_hub(), + should_enable_heuristics: false, }; struct Scenario { From 63012cd9a28245cd0572068ca74ec20c1dd92f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= Date: Tue, 14 Jan 2025 11:46:58 +0100 Subject: [PATCH 25/57] Fix unused imports (#8678) --- .../store/re_log_encoding/src/protobuf_conversions.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/crates/store/re_log_encoding/src/protobuf_conversions.rs b/crates/store/re_log_encoding/src/protobuf_conversions.rs index 4ad6580d2950..f3193575907a 100644 --- a/crates/store/re_log_encoding/src/protobuf_conversions.rs +++ b/crates/store/re_log_encoding/src/protobuf_conversions.rs @@ -1,7 +1,3 @@ -use re_protos::missing_field; - -use crate::codec::CodecError; - impl From for crate::Compression { fn from(value: re_protos::log_msg::v0::Compression) -> Self { match value { @@ -24,9 +20,12 @@ impl From for re_protos::log_msg::v0::Compression { pub fn log_msg_from_proto( message: re_protos::log_msg::v0::LogMsg, ) -> Result { - use crate::codec::arrow::decode_arrow; + use crate::codec::{arrow::decode_arrow, CodecError}; use crate::decoder::DecodeError; - use re_protos::log_msg::v0::{log_msg::Msg, Encoding}; + use re_protos::{ + log_msg::v0::{log_msg::Msg, Encoding}, + missing_field, + }; match message.msg { Some(Msg::SetStoreInfo(set_store_info)) => Ok(re_log_types::LogMsg::SetStoreInfo( From 3a8c22fb2cd8b5c550d63b3bda2ad1a922a2c7c6 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 14 Jan 2025 14:25:24 +0100 Subject: [PATCH 26/57] Port `ArrowMsg` to using `arrow::RecordBatch` (#8669) ### Related * Poart of #3741 ### Details I'd like to replace our `TransportChunk` with arrow's `RecordBatch`. This is a good step in that direction. --------- Co-authored-by: Jeremy Leibs --- Cargo.lock | 23 +- Cargo.toml | 8 +- clippy.toml | 3 + crates/store/re_chunk/src/arrow.rs | 2 +- crates/store/re_chunk/src/arrow2_util.rs | 7 +- crates/store/re_chunk/src/batcher.rs | 4 +- crates/store/re_chunk/src/transport.rs | 80 +++++-- crates/store/re_chunk_store/src/store.rs | 16 +- crates/store/re_dataframe/src/query.rs | 13 +- crates/store/re_grpc_client/src/lib.rs | 9 +- crates/store/re_log_encoding/Cargo.toml | 2 + .../benches/msg_encode_benchmark.rs | 8 +- .../store/re_log_encoding/src/codec/arrow.rs | 102 ++++++--- .../re_log_encoding/src/codec/file/decoder.rs | 7 +- .../re_log_encoding/src/codec/file/encoder.rs | 2 +- crates/store/re_log_encoding/src/codec/mod.rs | 13 +- .../re_log_encoding/src/codec/wire/decoder.rs | 10 +- .../re_log_encoding/src/codec/wire/encoder.rs | 5 +- .../re_log_encoding/src/codec/wire/mod.rs | 9 +- .../store/re_log_encoding/src/decoder/mod.rs | 98 ++++---- crates/store/re_log_encoding/src/encoder.rs | 2 +- .../src/protobuf_conversions.rs | 9 +- .../tests/arrow_encode_roundtrip.rs | 66 ++++++ crates/store/re_log_types/Cargo.toml | 8 +- crates/store/re_log_types/src/arrow_msg.rs | 214 +++++++++++------- crates/store/re_log_types/src/lib.rs | 49 +++- crates/top/re_sdk/src/recording_stream.rs | 23 +- crates/top/rerun/src/commands/rrd/compare.rs | 3 +- crates/top/rerun/src/commands/rrd/filter.rs | 57 +++-- crates/top/rerun/src/lib.rs | 2 - crates/utils/re_byte_size/src/arrow_sizes.rs | 97 +++++++- .../viewer/re_chunk_store_ui/src/chunk_ui.rs | 4 +- rerun_py/src/dataframe.rs | 4 +- rerun_py/src/python_bridge.rs | 6 +- rerun_py/src/remote.rs | 4 +- 35 files changed, 640 insertions(+), 329 deletions(-) create mode 100644 crates/store/re_log_encoding/tests/arrow_encode_roundtrip.rs diff --git a/Cargo.lock b/Cargo.lock index 461ddf90e8b6..bbd30938aff3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -365,6 +365,7 @@ dependencies = [ "arrow-buffer", "arrow-cast", "arrow-data", + "arrow-ipc", "arrow-ord", "arrow-row", "arrow-schema", @@ -457,6 +458,20 @@ dependencies = [ "serde", ] +[[package]] +name = "arrow-ipc" +version = "53.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed91bdeaff5a1c00d28d8f73466bcb64d32bbd7093b5a30156b4b9f4dba3eee" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-cast", + "arrow-data", + "arrow-schema", + "flatbuffers", +] + [[package]] name = "arrow-ord" version = "53.2.0" @@ -3885,7 +3900,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -5203,7 +5218,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c1318b19085f08681016926435853bbf7858f9c082d0999b80550ff5d9abe15" dependencies = [ "bytes", - "heck 0.5.0", + "heck 0.4.1", "itertools 0.13.0", "log", "multimap", @@ -5569,7 +5584,7 @@ dependencies = [ [[package]] name = "re_arrow2" version = "0.18.1" -source = "git+https://github.com/rerun-io/re_arrow2.git?branch=main#573b5bafd071d09698353d8f0de8d31f3fa59017" +source = "git+https://github.com/rerun-io/re_arrow2.git?branch=main#e8576708a1b41b493980ecb995e808aefcfa1fbc" dependencies = [ "ahash", "arrow-array", @@ -6057,6 +6072,7 @@ dependencies = [ name = "re_log_encoding" version = "0.22.0-alpha.1+dev" dependencies = [ + "arrow", "criterion", "ehttp", "js-sys", @@ -6074,6 +6090,7 @@ dependencies = [ "re_types", "rmp-serde", "serde_test", + "similar-asserts", "thiserror 1.0.65", "wasm-bindgen", "wasm-bindgen-futures", diff --git a/Cargo.toml b/Cargo.toml index 85b4d748085e..7574f393ff2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -555,10 +555,12 @@ significant_drop_tightening = "allow" # An update of parking_lot made this trigg [patch.crates-io] # Try to avoid patching crates! It prevents us from publishing the crates on crates.io. -# If you do patch always prefer to patch to a commit on the trunk of the upstream repo. +# If you do patch always prefer to patch to the trunk branch of the upstream repo (i.e. `main`, `master`, …). # If that is not possible, patch to a branch that has a PR open on the upstream repo. -# As a last resport, patch with a commit to our own repository. -# ALWAYS document what PR the commit hash is part of, or when it was merged into the upstream trunk. +# As a last resort, patch to a branch on our own repository. +# +# Prefer patching with `branch` over `rev` and let `Cargo.lock` handle the commit hash. +# That makes it easy to upade with `cargo update -p $CRATE`. ecolor = { git = "https://github.com/emilk/egui.git", rev = "f0d7c74e838b8e8920a22e7515990fbe057ec218" } # egui master 2025-01-08 eframe = { git = "https://github.com/emilk/egui.git", rev = "f0d7c74e838b8e8920a22e7515990fbe057ec218" } # egui master 2025-01-08 diff --git a/clippy.toml b/clippy.toml index bec822eb6e8f..01e482ba6bdd 100644 --- a/clippy.toml +++ b/clippy.toml @@ -54,6 +54,8 @@ disallowed-methods = [ { path = "arrow::compute::filter", reason = "Use `re_chunk::arrow_util::filter_array` instead" }, { path = "arrow::compute::take", reason = "Use `re_chunk::arrow_util::take_array` instead" }, + { path = "arrow::datatypes::Schema::new", reason = "Use `arrow::datatypes::Schema::new_with_metadata` instead. There is usually some metadata you want to preserve." }, + # Specify both `arrow2` and `re_arrow2` -- clippy gets lost in all the package renaming happening. { path = "arrow2::compute::concatenate::concatenate", reason = "Use `re_chunk::arrow2_util::concat_arrays` instead, which has proper early outs" }, { path = "arrow2::compute::filter::filter", reason = "Use `re_chunk::arrow2_util::filter_array` instead, which has proper early outs" }, @@ -72,6 +74,7 @@ disallowed-names = [] # https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types disallowed-types = [ + { path = "arrow::ipc::writer::StreamWriter", reason = "Wait until https://github.com/apache/arrow-rs/pull/6805 has been released" }, { path = "egui::Checkbox", reason = "Use `re_checkbox` from `re_ui::UiEx" }, { path = "ring::digest::SHA1_FOR_LEGACY_USE_ONLY", reason = "SHA1 is cryptographically broken" }, { path = "std::sync::Condvar", reason = "Use parking_lot instead" }, diff --git a/crates/store/re_chunk/src/arrow.rs b/crates/store/re_chunk/src/arrow.rs index 20eba08c8741..4f10fc039c45 100644 --- a/crates/store/re_chunk/src/arrow.rs +++ b/crates/store/re_chunk/src/arrow.rs @@ -22,7 +22,7 @@ impl TransportChunk { let metadata = self.schema.metadata.clone().into_iter().collect(); - let schema = Schema::new(fields).with_metadata(metadata); + let schema = Schema::new_with_metadata(fields, metadata); let columns: Vec<_> = self .data diff --git a/crates/store/re_chunk/src/arrow2_util.rs b/crates/store/re_chunk/src/arrow2_util.rs index c6e3696cc412..99ad03eefdf2 100644 --- a/crates/store/re_chunk/src/arrow2_util.rs +++ b/crates/store/re_chunk/src/arrow2_util.rs @@ -449,7 +449,7 @@ pub fn concatenate_record_batches( schema: Arrow2Schema, batches: &[TransportChunk], ) -> anyhow::Result { - assert!(batches.iter().map(|batch| &batch.schema).all_equal()); + assert!(batches.iter().map(|batch| batch.schema_ref()).all_equal()); let mut arrays = Vec::new(); @@ -465,8 +465,5 @@ pub fn concatenate_record_batches( } } - Ok(TransportChunk { - schema, - data: Arrow2Chunk::new(arrays), - }) + Ok(TransportChunk::new(schema, Arrow2Chunk::new(arrays))) } diff --git a/crates/store/re_chunk/src/batcher.rs b/crates/store/re_chunk/src/batcher.rs index e5c4a431fe49..b1f4a61d0afe 100644 --- a/crates/store/re_chunk/src/batcher.rs +++ b/crates/store/re_chunk/src/batcher.rs @@ -52,10 +52,10 @@ pub struct BatcherHooks { /// Callback to be run when an Arrow Chunk goes out of scope. /// - /// See [`re_log_types::ArrowChunkReleaseCallback`] for more information. + /// See [`re_log_types::ArrowRecordBatchReleaseCallback`] for more information. // // TODO(#6412): probably don't need this anymore. - pub on_release: Option, + pub on_release: Option, } impl BatcherHooks { diff --git a/crates/store/re_chunk/src/transport.rs b/crates/store/re_chunk/src/transport.rs index b10cd1ad1b14..3239102b0416 100644 --- a/crates/store/re_chunk/src/transport.rs +++ b/crates/store/re_chunk/src/transport.rs @@ -1,5 +1,6 @@ use arrow::array::{ - Array as ArrowArray, ArrayRef as ArrowArrayRef, StructArray as ArrowStructArray, + Array as ArrowArray, ArrayRef as ArrowArrayRef, RecordBatch as ArrowRecordBatch, + StructArray as ArrowStructArray, }; use arrow2::{ array::{Array as Arrow2Array, ListArray}, @@ -69,6 +70,48 @@ impl std::fmt::Display for TransportChunk { } } +impl TransportChunk { + pub fn new( + schema: impl Into, + columns: impl Into>>, + ) -> Self { + Self { + schema: schema.into(), + data: columns.into(), + } + } +} + +impl From for TransportChunk { + fn from(batch: ArrowRecordBatch) -> Self { + Self::new( + batch.schema(), + Arrow2Chunk::new( + batch + .columns() + .iter() + .map(|column| column.clone().into()) + .collect(), + ), + ) + } +} + +impl TryFrom for ArrowRecordBatch { + type Error = arrow::error::ArrowError; + + fn try_from(chunk: TransportChunk) -> Result { + let TransportChunk { schema, data } = chunk; + Self::try_new( + schema.into(), + data.columns() + .iter() + .map(|column| column.clone().into()) + .collect(), + ) + } +} + // TODO(#6572): Relying on Arrow's native schema metadata feature is bound to fail, we need to // switch to something more powerful asap. impl TransportChunk { @@ -301,6 +344,11 @@ impl TransportChunk { .and_then(|s| s.parse::().ok()) } + #[inline] + pub fn schema_ref(&self) -> &Arrow2Schema { + &self.schema + } + /// Looks in the chunk metadata for the `IS_SORTED` marker. /// /// It is possible that a chunk is sorted but didn't set that marker. @@ -541,10 +589,11 @@ impl Chunk { } } - Ok(TransportChunk { - schema, - data: Arrow2Chunk::new(columns), - }) + Ok(TransportChunk::new(schema, Arrow2Chunk::new(columns))) + } + + pub fn from_record_batch(batch: ArrowRecordBatch) -> ChunkResult { + Self::from_transport(&batch.into()) } pub fn from_transport(transport: &TransportChunk) -> ChunkResult { @@ -694,15 +743,11 @@ impl Chunk { let re_log_types::ArrowMsg { chunk_id: _, timepoint_max: _, - schema, - chunk, + batch, on_release: _, } = msg; - Self::from_transport(&TransportChunk { - schema: schema.clone(), - data: chunk.clone(), - }) + Self::from_record_batch(batch.clone()) } #[inline] @@ -714,8 +759,7 @@ impl Chunk { Ok(re_log_types::ArrowMsg { chunk_id: re_tuid::Tuid::from_u128(self.id().as_u128()), timepoint_max: self.timepoint_max(), - schema: transport.schema, - chunk: transport.data, + batch: transport.try_into()?, on_release: None, }) } @@ -805,14 +849,10 @@ mod tests { for _ in 0..3 { let chunk_in_transport = chunk_before.to_transport()?; #[cfg(feature = "arrow")] - let chunk_after = { - let chunk_in_record_batch = chunk_in_transport.try_to_arrow_record_batch()?; - let chunk_roundtrip = - TransportChunk::from_arrow_record_batch(&chunk_in_record_batch); - Chunk::from_transport(&chunk_roundtrip)? - }; + let chunk_after = + Chunk::from_record_batch(chunk_in_transport.try_to_arrow_record_batch()?)?; #[cfg(not(feature = "arrow"))] - let chunk_after = { Chunk::from_transport(&chunk_in_transport)? }; + let chunk_after = Chunk::from_transport(&chunk_in_transport)?; assert_eq!( chunk_in_transport.entity_path()?, diff --git a/crates/store/re_chunk_store/src/store.rs b/crates/store/re_chunk_store/src/store.rs index 7bf10cb1e8ed..bb2facfdafec 100644 --- a/crates/store/re_chunk_store/src/store.rs +++ b/crates/store/re_chunk_store/src/store.rs @@ -6,7 +6,7 @@ use arrow::datatypes::DataType as ArrowDataType; use arrow2::datatypes::DataType as Arrow2DataType; use nohash_hasher::IntMap; -use re_chunk::{Chunk, ChunkId, RowId, TransportChunk}; +use re_chunk::{Chunk, ChunkId, RowId}; use re_log_types::{EntityPath, StoreId, StoreInfo, TimeInt, Timeline}; use re_types_core::{ComponentDescriptor, ComponentName}; @@ -734,12 +734,7 @@ impl ChunkStore { anyhow::bail!("unknown store ID: {store_id}"); }; - let transport = TransportChunk { - schema: msg.schema.clone(), - data: msg.chunk.clone(), - }; - - let chunk = Chunk::from_transport(&transport) + let chunk = Chunk::from_arrow_msg(&msg) .with_context(|| format!("couldn't decode chunk {path_to_rrd:?}"))?; store @@ -787,12 +782,7 @@ impl ChunkStore { anyhow::bail!("unknown store ID: {store_id}"); }; - let transport = TransportChunk { - schema: msg.schema.clone(), - data: msg.chunk.clone(), - }; - - let chunk = Chunk::from_transport(&transport) + let chunk = Chunk::from_arrow_msg(&msg) .with_context(|| "couldn't decode chunk".to_owned())?; store diff --git a/crates/store/re_dataframe/src/query.rs b/crates/store/re_dataframe/src/query.rs index 8a1f76e2ce00..16801c116489 100644 --- a/crates/store/re_dataframe/src/query.rs +++ b/crates/store/re_dataframe/src/query.rs @@ -1268,10 +1268,10 @@ impl QueryHandle { /// See [`Self::next_row`] for more information. #[inline] pub fn next_row_batch(&self) -> Option { - Some(RecordBatch { - schema: self.schema().clone(), - data: Arrow2Chunk::new(self.next_row_arrow2()?), - }) + Some(RecordBatch::new( + self.schema().clone(), + Arrow2Chunk::new(self.next_row_arrow2()?), + )) } #[inline] @@ -1286,10 +1286,7 @@ impl QueryHandle { #[allow(clippy::unwrap_used)] let schema = self.state.get().unwrap().arrow_schema.clone(); - Some(RecordBatch { - schema, - data: Arrow2Chunk::new(row), - }) + Some(RecordBatch::new(schema, Arrow2Chunk::new(row))) } } diff --git a/crates/store/re_grpc_client/src/lib.rs b/crates/store/re_grpc_client/src/lib.rs index c1514ece5c5c..75bb835ec146 100644 --- a/crates/store/re_grpc_client/src/lib.rs +++ b/crates/store/re_grpc_client/src/lib.rs @@ -283,7 +283,7 @@ pub fn store_info_from_catalog_chunk( .as_any() .downcast_ref::>() .ok_or(StreamError::ChunkError(re_chunk::ChunkError::Malformed { - reason: format!("application_id must be a utf8 array: {:?}", tc.schema), + reason: format!("application_id must be a utf8 array: {:?}", tc.schema_ref()), }))? .value(0); @@ -297,7 +297,7 @@ pub fn store_info_from_catalog_chunk( .as_any() .downcast_ref::() .ok_or(StreamError::ChunkError(re_chunk::ChunkError::Malformed { - reason: format!("start_time must be an int64 array: {:?}", tc.schema), + reason: format!("start_time must be an int64 array: {:?}", tc.schema_ref()), }))? .value(0); @@ -456,10 +456,7 @@ async fn stream_catalog_async( ); // modified and enriched TransportChunk - let mut tc = TransportChunk { - schema, - data: arrow2::chunk::Chunk::new(arrays), - }; + let mut tc = TransportChunk::new(schema, arrow2::chunk::Chunk::new(arrays)); tc.schema.metadata.insert( TransportChunk::CHUNK_METADATA_KEY_ID.to_owned(), diff --git a/crates/store/re_log_encoding/Cargo.toml b/crates/store/re_log_encoding/Cargo.toml index 5fd58ed1ae61..abe9378978f3 100644 --- a/crates/store/re_log_encoding/Cargo.toml +++ b/crates/store/re_log_encoding/Cargo.toml @@ -51,6 +51,7 @@ re_smart_channel.workspace = true re_tracing.workspace = true # External: +arrow = { workspace = true, features = ["ipc"] } arrow2.workspace = true parking_lot.workspace = true thiserror.workspace = true @@ -74,6 +75,7 @@ re_types.workspace = true criterion.workspace = true mimalloc.workspace = true serde_test.workspace = true +similar-asserts.workspace = true [lib] bench = false diff --git a/crates/store/re_log_encoding/benches/msg_encode_benchmark.rs b/crates/store/re_log_encoding/benches/msg_encode_benchmark.rs index 40c72e5a906b..4dd962f62f51 100644 --- a/crates/store/re_log_encoding/benches/msg_encode_benchmark.rs +++ b/crates/store/re_log_encoding/benches/msg_encode_benchmark.rs @@ -7,7 +7,7 @@ compile_error!("msg_encode_benchmark requires 'decoder' and 'encoder' features." #[global_allocator] static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; -use re_chunk::{Chunk, RowId, TransportChunk}; +use re_chunk::{Chunk, RowId}; use re_log_types::{ entity_path, example_components::{MyColor, MyPoint}, @@ -73,11 +73,7 @@ fn decode_chunks(messages: &[LogMsg]) -> Vec { .iter() .map(|log_msg| { if let LogMsg::ArrowMsg(_, arrow_msg) = log_msg { - Chunk::from_transport(&TransportChunk { - schema: arrow_msg.schema.clone(), - data: arrow_msg.chunk.clone(), - }) - .unwrap() + Chunk::from_arrow_msg(arrow_msg).unwrap() } else { unreachable!() } diff --git a/crates/store/re_log_encoding/src/codec/arrow.rs b/crates/store/re_log_encoding/src/codec/arrow.rs index ae7cddabe27e..84a50a086ab6 100644 --- a/crates/store/re_log_encoding/src/codec/arrow.rs +++ b/crates/store/re_log_encoding/src/codec/arrow.rs @@ -1,51 +1,86 @@ use super::CodecError; -use arrow2::array::Array as Arrow2Array; -use arrow2::datatypes::Schema as Arrow2Schema; -use arrow2::io::ipc; +use arrow::array::RecordBatch as ArrowRecordBatch; -type Arrow2Chunk = arrow2::chunk::Chunk>; +/// TODO(#3741): switch to arrow1 once is released +const SERIALIZE_WITH_ARROW_1: bool = false; // I _think_ we can use arrow1 here, because we don't encounter the above bug in this context +const DESERIALIZE_WITH_ARROW_1: bool = true; // Both arrow1 and arrow2 should be working fine /// Helper function that serializes given arrow schema and record batch into bytes /// using Arrow IPC format. pub(crate) fn write_arrow_to_bytes( writer: &mut W, - schema: &Arrow2Schema, - data: &Arrow2Chunk, + batch: &ArrowRecordBatch, ) -> Result<(), CodecError> { - let options = ipc::write::WriteOptions { compression: None }; - let mut sw = ipc::write::StreamWriter::new(writer, options); + if SERIALIZE_WITH_ARROW_1 { + #[allow(clippy::disallowed_types)] // it's behind a disabled feature flag + let mut sw = arrow::ipc::writer::StreamWriter::try_new(writer, batch.schema_ref()) + .map_err(CodecError::ArrowSerialization)?; + sw.write(batch).map_err(CodecError::ArrowSerialization)?; + sw.finish().map_err(CodecError::ArrowSerialization)?; + } else { + let schema = arrow2::datatypes::Schema::from(batch.schema()); + let chunk = arrow2::chunk::Chunk::new( + batch + .columns() + .iter() + .map(|c| -> Box { c.clone().into() }) + .collect(), + ); - sw.start(schema, None) - .map_err(CodecError::ArrowSerialization)?; - sw.write(data, None) - .map_err(CodecError::ArrowSerialization)?; - sw.finish().map_err(CodecError::ArrowSerialization)?; + let mut writer = arrow2::io::ipc::write::StreamWriter::new(writer, Default::default()); + writer + .start(&schema, None) + .map_err(CodecError::Arrow2Serialization)?; + writer + .write(&chunk, None) + .map_err(CodecError::Arrow2Serialization)?; + writer.finish().map_err(CodecError::Arrow2Serialization)?; + } Ok(()) } /// Helper function that deserializes raw bytes into arrow schema and record batch /// using Arrow IPC format. +/// +/// Returns only the first record batch in the stream. pub(crate) fn read_arrow_from_bytes( reader: &mut R, -) -> Result<(Arrow2Schema, Arrow2Chunk), CodecError> { - use arrow2::io::ipc; - - let metadata = - ipc::read::read_stream_metadata(reader).map_err(CodecError::ArrowSerialization)?; - let mut stream = ipc::read::StreamReader::new(reader, metadata, None); - - let schema = stream.schema().clone(); - // there should be at least one record batch in the stream - let stream_state = stream - .next() - .ok_or(CodecError::MissingRecordBatch)? - .map_err(CodecError::ArrowSerialization)?; - - match stream_state { - ipc::read::StreamState::Waiting => Err(CodecError::UnexpectedStreamState), - ipc::read::StreamState::Some(chunk) => Ok((schema, chunk)), +) -> Result { + if DESERIALIZE_WITH_ARROW_1 { + let mut stream = arrow::ipc::reader::StreamReader::try_new(reader, None) + .map_err(CodecError::ArrowDeserialization)?; + + stream + .next() + .ok_or(CodecError::MissingRecordBatch)? + .map_err(CodecError::ArrowDeserialization) + } else { + use arrow2::io::ipc; + + let metadata = + ipc::read::read_stream_metadata(reader).map_err(CodecError::Arrow2Serialization)?; + let mut stream = ipc::read::StreamReader::new(reader, metadata, None); + + let schema = stream.schema().clone(); + // there should be at least one record batch in the stream + let stream_state = stream + .next() + .ok_or(CodecError::MissingRecordBatch)? + .map_err(CodecError::Arrow2Serialization)?; + + match stream_state { + ipc::read::StreamState::Waiting => Err(CodecError::UnexpectedStreamState), + ipc::read::StreamState::Some(chunk) => { + let batch = ArrowRecordBatch::try_new( + schema.into(), + chunk.columns().iter().map(|c| c.clone().into()).collect(), + ) + .map_err(CodecError::ArrowDeserialization)?; + Ok(batch) + } + } } } @@ -57,12 +92,11 @@ pub(crate) struct Payload { #[cfg(feature = "encoder")] pub(crate) fn encode_arrow( - schema: &Arrow2Schema, - chunk: &Arrow2Chunk, + batch: &ArrowRecordBatch, compression: crate::Compression, ) -> Result { let mut uncompressed = Vec::new(); - write_arrow_to_bytes(&mut uncompressed, schema, chunk)?; + write_arrow_to_bytes(&mut uncompressed, batch)?; let uncompressed_size = uncompressed.len(); let data = match compression { @@ -81,7 +115,7 @@ pub(crate) fn decode_arrow( data: &[u8], uncompressed_size: usize, compression: crate::Compression, -) -> Result<(Arrow2Schema, Arrow2Chunk), crate::decoder::DecodeError> { +) -> Result { let mut uncompressed = Vec::new(); let data = match compression { crate::Compression::Off => data, diff --git a/crates/store/re_log_encoding/src/codec/file/decoder.rs b/crates/store/re_log_encoding/src/codec/file/decoder.rs index 16b6f0ba4728..a9fe39e652b2 100644 --- a/crates/store/re_log_encoding/src/codec/file/decoder.rs +++ b/crates/store/re_log_encoding/src/codec/file/decoder.rs @@ -27,7 +27,7 @@ pub(crate) fn decode(data: &mut impl std::io::Read) -> Result<(u64, Option Result<(u64, Option { - let payload = encode_arrow(&arrow_msg.schema, &arrow_msg.chunk, compression)?; + let payload = encode_arrow(&arrow_msg.batch, compression)?; let arrow_msg = ArrowMsg { store_id: Some(store_id.clone().into()), compression: match compression { diff --git a/crates/store/re_log_encoding/src/codec/mod.rs b/crates/store/re_log_encoding/src/codec/mod.rs index 647c2fc156e0..6f143be06875 100644 --- a/crates/store/re_log_encoding/src/codec/mod.rs +++ b/crates/store/re_log_encoding/src/codec/mod.rs @@ -4,8 +4,17 @@ pub mod wire; #[derive(Debug, thiserror::Error)] pub enum CodecError { - #[error("Arrow serialization error: {0}")] - ArrowSerialization(arrow2::error::Error), + #[error("Arrow IPC serialization error: {0}")] + ArrowSerialization(::arrow::error::ArrowError), + + #[error("Arrow2 IPC serialization error: {0}")] + Arrow2Serialization(::arrow2::error::Error), + + #[error("Invalid Chunk: {0}")] + InvalidChunk(::arrow::error::ArrowError), + + #[error("Arrow IPC deserialization error: {0}")] + ArrowDeserialization(::arrow::error::ArrowError), #[error("Failed to decode message header {0}")] HeaderDecoding(std::io::Error), diff --git a/crates/store/re_log_encoding/src/codec/wire/decoder.rs b/crates/store/re_log_encoding/src/codec/wire/decoder.rs index cc325830c59a..8df9ae1ca0e0 100644 --- a/crates/store/re_log_encoding/src/codec/wire/decoder.rs +++ b/crates/store/re_log_encoding/src/codec/wire/decoder.rs @@ -12,14 +12,8 @@ fn decode( match version { re_protos::common::v0::EncoderVersion::V0 => { let mut reader = std::io::Cursor::new(data); - let (schema, data) = read_arrow_from_bytes(&mut reader)?; - - let tc = TransportChunk { - schema: schema.clone(), - data, - }; - - Ok(tc) + let batch = read_arrow_from_bytes(&mut reader)?; + Ok(batch.into()) } } } diff --git a/crates/store/re_log_encoding/src/codec/wire/encoder.rs b/crates/store/re_log_encoding/src/codec/wire/encoder.rs index 1b6b8e4443c4..58c8a95dca4c 100644 --- a/crates/store/re_log_encoding/src/codec/wire/encoder.rs +++ b/crates/store/re_log_encoding/src/codec/wire/encoder.rs @@ -9,11 +9,12 @@ fn encode( version: re_protos::common::v0::EncoderVersion, chunk: &TransportChunk, ) -> Result, CodecError> { + let transport_chunk = + arrow::array::RecordBatch::try_from(chunk.clone()).map_err(CodecError::InvalidChunk)?; match version { re_protos::common::v0::EncoderVersion::V0 => { let mut data: Vec = Vec::new(); - write_arrow_to_bytes(&mut data, &chunk.schema, &chunk.data)?; - + write_arrow_to_bytes(&mut data, &transport_chunk)?; Ok(data) } } diff --git a/crates/store/re_log_encoding/src/codec/wire/mod.rs b/crates/store/re_log_encoding/src/codec/wire/mod.rs index 5125ea662a5e..a08cd28a810a 100644 --- a/crates/store/re_log_encoding/src/codec/wire/mod.rs +++ b/crates/store/re_log_encoding/src/codec/wire/mod.rs @@ -43,10 +43,11 @@ mod tests { }; let decoded = dataframe_part.decode(); - assert!(matches!( - decoded.err().unwrap(), - CodecError::ArrowSerialization(_) - )); + let error = decoded.err().unwrap(); + assert!( + matches!(error, CodecError::ArrowDeserialization(_)), + "Expected CodecError::ArrowDeserialization; got {error:?}" + ); } #[test] diff --git a/crates/store/re_log_encoding/src/decoder/mod.rs b/crates/store/re_log_encoding/src/decoder/mod.rs index 50f6517f9a75..0c10b855b9fc 100644 --- a/crates/store/re_log_encoding/src/decoder/mod.rs +++ b/crates/store/re_log_encoding/src/decoder/mod.rs @@ -86,7 +86,7 @@ pub enum DecodeError { Chunk(#[from] re_chunk::ChunkError), #[error("Arrow error: {0}")] - Arrow(#[from] arrow2::error::Error), + Arrow(#[from] arrow::error::ArrowError), #[error("MsgPack error: {0}")] MsgPack(#[from] rmp_serde::decode::Error), @@ -411,9 +411,35 @@ mod tests { ApplicationId, SetStoreInfo, StoreId, StoreInfo, StoreKind, StoreSource, Time, }; + // TODO(#3741): remove this once we are all in on arrow-rs + fn strip_arrow_extensions_from_log_messages(log_msg: Vec) -> Vec { + log_msg + .into_iter() + .map(LogMsg::strip_arrow_extension_types) + .collect() + } + fn fake_log_messages() -> Vec { let store_id = StoreId::random(StoreKind::Blueprint); - vec![ + + let arrow_msg = re_chunk::Chunk::builder("test_entity".into()) + .with_archetype( + re_chunk::RowId::new(), + re_log_types::TimePoint::default().with( + re_log_types::Timeline::new_sequence("blueprint"), + re_log_types::TimeInt::from_milliseconds(re_log_types::NonMinI64::MIN), + ), + &re_types::blueprint::archetypes::Background::new( + re_types::blueprint::components::BackgroundKind::SolidColor, + ) + .with_color([255, 0, 0]), + ) + .build() + .unwrap() + .to_arrow_msg() + .unwrap(); + + strip_arrow_extensions_from_log_messages(vec![ LogMsg::SetStoreInfo(SetStoreInfo { row_id: *RowId::new(), info: StoreInfo { @@ -429,51 +455,20 @@ mod tests { store_version: Some(CrateVersion::LOCAL), }, }), - LogMsg::ArrowMsg( - store_id.clone(), - re_chunk::Chunk::builder("test_entity".into()) - .with_archetype( - re_chunk::RowId::new(), - re_log_types::TimePoint::default().with( - re_log_types::Timeline::new_sequence("blueprint"), - re_log_types::TimeInt::from_milliseconds(re_log_types::NonMinI64::MIN), - ), - &re_types::blueprint::archetypes::Background::new( - re_types::blueprint::components::BackgroundKind::SolidColor, - ) - .with_color([255, 0, 0]), - ) - .build() - .unwrap() - .to_arrow_msg() - .unwrap(), - ), + LogMsg::ArrowMsg(store_id.clone(), arrow_msg), LogMsg::BlueprintActivationCommand(re_log_types::BlueprintActivationCommand { blueprint_id: store_id, make_active: true, make_default: true, }), - ] - } - - // TODO(#3741): should not be needed once the migration from arrow2 is complete - fn clear_arrow_extension_metadata(messages: &mut Vec) { - for msg in messages { - if let LogMsg::ArrowMsg(_, arrow_msg) = msg { - for field in &mut arrow_msg.schema.fields { - field - .metadata - .retain(|k, _| !k.starts_with("ARROW:extension")); - } - } - } + ]) } #[test] fn test_encode_decode() { let rrd_version = CrateVersion::LOCAL; - let mut messages = fake_log_messages(); + let messages = fake_log_messages(); let options = [ EncodingOptions { @@ -499,19 +494,14 @@ mod tests { crate::encoder::encode_ref(rrd_version, options, messages.iter().map(Ok), &mut file) .unwrap(); - let mut decoded_messages = Decoder::new(VersionPolicy::Error, &mut file.as_slice()) - .unwrap() - .collect::, DecodeError>>() - .unwrap(); - - // TODO(#3741): should not be needed once the migration from arrow2 is complete - clear_arrow_extension_metadata(&mut messages); - clear_arrow_extension_metadata(&mut decoded_messages); - - assert!( - messages == decoded_messages, - "Got: {decoded_messages:#?}, expected: {messages:#?}" + let decoded_messages = strip_arrow_extensions_from_log_messages( + Decoder::new(VersionPolicy::Error, &mut file.as_slice()) + .unwrap() + .collect::, DecodeError>>() + .unwrap(), ); + + similar_asserts::assert_eq!(decoded_messages, messages); } } @@ -542,7 +532,7 @@ mod tests { let mut data = vec![]; // write "2 files" i.e. 2 streams that end with end-of-stream marker - let mut messages = fake_log_messages(); + let messages = fake_log_messages(); // (2 encoders as each encoder writes a file header) let writer = std::io::Cursor::new(&mut data); @@ -569,13 +559,11 @@ mod tests { ) .unwrap(); - let mut decoded_messages = decoder.into_iter().collect::, _>>().unwrap(); - - // TODO(#3741): should not be needed once the migration from arrow2 is complete - clear_arrow_extension_metadata(&mut messages); - clear_arrow_extension_metadata(&mut decoded_messages); + let decoded_messages = strip_arrow_extensions_from_log_messages( + decoder.into_iter().collect::, _>>().unwrap(), + ); - assert_eq!([messages.clone(), messages].concat(), decoded_messages); + similar_asserts::assert_eq!(decoded_messages, [messages.clone(), messages].concat()); } } } diff --git a/crates/store/re_log_encoding/src/encoder.rs b/crates/store/re_log_encoding/src/encoder.rs index 47fd4bdffa2e..8daebfa2c99c 100644 --- a/crates/store/re_log_encoding/src/encoder.rs +++ b/crates/store/re_log_encoding/src/encoder.rs @@ -28,7 +28,7 @@ pub enum EncodeError { Protobuf(#[from] re_protos::external::prost::EncodeError), #[error("Arrow error: {0}")] - Arrow(#[from] arrow2::error::Error), + Arrow(#[from] arrow::error::ArrowError), #[error("{0}")] Codec(#[from] codec::CodecError), diff --git a/crates/store/re_log_encoding/src/protobuf_conversions.rs b/crates/store/re_log_encoding/src/protobuf_conversions.rs index f3193575907a..33a6181fd483 100644 --- a/crates/store/re_log_encoding/src/protobuf_conversions.rs +++ b/crates/store/re_log_encoding/src/protobuf_conversions.rs @@ -36,7 +36,7 @@ pub fn log_msg_from_proto( return Err(DecodeError::Codec(CodecError::UnsupportedEncoding)); } - let (schema, chunk) = decode_arrow( + let batch = decode_arrow( &arrow_msg.payload, arrow_msg.uncompressed_size as usize, arrow_msg.compression().into(), @@ -47,10 +47,7 @@ pub fn log_msg_from_proto( .ok_or_else(|| missing_field!(re_protos::log_msg::v0::ArrowMsg, "store_id"))? .into(); - let chunk = re_chunk::Chunk::from_transport(&re_chunk::TransportChunk { - schema, - data: chunk, - })?; + let chunk = re_chunk::Chunk::from_record_batch(batch)?; Ok(re_log_types::LogMsg::ArrowMsg( store_id, @@ -86,7 +83,7 @@ pub fn log_msg_to_proto( } } re_log_types::LogMsg::ArrowMsg(store_id, arrow_msg) => { - let payload = encode_arrow(&arrow_msg.schema, &arrow_msg.chunk, compression)?; + let payload = encode_arrow(&arrow_msg.batch, compression)?; let arrow_msg = ArrowMsg { store_id: Some(store_id.into()), compression: match compression { diff --git a/crates/store/re_log_encoding/tests/arrow_encode_roundtrip.rs b/crates/store/re_log_encoding/tests/arrow_encode_roundtrip.rs new file mode 100644 index 000000000000..de3fb567958b --- /dev/null +++ b/crates/store/re_log_encoding/tests/arrow_encode_roundtrip.rs @@ -0,0 +1,66 @@ +use re_build_info::CrateVersion; +use re_chunk::{Chunk, RowId, TimePoint, Timeline}; +use re_log_encoding::{ + decoder::decode_bytes, encoder::encode_as_bytes, EncodingOptions, VersionPolicy, +}; +use re_log_types::{LogMsg, StoreId}; +use re_types::archetypes::Points3D; + +fn no_radii() -> impl Iterator { + std::iter::empty() +} + +#[test] +fn encode_roundtrip() { + fn timepoint(time: i64) -> TimePoint { + TimePoint::default().with(Timeline::new_sequence("my_index"), time) + } + + let chunk = Chunk::builder("points".into()) + .with_archetype( + RowId::new(), + timepoint(1), + &Points3D::new([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]]).with_radii(no_radii()), + ) + .with_archetype( + RowId::new(), + timepoint(1), + &Points3D::new([[10., 11., 12.]]).with_colors([[255, 0, 0]]), + ) + .build() + .unwrap(); + + let transport = chunk.to_transport().unwrap(); + assert_eq!(Chunk::from_transport(&transport).unwrap(), chunk); + + let arrow_msg = chunk.to_arrow_msg().unwrap(); + assert_eq!(Chunk::from_arrow_msg(&arrow_msg).unwrap(), chunk); + + let store_id = StoreId::empty_recording(); + let messages = [LogMsg::ArrowMsg(store_id, arrow_msg)]; + + for option in [ + EncodingOptions::MSGPACK_UNCOMPRESSED, + EncodingOptions::MSGPACK_COMPRESSED, + EncodingOptions::PROTOBUF_COMPRESSED, + ] { + let crate_version = CrateVersion::LOCAL; + let encoded = + encode_as_bytes(crate_version, option, messages.iter().cloned().map(Ok)).unwrap(); + let decoded = decode_bytes(VersionPolicy::Error, &encoded).unwrap(); + similar_asserts::assert_eq!( + strip_arrow_extensions_from_log_messages(&decoded), + strip_arrow_extensions_from_log_messages(&messages), + "Failed to roundtrip chunk with option {option:?}" + ); + } +} + +// TODO(#3741): remove this once we are all in on arrow-rs +fn strip_arrow_extensions_from_log_messages(log_msg: &[LogMsg]) -> Vec { + log_msg + .iter() + .cloned() + .map(LogMsg::strip_arrow_extension_types) + .collect() +} diff --git a/crates/store/re_log_types/Cargo.toml b/crates/store/re_log_types/Cargo.toml index d83b0dc6a681..fcf98b9794e7 100644 --- a/crates/store/re_log_types/Cargo.toml +++ b/crates/store/re_log_types/Cargo.toml @@ -56,12 +56,8 @@ re_types_core.workspace = true # External ahash.workspace = true anyhow.workspace = true -arrow.workspace = true -arrow2 = { workspace = true, features = [ - "io_ipc", - "io_print", - "compute_concatenate", -] } +arrow = { workspace = true, features = ["ipc"] } +arrow2 = { workspace = true, features = ["io_print", "compute_concatenate"] } backtrace.workspace = true bytemuck.workspace = true clean-path.workspace = true diff --git a/crates/store/re_log_types/src/arrow_msg.rs b/crates/store/re_log_types/src/arrow_msg.rs index d680ec5aa2b0..6a02c767f5f6 100644 --- a/crates/store/re_log_types/src/arrow_msg.rs +++ b/crates/store/re_log_types/src/arrow_msg.rs @@ -1,17 +1,20 @@ //! [`ArrowMsg`] is the [`crate::LogMsg`] sub-type containing an Arrow payload. //! //! We have custom implementations of [`serde::Serialize`] and [`serde::Deserialize`] that wraps -//! the inner Arrow serialization of [`Arrow2Schema`] and [`Arrow2Chunk`]. +//! the inner Arrow serialization of an [`ArrowRecordBatch`]. use std::sync::Arc; +use arrow::array::RecordBatch as ArrowRecordBatch; + use crate::TimePoint; -use arrow2::{ - array::Array as Arrow2Array, chunk::Chunk as Arrow2Chunk, datatypes::Schema as Arrow2Schema, -}; + +// TODO(#3741): Remove once is released +const SERIALIZE_WITH_ARROW_1: bool = false; +const DESERIALIZE_WITH_ARROW_1: bool = true; // Both arrow1 and arrow2 should be working fine /// An arbitrary callback to be run when an [`ArrowMsg`], and more specifically the -/// [`Arrow2Chunk`] within it, goes out of scope. +/// [`ArrowRecordBatch`] within it, goes out of scope. /// /// If the [`ArrowMsg`] has been cloned in a bunch of places, the callback will run for each and /// every instance. @@ -20,10 +23,10 @@ use arrow2::{ // TODO(#6412): probably don't need this anymore. #[allow(clippy::type_complexity)] #[derive(Clone)] -pub struct ArrowChunkReleaseCallback(Arc>) + Send + Sync>); +pub struct ArrowRecordBatchReleaseCallback(Arc); -impl std::ops::Deref for ArrowChunkReleaseCallback { - type Target = dyn Fn(Arrow2Chunk>) + Send + Sync; +impl std::ops::Deref for ArrowRecordBatchReleaseCallback { + type Target = dyn Fn(ArrowRecordBatch) + Send + Sync; #[inline] fn deref(&self) -> &Self::Target { @@ -31,9 +34,9 @@ impl std::ops::Deref for ArrowChunkReleaseCallback { } } -impl From for ArrowChunkReleaseCallback +impl From for ArrowRecordBatchReleaseCallback where - F: Fn(Arrow2Chunk>) + Send + Sync + 'static, + F: Fn(ArrowRecordBatch) + Send + Sync + 'static, { #[inline] fn from(f: F) -> Self { @@ -41,26 +44,26 @@ where } } -impl ArrowChunkReleaseCallback { +impl ArrowRecordBatchReleaseCallback { #[inline] fn as_ptr(&self) -> *const () { Arc::as_ptr(&self.0).cast::<()>() } } -impl PartialEq for ArrowChunkReleaseCallback { +impl PartialEq for ArrowRecordBatchReleaseCallback { #[inline] fn eq(&self, other: &Self) -> bool { Arc::ptr_eq(&self.0, &other.0) } } -impl Eq for ArrowChunkReleaseCallback {} +impl Eq for ArrowRecordBatchReleaseCallback {} -impl std::fmt::Debug for ArrowChunkReleaseCallback { +impl std::fmt::Debug for ArrowRecordBatchReleaseCallback { #[inline] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("ArrowChunkReleaseCallback") + f.debug_tuple("ArrowRecordBatchReleaseCallback") .field(&format!("{:p}", self.as_ptr())) .finish() } @@ -79,20 +82,16 @@ pub struct ArrowMsg { /// deserialize the arrow payload. pub timepoint_max: TimePoint, - /// Schema for all control & data columns. - pub schema: Arrow2Schema, + /// Schema and data for all control & data columns. + pub batch: ArrowRecordBatch, - /// Data for all control & data columns. - pub chunk: Arrow2Chunk>, - - // pub on_release: Option>, - pub on_release: Option, + pub on_release: Option, } impl Drop for ArrowMsg { fn drop(&mut self) { if let Some(on_release) = self.on_release.take() { - (*on_release)(self.chunk.clone() /* shallow */); + (*on_release)(self.batch.clone() /* shallow */); } } } @@ -104,26 +103,48 @@ impl serde::Serialize for ArrowMsg { S: serde::Serializer, { re_tracing::profile_scope!("ArrowMsg::serialize"); - - use arrow2::io::ipc::write::StreamWriter; use serde::ser::SerializeTuple; - let mut buf = Vec::::new(); - let mut writer = StreamWriter::new(&mut buf, Default::default()); - writer - .start(&self.schema, None) - .map_err(|err| serde::ser::Error::custom(err.to_string()))?; - writer - .write(&self.chunk, None) - .map_err(|err| serde::ser::Error::custom(err.to_string()))?; - writer - .finish() - .map_err(|err| serde::ser::Error::custom(err.to_string()))?; + let mut ipc_bytes = Vec::::new(); + + if SERIALIZE_WITH_ARROW_1 { + #[allow(clippy::disallowed_types)] // it's behind a disabled feature flag + let mut writer = + arrow::ipc::writer::StreamWriter::try_new(&mut ipc_bytes, self.batch.schema_ref()) + .map_err(|err| serde::ser::Error::custom(err.to_string()))?; + writer + .write(&self.batch) + .map_err(|err| serde::ser::Error::custom(err.to_string()))?; + writer + .finish() + .map_err(|err| serde::ser::Error::custom(err.to_string()))?; + } else { + let schema = arrow2::datatypes::Schema::from(self.batch.schema()); + let chunk = arrow2::chunk::Chunk::new( + self.batch + .columns() + .iter() + .map(|c| -> Box { c.clone().into() }) + .collect(), + ); + + let mut writer = + arrow2::io::ipc::write::StreamWriter::new(&mut ipc_bytes, Default::default()); + writer + .start(&schema, None) + .map_err(|err| serde::ser::Error::custom(err.to_string()))?; + writer + .write(&chunk, None) + .map_err(|err| serde::ser::Error::custom(err.to_string()))?; + writer + .finish() + .map_err(|err| serde::ser::Error::custom(err.to_string()))?; + } let mut inner = serializer.serialize_tuple(3)?; inner.serialize_element(&self.chunk_id)?; inner.serialize_element(&self.timepoint_max)?; - inner.serialize_element(&serde_bytes::ByteBuf::from(buf))?; + inner.serialize_element(&serde_bytes::ByteBuf::from(ipc_bytes))?; inner.end() } } @@ -134,8 +155,6 @@ impl<'de> serde::Deserialize<'de> for ArrowMsg { where D: serde::Deserializer<'de>, { - use arrow2::io::ipc::read::{read_stream_metadata, StreamReader, StreamState}; - struct FieldVisitor; impl<'de> serde::de::Visitor<'de> for FieldVisitor { @@ -153,54 +172,97 @@ impl<'de> serde::Deserialize<'de> for ArrowMsg { let table_id: Option = seq.next_element()?; let timepoint_max: Option = seq.next_element()?; - let buf: Option = seq.next_element()?; + let ipc_bytes: Option = seq.next_element()?; if let (Some(chunk_id), Some(timepoint_max), Some(buf)) = - (table_id, timepoint_max, buf) + (table_id, timepoint_max, ipc_bytes) { let mut cursor = std::io::Cursor::new(buf); - let metadata = match read_stream_metadata(&mut cursor) { - Ok(metadata) => metadata, - Err(err) => { + + if DESERIALIZE_WITH_ARROW_1 { + use arrow::ipc::reader::StreamReader; + + let stream = StreamReader::try_new(cursor, None).map_err(|err| { + serde::de::Error::custom(format!("Arrow error: {err}")) + })?; + let batches: Result, _> = stream.collect(); + + let batches = batches.map_err(|err| { + serde::de::Error::custom(format!("Arrow error: {err}")) + })?; + + if batches.is_empty() { + return Err(serde::de::Error::custom("No RecordBatch in stream")); + } + if batches.len() > 1 { return Err(serde::de::Error::custom(format!( - "Failed to read stream metadata: {err}" - ))) + "Found {} batches in stream - expected just one.", + batches.len() + ))); } - }; - let schema = metadata.schema.clone(); - let stream = StreamReader::new(cursor, metadata, None); - let chunks: Result, _> = stream - .map(|state| match state { - Ok(StreamState::Some(chunk)) => Ok(chunk), - Ok(StreamState::Waiting) => { - unreachable!("cannot be waiting on a fixed buffer") - } - Err(err) => Err(err), + #[allow(clippy::unwrap_used)] // is_empty check above + let batch = batches.into_iter().next().unwrap(); + + Ok(ArrowMsg { + chunk_id, + timepoint_max, + batch, + on_release: None, }) - .collect(); + } else { + use arrow2::io::ipc::read::{ + read_stream_metadata, StreamReader, StreamState, + }; + + let metadata = match read_stream_metadata(&mut cursor) { + Ok(metadata) => metadata, + Err(err) => { + return Err(serde::de::Error::custom(format!( + "Failed to read stream metadata: {err}" + ))) + } + }; + let schema = metadata.schema.clone(); + let stream = StreamReader::new(cursor, metadata, None); + let chunks: Result, _> = stream + .map(|state| match state { + Ok(StreamState::Some(chunk)) => Ok(chunk), + Ok(StreamState::Waiting) => { + unreachable!("cannot be waiting on a fixed buffer") + } + Err(err) => Err(err), + }) + .collect(); + + let chunks = chunks.map_err(|err| { + serde::de::Error::custom(format!("Arrow error: {err}")) + })?; - let chunks = chunks + if chunks.is_empty() { + return Err(serde::de::Error::custom("No Arrow2Chunk found in stream")); + } + if chunks.len() > 1 { + return Err(serde::de::Error::custom(format!( + "Found {} chunks in stream - expected just one.", + chunks.len() + ))); + } + #[allow(clippy::unwrap_used)] // is_empty check above + let chunk = chunks.into_iter().next().unwrap(); + + let batch = ArrowRecordBatch::try_new( + schema.into(), + chunk.columns().iter().map(|c| c.clone().into()).collect(), + ) .map_err(|err| serde::de::Error::custom(format!("Arrow error: {err}")))?; - if chunks.is_empty() { - return Err(serde::de::Error::custom("No Arrow2Chunk found in stream")); - } - if chunks.len() > 1 { - return Err(serde::de::Error::custom(format!( - "Found {} chunks in stream - expected just one.", - chunks.len() - ))); + Ok(ArrowMsg { + chunk_id, + timepoint_max, + batch, + on_release: None, + }) } - #[allow(clippy::unwrap_used)] // is_empty check above - let chunk = chunks.into_iter().next().unwrap(); - - Ok(ArrowMsg { - chunk_id, - timepoint_max, - schema, - chunk, - on_release: None, - }) } else { Err(serde::de::Error::custom( "Expected (table_id, timepoint, buf)", diff --git a/crates/store/re_log_types/src/lib.rs b/crates/store/re_log_types/src/lib.rs index 7cc2768c42c7..cb4509f9594b 100644 --- a/crates/store/re_log_types/src/lib.rs +++ b/crates/store/re_log_types/src/lib.rs @@ -39,7 +39,7 @@ use std::sync::Arc; use re_build_info::CrateVersion; use re_byte_size::SizeBytes; -pub use self::arrow_msg::{ArrowChunkReleaseCallback, ArrowMsg}; +pub use self::arrow_msg::{ArrowMsg, ArrowRecordBatchReleaseCallback}; pub use self::instance::Instance; pub use self::path::*; pub use self::resolved_time_range::{ResolvedTimeRange, ResolvedTimeRangeF}; @@ -303,6 +303,18 @@ impl LogMsg { } } } + + // TODO(#3741): remove this once we are all in on arrow-rs + /// USE ONLY FOR TESTS + pub fn strip_arrow_extension_types(self) -> Self { + match self { + Self::ArrowMsg(store_id, mut arrow_msg) => { + strip_arrow_extension_types_from_batch(&mut arrow_msg.batch); + Self::ArrowMsg(store_id, arrow_msg) + } + other => other, + } + } } impl_into_enum!(SetStoreInfo, LogMsg, SetStoreInfo); @@ -746,15 +758,11 @@ impl SizeBytes for ArrowMsg { let Self { chunk_id, timepoint_max, - schema, - chunk, + batch, on_release: _, } = self; - chunk_id.heap_size_bytes() - + timepoint_max.heap_size_bytes() - + schema.heap_size_bytes() - + chunk.heap_size_bytes() + chunk_id.heap_size_bytes() + timepoint_max.heap_size_bytes() + batch.heap_size_bytes() } } @@ -773,6 +781,33 @@ impl SizeBytes for LogMsg { } } +/// USE ONLY FOR TESTS +// TODO(#3741): remove once is released +use arrow::array::RecordBatch as ArrowRecordBatch; + +pub fn strip_arrow_extension_types_from_batch(batch: &mut ArrowRecordBatch) { + use arrow::datatypes::{Field, Schema}; + + fn strip_arrow_extensions_from_field(field: &Field) -> Field { + let mut metadata = field.metadata().clone(); + metadata.retain(|key, _| !key.starts_with("ARROW:extension")); + field.clone().with_metadata(metadata) + } + + let old_schema = batch.schema(); + let new_fields: arrow::datatypes::Fields = old_schema + .fields() + .iter() + .map(|field| strip_arrow_extensions_from_field(field)) + .collect(); + let new_schema = Schema::new_with_metadata(new_fields, old_schema.metadata().clone()); + + #[allow(clippy::unwrap_used)] // The invariants of the input aren't changed + { + *batch = ArrowRecordBatch::try_new(new_schema.into(), batch.columns().to_vec()).unwrap(); + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/top/re_sdk/src/recording_stream.rs b/crates/top/re_sdk/src/recording_stream.rs index 7333056146a4..22f4efb9bea9 100644 --- a/crates/top/re_sdk/src/recording_stream.rs +++ b/crates/top/re_sdk/src/recording_stream.rs @@ -14,7 +14,7 @@ use re_chunk::{ ChunkId, PendingRow, RowId, TimeColumn, }; use re_log_types::{ - ApplicationId, ArrowChunkReleaseCallback, BlueprintActivationCommand, EntityPath, LogMsg, + ApplicationId, ArrowRecordBatchReleaseCallback, BlueprintActivationCommand, EntityPath, LogMsg, StoreId, StoreInfo, StoreKind, StoreSource, Time, TimeInt, TimePoint, TimeType, Timeline, TimelineName, }; @@ -1411,7 +1411,7 @@ fn forwarding_thread( mut sink: Box, cmds_rx: Receiver, chunks: Receiver, - on_release: Option, + on_release: Option, ) { /// Returns `true` to indicate that processing can continue; i.e. `false` means immediate /// shutdown. @@ -2350,7 +2350,6 @@ impl RecordingStream { #[cfg(test)] mod tests { - use re_chunk::TransportChunk; use re_log_types::example_components::MyLabel; use super::*; @@ -2410,11 +2409,7 @@ mod tests { LogMsg::ArrowMsg(rid, msg) => { assert_eq!(store_info.store_id, rid); - let chunk = Chunk::from_transport(&TransportChunk { - schema: msg.schema.clone(), - data: msg.chunk.clone(), - }) - .unwrap(); + let chunk = Chunk::from_arrow_msg(&msg).unwrap(); chunk.sanity_check().unwrap(); } @@ -2472,11 +2467,7 @@ mod tests { LogMsg::ArrowMsg(rid, msg) => { assert_eq!(store_info.store_id, rid); - let chunk = Chunk::from_transport(&TransportChunk { - schema: msg.schema.clone(), - data: msg.chunk.clone(), - }) - .unwrap(); + let chunk = Chunk::from_arrow_msg(&msg).unwrap(); chunk.sanity_check().unwrap(); } @@ -2543,11 +2534,7 @@ mod tests { LogMsg::ArrowMsg(rid, msg) => { assert_eq!(store_info.store_id, rid); - let chunk = Chunk::from_transport(&TransportChunk { - schema: msg.schema.clone(), - data: msg.chunk.clone(), - }) - .unwrap(); + let chunk = Chunk::from_arrow_msg(&msg).unwrap(); chunk.sanity_check().unwrap(); } diff --git a/crates/top/rerun/src/commands/rrd/compare.rs b/crates/top/rerun/src/commands/rrd/compare.rs index 901d71da750d..3faa45e09b2f 100644 --- a/crates/top/rerun/src/commands/rrd/compare.rs +++ b/crates/top/rerun/src/commands/rrd/compare.rs @@ -126,7 +126,8 @@ fn compute_uber_table( "more than one data recording found in rrd file" ); - let store = stores.pop().unwrap(); // safe, ensured above + #[allow(clippy::unwrap_used)] // safe, ensured above + let store = stores.pop().unwrap(); let engine = store.storage_engine(); Ok(( diff --git a/crates/top/rerun/src/commands/rrd/filter.rs b/crates/top/rerun/src/commands/rrd/filter.rs index b1e9ca2c0e5e..6b2256d4056a 100644 --- a/crates/top/rerun/src/commands/rrd/filter.rs +++ b/crates/top/rerun/src/commands/rrd/filter.rs @@ -1,10 +1,15 @@ use std::{collections::HashSet, io::IsTerminal}; use anyhow::Context as _; +use arrow::{ + array::RecordBatch as ArrowRecordBatch, + datatypes::{Field as ArrowField, Schema as ArrowSchema}, +}; use itertools::Either; use re_build_info::CrateVersion; use re_chunk::{external::crossbeam, TransportChunk}; +use re_sdk::{external::arrow, EntityPath}; use crate::commands::read_rrd_streams_from_file_or_stdin; @@ -106,22 +111,33 @@ impl FilterCommand { Ok(msg) => { let msg = match msg { re_log_types::LogMsg::ArrowMsg(store_id, mut msg) => { - if !should_keep_entity_path(&dropped_entity_paths, &msg.schema) { + if !should_keep_entity_path(&dropped_entity_paths, &msg.batch.schema()) + { None } else { - let (fields, columns): (Vec<_>, Vec<_>) = - itertools::izip!(msg.schema.fields.iter(), msg.chunk.iter()) - .filter(|(field, _col)| { - should_keep_timeline(&dropped_timelines, field) - }) - .map(|(field, col)| (field.clone(), col.clone())) - .unzip(); - - msg.schema.fields = fields; - msg.chunk = - re_log_types::external::arrow2::chunk::Chunk::new(columns); - - Some(re_log_types::LogMsg::ArrowMsg(store_id, msg)) + let (fields, columns): (Vec<_>, Vec<_>) = itertools::izip!( + &msg.batch.schema().fields, + msg.batch.columns() + ) + .filter(|(field, _col)| { + should_keep_timeline(&dropped_timelines, field) + }) + .map(|(field, col)| (field.clone(), col.clone())) + .unzip(); + + if let Ok(new_batch) = ArrowRecordBatch::try_new( + ArrowSchema::new_with_metadata( + fields, + msg.batch.schema().metadata().clone(), + ) + .into(), + columns, + ) { + msg.batch = new_batch; + Some(re_log_types::LogMsg::ArrowMsg(store_id, msg)) + } else { + None // Probably failed because we filtered out everything + } } } @@ -150,7 +166,7 @@ impl FilterCommand { let rrd_out_size = encoding_handle .context("couldn't spawn IO thread")? .join() - .unwrap()?; + .map_err(|err| anyhow::anyhow!("Unknown error: {err:?}"))??; // NOLINT: there is no `Display` for this `err` let rrds_in_size = rx_size_bytes.recv().ok(); let size_reduction = @@ -185,26 +201,21 @@ impl FilterCommand { // --- -use re_sdk::{ - external::arrow2::{datatypes::Field as ArrowField, datatypes::Schema as Arrow2Schema}, - EntityPath, -}; - fn should_keep_timeline(dropped_timelines: &HashSet<&String>, field: &ArrowField) -> bool { let is_timeline = field - .metadata + .metadata() .get(TransportChunk::FIELD_METADATA_KEY_KIND) .map(|s| s.as_str()) == Some(TransportChunk::FIELD_METADATA_VALUE_KIND_TIME); - let is_dropped = dropped_timelines.contains(&field.name); + let is_dropped = dropped_timelines.contains(field.name()); !is_timeline || !is_dropped } fn should_keep_entity_path( dropped_entity_paths: &HashSet, - schema: &Arrow2Schema, + schema: &ArrowSchema, ) -> bool { let Some(entity_path) = schema .metadata diff --git a/crates/top/rerun/src/lib.rs b/crates/top/rerun/src/lib.rs index 3386ccc73ddc..cdfe26a44eb2 100644 --- a/crates/top/rerun/src/lib.rs +++ b/crates/top/rerun/src/lib.rs @@ -102,8 +102,6 @@ //! See [`Logger`]. //! -// TODO(#6330): remove unwrap() -#![allow(clippy::unwrap_used)] #![warn(missing_docs)] // Let's keep the this crate well-documented! #[cfg(feature = "run")] diff --git a/crates/utils/re_byte_size/src/arrow_sizes.rs b/crates/utils/re_byte_size/src/arrow_sizes.rs index 862af2b8b583..b5d1bf45e1ec 100644 --- a/crates/utils/re_byte_size/src/arrow_sizes.rs +++ b/crates/utils/re_byte_size/src/arrow_sizes.rs @@ -1,7 +1,7 @@ use arrow::{ - array::{Array, ArrayRef}, + array::{Array, ArrayRef, RecordBatch}, buffer::ScalarBuffer, - datatypes::ArrowNativeType, + datatypes::{ArrowNativeType, DataType, Field, Fields, Schema, UnionFields}, }; use super::SizeBytes; @@ -33,3 +33,96 @@ impl SizeBytes for ScalarBuffer { self.inner().capacity() as _ } } + +impl SizeBytes for RecordBatch { + #[inline] + fn heap_size_bytes(&self) -> u64 { + self.schema().heap_size_bytes() + + self + .columns() + .iter() + .map(|array| array.heap_size_bytes()) + .sum::() + } +} + +impl SizeBytes for Schema { + #[inline] + fn heap_size_bytes(&self) -> u64 { + let Self { fields, metadata } = self; + fields.heap_size_bytes() + metadata.heap_size_bytes() + } +} + +impl SizeBytes for Fields { + #[inline] + fn heap_size_bytes(&self) -> u64 { + self.iter().map(|field| field.heap_size_bytes()).sum() + } +} + +impl SizeBytes for Field { + #[inline] + fn heap_size_bytes(&self) -> u64 { + self.name().heap_size_bytes() + self.data_type().heap_size_bytes() + } +} + +impl SizeBytes for DataType { + #[inline] + fn heap_size_bytes(&self) -> u64 { + match self { + Self::Null + | Self::Boolean + | Self::Int8 + | Self::Int16 + | Self::Int32 + | Self::Int64 + | Self::UInt8 + | Self::UInt16 + | Self::UInt32 + | Self::UInt64 + | Self::Float16 + | Self::Float32 + | Self::Float64 + | Self::Date32 + | Self::Date64 + | Self::Binary + | Self::LargeBinary + | Self::Utf8 + | Self::LargeUtf8 + | Self::BinaryView + | Self::Decimal128(_, _) + | Self::Decimal256(_, _) + | Self::FixedSizeBinary(_) + | Self::Utf8View => 0, + Self::Timestamp(_time_unit, _tz) => 0, + + Self::Time32(_time_unit) | Self::Time64(_time_unit) | Self::Duration(_time_unit) => 0, + + Self::Interval(_interval_unit) => 0, + + Self::List(field) + | Self::ListView(field) + | Self::FixedSizeList(field, _) + | Self::LargeList(field) + | Self::Map(field, _) + | Self::LargeListView(field) => field.heap_size_bytes(), + + Self::Union(fields, _) => fields.heap_size_bytes(), + Self::Struct(fields) => fields.heap_size_bytes(), + + Self::Dictionary(key, value) => key.heap_size_bytes() + value.heap_size_bytes(), + + Self::RunEndEncoded(field, field1) => { + field.heap_size_bytes() + field1.heap_size_bytes() + } + } + } +} + +impl SizeBytes for UnionFields { + fn heap_size_bytes(&self) -> u64 { + self.iter().map(|(_, field)| field.heap_size_bytes()).sum() + } +} diff --git a/crates/viewer/re_chunk_store_ui/src/chunk_ui.rs b/crates/viewer/re_chunk_store_ui/src/chunk_ui.rs index 2e9a4b0853c1..0efbee8c4067 100644 --- a/crates/viewer/re_chunk_store_ui/src/chunk_ui.rs +++ b/crates/viewer/re_chunk_store_ui/src/chunk_ui.rs @@ -203,7 +203,7 @@ impl ChunkUi { }; let fields_ui = |ui: &mut egui::Ui, transport: &TransportChunk| { - for field in &transport.schema.fields { + for field in &transport.schema_ref().fields { ui.push_id(field.name.clone(), |ui| { ui.list_item_collapsible_noninteractive_label(&field.name, false, |ui| { ui.list_item_collapsible_noninteractive_label("Data type", false, |ui| { @@ -279,7 +279,7 @@ impl ChunkUi { Ok(transport) => { ui.list_item_collapsible_noninteractive_label("Transport", false, |ui| { ui.list_item_collapsible_noninteractive_label("Metadata", false, |ui| { - metadata_ui(ui, &transport.schema.metadata); + metadata_ui(ui, &transport.schema_ref().metadata); }); ui.list_item_collapsible_noninteractive_label("Fields", false, |ui| { fields_ui(ui, &transport); diff --git a/rerun_py/src/dataframe.rs b/rerun_py/src/dataframe.rs index c7885138d3c0..fd7772b3a4be 100644 --- a/rerun_py/src/dataframe.rs +++ b/rerun_py/src/dataframe.rs @@ -756,7 +756,7 @@ impl PyRecordingView { let fields: Vec = schema.fields.iter().map(|f| f.clone().into()).collect(); let metadata = schema.metadata.clone().into_iter().collect(); - let schema = arrow::datatypes::Schema::new(fields).with_metadata(metadata); + let schema = arrow::datatypes::Schema::new_with_metadata(fields, metadata); let reader = RecordBatchIterator::new( query_handle @@ -853,7 +853,7 @@ impl PyRecordingView { let fields: Vec = schema.fields.iter().map(|f| f.clone().into()).collect(); let metadata = schema.metadata.clone().into_iter().collect(); - let schema = arrow::datatypes::Schema::new(fields).with_metadata(metadata); + let schema = arrow::datatypes::Schema::new_with_metadata(fields, metadata); let reader = RecordBatchIterator::new( query_handle diff --git a/rerun_py/src/python_bridge.rs b/rerun_py/src/python_bridge.rs index ba37d6ece289..a0b4a97a1674 100644 --- a/rerun_py/src/python_bridge.rs +++ b/rerun_py/src/python_bridge.rs @@ -6,6 +6,7 @@ use std::io::IsTerminal as _; use std::path::PathBuf; use std::{borrow::Borrow, collections::HashMap}; +use arrow::array::RecordBatch as ArrowRecordBatch; use itertools::Itertools; use pyo3::{ exceptions::PyRuntimeError, @@ -45,9 +46,8 @@ fn all_recordings() -> parking_lot::MutexGuard<'static, HashMap>; -type GarbageSender = crossbeam::channel::Sender; -type GarbageReceiver = crossbeam::channel::Receiver; +type GarbageSender = crossbeam::channel::Sender; +type GarbageReceiver = crossbeam::channel::Receiver; /// ## Release Callbacks /// diff --git a/rerun_py/src/remote.rs b/rerun_py/src/remote.rs index 2ba5b453c8a6..e0a7ceb7d4c5 100644 --- a/rerun_py/src/remote.rs +++ b/rerun_py/src/remote.rs @@ -168,12 +168,12 @@ impl PyStorageNodeClient { let schema = batches .first() .map(|batch| batch.schema.clone()) - .unwrap_or_else(|| arrow2::datatypes::Schema::from(vec![])); + .unwrap_or_default(); let fields: Vec = schema.fields.iter().map(|f| f.clone().into()).collect(); let metadata = schema.metadata.clone().into_iter().collect(); - let schema = arrow::datatypes::Schema::new(fields).with_metadata(metadata); + let schema = arrow::datatypes::Schema::new_with_metadata(fields, metadata); Ok(RecordBatchIterator::new( batches.into_iter().map(|tc| tc.try_to_arrow_record_batch()), From 209547ceb663e38ef432a29d961f106d2ba6d477 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 14 Jan 2025 14:50:49 +0100 Subject: [PATCH 27/57] Port Transform3D to eager serialization & update API (#8682) ### Related * Part of https://github.com/rerun-io/rerun/issues/7245 ### What Use new eager serialization & update API for transforms. The only breaking change here is that Transform3D is no longer copy, otherwise it's fully compatible. --------- Co-authored-by: Clement Rey --- .../re_types_builder/src/codegen/rust/api.rs | 47 +--- .../rerun/archetypes/transform3d.fbs | 3 +- .../re_types/src/archetypes/transform3d.rs | 240 +++++++----------- .../src/archetypes/transform3d_ext.rs | 110 +++----- .../store/re_types/tests/types/transform3d.rs | 81 +++--- .../all/archetypes/transform3d_axes.rs | 22 +- 6 files changed, 203 insertions(+), 300 deletions(-) diff --git a/crates/build/re_types_builder/src/codegen/rust/api.rs b/crates/build/re_types_builder/src/codegen/rust/api.rs index c80138f4810e..c60624a37b81 100644 --- a/crates/build/re_types_builder/src/codegen/rust/api.rs +++ b/crates/build/re_types_builder/src/codegen/rust/api.rs @@ -1182,34 +1182,12 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { // NOTE: The nullability we're dealing with here is the nullability of an entire array of components, // not the nullability of individual elements (i.e. instances)! let batch = if is_nullable { - if obj.attrs.has(ATTR_RERUN_LOG_MISSING_AS_EMPTY) { - if is_plural { - // Always log Option> as Vec, mapping None to empty batch - let component_type = quote_field_type_from_typ(&obj_field.typ, false).0; - quote! { - Some( - if let Some(comp_batch) = &self.#field_name { - (comp_batch as &dyn ComponentBatch) - } else { - // We need a reference to something that outives the function call - static EMPTY_BATCH: once_cell::sync::OnceCell<#component_type> = once_cell::sync::OnceCell::new(); - let empty_batch: &#component_type = EMPTY_BATCH.get_or_init(|| Vec::new()); - (empty_batch as &dyn ComponentBatch) - } - ) - } - } else { - // Always log Option, mapping None to empty batch - quote!{ Some(&self.#field_name as &dyn ComponentBatch) } - } + if is_plural { + // Maybe logging an Option> + quote!{ self.#field_name.as_ref().map(|comp_batch| (comp_batch as &dyn ComponentBatch)) } } else { - if is_plural { - // Maybe logging an Option> - quote!{ self.#field_name.as_ref().map(|comp_batch| (comp_batch as &dyn ComponentBatch)) } - } else { - // Maybe logging an Option - quote!{ self.#field_name.as_ref().map(|comp| (comp as &dyn ComponentBatch)) } - } + // Maybe logging an Option + quote!{ self.#field_name.as_ref().map(|comp| (comp as &dyn ComponentBatch)) } } } else { // Always logging a Vec or C @@ -1683,19 +1661,8 @@ fn quote_builder_from_obj(reporter: &Reporter, objects: &Objects, obj: &Object) }; if required.is_empty() && obj.attrs.has(ATTR_RERUN_LOG_MISSING_AS_EMPTY) { - let docstring = quote_doc_line(&format!( - "Create a new `{name}` which when logged will clear the values of all components." - )); - - quote! { - #docstring - #[inline] - #fn_new_pub fn clear() -> Self { - Self { - #(#quoted_optional,)* - } - } - } + // Skip the `new` method. + quote!() } else { let docstring = quote_doc_line(&format!("Create a new `{name}`.")); diff --git a/crates/store/re_types/definitions/rerun/archetypes/transform3d.fbs b/crates/store/re_types/definitions/rerun/archetypes/transform3d.fbs index df0de1c10e2e..5aae1ce97c14 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/transform3d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/transform3d.fbs @@ -17,10 +17,11 @@ namespace rerun.archetypes; /// \example archetypes/transform3d_simple title="Variety of 3D transforms" image="https://static.rerun.io/transform3d_simple/141368b07360ce3fcb1553079258ae3f42bdb9ac/1200w.png" /// \example archetypes/transform3d_hierarchy title="Transform hierarchy" image="https://static.rerun.io/transform_hierarchy/cb7be7a5a31fcb2efc02ba38e434849248f87554/1200w.png" table Transform3D ( + "attr.rust.archetype_eager", "attr.docs.category": "Spatial 3D", "attr.docs.view_types": "Spatial3DView, Spatial2DView: if logged above active projection", "attr.rerun.log_missing_as_empty", // See https://github.com/rerun-io/rerun/issues/6909 - "attr.rust.derive": "Copy, PartialEq" + "attr.rust.derive": "PartialEq" ) { /// Translation vector. translation: rerun.components.Translation3D ("attr.rerun.component_optional", nullable, order: 1100); diff --git a/crates/store/re_types/src/archetypes/transform3d.rs b/crates/store/re_types/src/archetypes/transform3d.rs index 9cbb0b33385d..95633745cb1d 100644 --- a/crates/store/re_types/src/archetypes/transform3d.rs +++ b/crates/store/re_types/src/archetypes/transform3d.rs @@ -166,31 +166,31 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, Copy, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct Transform3D { /// Translation vector. - pub translation: Option, + pub translation: Option, /// Rotation via axis + angle. - pub rotation_axis_angle: Option, + pub rotation_axis_angle: Option, /// Rotation via quaternion. - pub quaternion: Option, + pub quaternion: Option, /// Scaling factor. - pub scale: Option, + pub scale: Option, /// 3x3 transformation matrix. - pub mat3x3: Option, + pub mat3x3: Option, /// Specifies the relation this transform establishes between this entity and its parent. - pub relation: Option, + pub relation: Option, /// Visual length of the 3 axes. /// /// The length is interpreted in the local coordinate system of the transform. /// If the transform is scaled, the axes will be scaled accordingly. - pub axis_length: Option, + pub axis_length: Option, } impl Transform3D { @@ -362,72 +362,35 @@ impl ::re_types_core::Archetype for Transform3D { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let translation = if let Some(array) = arrays_by_descr.get(&Self::descriptor_translation()) - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Transform3D#translation")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let rotation_axis_angle = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_rotation_axis_angle()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Transform3D#rotation_axis_angle")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let quaternion = if let Some(array) = arrays_by_descr.get(&Self::descriptor_quaternion()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Transform3D#quaternion")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let scale = if let Some(array) = arrays_by_descr.get(&Self::descriptor_scale()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Transform3D#scale")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let mat3x3 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_mat3x3()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Transform3D#mat3x3")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let relation = if let Some(array) = arrays_by_descr.get(&Self::descriptor_relation()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Transform3D#relation")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let axis_length = if let Some(array) = arrays_by_descr.get(&Self::descriptor_axis_length()) - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Transform3D#axis_length")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let translation = arrays_by_descr + .get(&Self::descriptor_translation()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_translation()) + }); + let rotation_axis_angle = arrays_by_descr + .get(&Self::descriptor_rotation_axis_angle()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_rotation_axis_angle()) + }); + let quaternion = arrays_by_descr + .get(&Self::descriptor_quaternion()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_quaternion()) + }); + let scale = arrays_by_descr + .get(&Self::descriptor_scale()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_scale())); + let mat3x3 = arrays_by_descr + .get(&Self::descriptor_mat3x3()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_mat3x3())); + let relation = arrays_by_descr + .get(&Self::descriptor_relation()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_relation())); + let axis_length = arrays_by_descr + .get(&Self::descriptor_axis_length()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_axis_length()) + }); Ok(Self { translation, rotation_axis_angle, @@ -441,53 +404,18 @@ impl ::re_types_core::Archetype for Transform3D { } impl ::re_types_core::AsComponents for Transform3D { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.translation as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_translation()), - } - }), - (Some(&self.rotation_axis_angle as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_rotation_axis_angle()), - } - }), - (Some(&self.quaternion as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_quaternion()), - } - }), - (Some(&self.scale as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_scale()), - } - }), - (Some(&self.mat3x3 as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_mat3x3()), - } - }), - (Some(&self.relation as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_relation()), - } - }), - (Some(&self.axis_length as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_axis_length()), - } - }), + Self::indicator().serialized(), + self.translation.clone(), + self.rotation_axis_angle.clone(), + self.quaternion.clone(), + self.scale.clone(), + self.mat3x3.clone(), + self.relation.clone(), + self.axis_length.clone(), ] .into_iter() .flatten() @@ -498,17 +426,45 @@ impl ::re_types_core::AsComponents for Transform3D { impl ::re_types_core::ArchetypeReflectionMarker for Transform3D {} impl Transform3D { - /// Create a new `Transform3D` which when logged will clear the values of all components. + /// Update only some specific fields of a `Transform3D`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `Transform3D`. #[inline] - pub fn clear() -> Self { + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; Self { - translation: None, - rotation_axis_angle: None, - quaternion: None, - scale: None, - mat3x3: None, - relation: None, - axis_length: None, + translation: Some(SerializedComponentBatch::new( + crate::components::Translation3D::arrow_empty(), + Self::descriptor_translation(), + )), + rotation_axis_angle: Some(SerializedComponentBatch::new( + crate::components::RotationAxisAngle::arrow_empty(), + Self::descriptor_rotation_axis_angle(), + )), + quaternion: Some(SerializedComponentBatch::new( + crate::components::RotationQuat::arrow_empty(), + Self::descriptor_quaternion(), + )), + scale: Some(SerializedComponentBatch::new( + crate::components::Scale3D::arrow_empty(), + Self::descriptor_scale(), + )), + mat3x3: Some(SerializedComponentBatch::new( + crate::components::TransformMat3x3::arrow_empty(), + Self::descriptor_mat3x3(), + )), + relation: Some(SerializedComponentBatch::new( + crate::components::TransformRelation::arrow_empty(), + Self::descriptor_relation(), + )), + axis_length: Some(SerializedComponentBatch::new( + crate::components::AxisLength::arrow_empty(), + Self::descriptor_axis_length(), + )), } } @@ -518,7 +474,7 @@ impl Transform3D { mut self, translation: impl Into, ) -> Self { - self.translation = Some(translation.into()); + self.translation = try_serialize_field(Self::descriptor_translation(), [translation]); self } @@ -528,7 +484,10 @@ impl Transform3D { mut self, rotation_axis_angle: impl Into, ) -> Self { - self.rotation_axis_angle = Some(rotation_axis_angle.into()); + self.rotation_axis_angle = try_serialize_field( + Self::descriptor_rotation_axis_angle(), + [rotation_axis_angle], + ); self } @@ -538,21 +497,21 @@ impl Transform3D { mut self, quaternion: impl Into, ) -> Self { - self.quaternion = Some(quaternion.into()); + self.quaternion = try_serialize_field(Self::descriptor_quaternion(), [quaternion]); self } /// Scaling factor. #[inline] pub fn with_scale(mut self, scale: impl Into) -> Self { - self.scale = Some(scale.into()); + self.scale = try_serialize_field(Self::descriptor_scale(), [scale]); self } /// 3x3 transformation matrix. #[inline] pub fn with_mat3x3(mut self, mat3x3: impl Into) -> Self { - self.mat3x3 = Some(mat3x3.into()); + self.mat3x3 = try_serialize_field(Self::descriptor_mat3x3(), [mat3x3]); self } @@ -562,7 +521,7 @@ impl Transform3D { mut self, relation: impl Into, ) -> Self { - self.relation = Some(relation.into()); + self.relation = try_serialize_field(Self::descriptor_relation(), [relation]); self } @@ -575,7 +534,7 @@ impl Transform3D { mut self, axis_length: impl Into, ) -> Self { - self.axis_length = Some(axis_length.into()); + self.axis_length = try_serialize_field(Self::descriptor_axis_length(), [axis_length]); self } } @@ -591,15 +550,4 @@ impl ::re_byte_size::SizeBytes for Transform3D { + self.relation.heap_size_bytes() + self.axis_length.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/transform3d_ext.rs b/crates/store/re_types/src/archetypes/transform3d_ext.rs index f9caad342cf8..8e094ed41f6f 100644 --- a/crates/store/re_types/src/archetypes/transform3d_ext.rs +++ b/crates/store/re_types/src/archetypes/transform3d_ext.rs @@ -1,5 +1,5 @@ use crate::{ - components::{Scale3D, TransformMat3x3, TransformRelation, Translation3D}, + components::{Scale3D, TransformMat3x3, Translation3D}, Rotation3D, }; @@ -20,128 +20,100 @@ impl Transform3D { axis_length: None, }; + /// Clear all the fields of a `Transform3D`. + #[deprecated(since = "0.22.0", note = "Use `Self::clear_fields()` instead.")] + pub fn clear() -> Self { + Self::clear_fields() + } + /// Convenience method that takes any kind of (single) rotation representation and sets it on this transform. #[inline] pub fn with_rotation(self, rotation: impl Into) -> Self { match rotation.into() { - Rotation3D::Quaternion(quaternion) => Self { - quaternion: Some(quaternion), - ..self - }, - Rotation3D::AxisAngle(rotation_axis_angle) => Self { - rotation_axis_angle: Some(rotation_axis_angle), - ..self - }, + Rotation3D::Quaternion(quaternion) => self.with_quaternion(quaternion), + Rotation3D::AxisAngle(rotation_axis_angle) => { + self.with_rotation_axis_angle(rotation_axis_angle) + } } } - /// From a translation. + /// From a translation, clearing all other fields. #[inline] pub fn from_translation(translation: impl Into) -> Self { - Self { - translation: Some(translation.into()), - ..Self::clear() - } + Self::clear_fields().with_translation(translation) } - /// From a translation. + /// From a 3x3 matrix, clearing all other fields. #[inline] pub fn from_mat3x3(mat3x3: impl Into) -> Self { - Self { - mat3x3: Some(mat3x3.into()), - ..Self::clear() - } + Self::clear_fields().with_mat3x3(mat3x3) } - /// From a rotation + /// From a rotation, clearing all other fields. #[inline] pub fn from_rotation(rotation: impl Into) -> Self { - Self::clear().with_rotation(rotation) + Self::clear_fields().with_rotation(rotation) } - /// From a scale + /// From a scale, clearing all other fields. #[inline] pub fn from_scale(scale: impl Into) -> Self { - Self { - scale: Some(scale.into()), - ..Self::clear() - } + Self::clear_fields().with_scale(scale) } /// From a translation applied after a rotation, known as a rigid transformation. + /// + /// Clears all other fields. #[inline] pub fn from_translation_rotation( translation: impl Into, rotation: impl Into, ) -> Self { - Self { - translation: Some(translation.into()), - ..Self::clear() - } - .with_rotation(rotation) + Self::clear_fields() + .with_translation(translation) + .with_rotation(rotation) } - /// From a translation applied after a 3x3 matrix. + /// From a translation applied after a 3x3 matrix, clearing all other fields. #[inline] pub fn from_translation_mat3x3( translation: impl Into, mat3x3: impl Into, ) -> Self { - Self { - mat3x3: Some(mat3x3.into()), - translation: Some(translation.into()), - ..Self::clear() - } + Self::clear_fields() + .with_mat3x3(mat3x3) + .with_translation(translation) } - /// From a translation applied after a scale. + /// From a translation applied after a scale, clearing all other fields. #[inline] pub fn from_translation_scale( translation: impl Into, scale: impl Into, ) -> Self { - Self { - scale: Some(scale.into()), - translation: Some(translation.into()), - ..Self::clear() - } + Self::clear_fields() + .with_scale(scale) + .with_translation(translation) } - /// From a translation, applied after a rotation & scale, known as an affine transformation. + /// From a translation, applied after a rotation & scale, known as an affine transformation, clearing all other fields. #[inline] pub fn from_translation_rotation_scale( translation: impl Into, rotation: impl Into, scale: impl Into, ) -> Self { - Self { - scale: Some(scale.into()), - translation: Some(translation.into()), - ..Self::clear() - } - .with_rotation(rotation) + Self::clear_fields() + .with_scale(scale) + .with_translation(translation) + .with_rotation(rotation) } - /// From a rotation & scale + /// From a rotation & scale, clearing all other fields. #[inline] pub fn from_rotation_scale(rotation: impl Into, scale: impl Into) -> Self { - Self { - scale: Some(scale.into()), - ..Self::clear() - } - .with_rotation(rotation) - } - - /// Indicate that this transform is from parent to child. - /// - /// This is the opposite of the default, which is from child to parent. - #[allow(clippy::wrong_self_convention)] - #[inline] - #[deprecated( - since = "0.18.0", - note = "Use `.with_relation(rerun::TransformRelation::ChildFromParent)` instead." - )] - pub fn from_parent(self) -> Self { - self.with_relation(TransformRelation::ChildFromParent) + Self::clear_fields() + .with_rotation(rotation) + .with_scale(scale) } } diff --git a/crates/store/re_types/tests/types/transform3d.rs b/crates/store/re_types/tests/types/transform3d.rs index 1c03e2f28d54..720d1288e7f6 100644 --- a/crates/store/re_types/tests/types/transform3d.rs +++ b/crates/store/re_types/tests/types/transform3d.rs @@ -2,59 +2,70 @@ use std::f32::consts::TAU; use re_types::{ archetypes::Transform3D, - components::{Scale3D, TransformRelation}, - datatypes::{Angle, Mat3x3, RotationAxisAngle, Vec3D}, - Archetype as _, AsComponents as _, + components::{RotationAxisAngle, Scale3D, TransformMat3x3, TransformRelation, Translation3D}, + datatypes::Angle, + Archetype as _, AsComponents as _, ComponentBatch as _, }; #[test] fn roundtrip() { + let translation_serialized = Translation3D::new(1.0, 2.0, 3.0) + .serialized() + .map(|batch| batch.with_descriptor_override(Transform3D::descriptor_translation())); + let scale_serialized = Scale3D::uniform(42.0) + .serialized() + .map(|batch| batch.with_descriptor_override(Transform3D::descriptor_scale())); + + let mat3x3_serialized = TransformMat3x3::from([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]) + .serialized() + .map(|batch| batch.with_descriptor_override(Transform3D::descriptor_mat3x3())); + let rotation_axis_angle_serialized = + RotationAxisAngle::new([0.2, 0.2, 0.8], Angle::from_radians(0.5 * TAU)) + .serialized() + .map(|batch| { + batch.with_descriptor_override(Transform3D::descriptor_rotation_axis_angle()) + }); + let relation_child_from_parent_serialized = TransformRelation::ChildFromParent + .serialized() + .map(|batch| batch.with_descriptor_override(Transform3D::descriptor_relation())); + let relation_parent_from_child_serialized = TransformRelation::ParentFromChild + .serialized() + .map(|batch| batch.with_descriptor_override(Transform3D::descriptor_relation())); + let all_expected = [ - Transform3D::clear(), + Transform3D::clear_fields(), Transform3D { - translation: Some(Vec3D([1.0, 2.0, 3.0]).into()), - scale: Some(Scale3D::uniform(42.0)), - relation: Some(TransformRelation::ChildFromParent), - ..Transform3D::clear() + translation: translation_serialized.clone(), + scale: scale_serialized.clone(), + relation: relation_child_from_parent_serialized.clone(), + ..Transform3D::clear_fields() }, // Transform3D { - translation: Some([1.0, 2.0, 3.0].into()), - rotation_axis_angle: Some( - RotationAxisAngle { - axis: Vec3D([0.2, 0.2, 0.8]), - angle: Angle::from_radians(0.5 * TAU), - } - .into(), - ), - ..Transform3D::clear() + translation: translation_serialized.clone(), + rotation_axis_angle: rotation_axis_angle_serialized.clone(), + ..Transform3D::clear_fields() }, // Transform3D { - translation: Some(Vec3D([1.0, 2.0, 3.0]).into()), - rotation_axis_angle: Some( - RotationAxisAngle { - axis: Vec3D([0.2, 0.2, 0.8]), - angle: Angle::from_radians(0.5 * TAU), - } - .into(), - ), - scale: Some(Scale3D::uniform(42.0)), - relation: Some(TransformRelation::ChildFromParent), - ..Transform3D::clear() + translation: translation_serialized.clone(), + rotation_axis_angle: rotation_axis_angle_serialized.clone(), + scale: scale_serialized.clone(), + relation: relation_child_from_parent_serialized.clone(), + ..Transform3D::clear_fields() }, // Transform3D { - translation: Some(Vec3D([1.0, 2.0, 3.0]).into()), - relation: Some(TransformRelation::ChildFromParent), - ..Transform3D::clear() + translation: translation_serialized.clone(), + relation: relation_child_from_parent_serialized.clone(), + ..Transform3D::clear_fields() }, // Transform3D { - mat3x3: Some(Mat3x3([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]).into()), - relation: Some(TransformRelation::ParentFromChild), - ..Transform3D::clear() + mat3x3: mat3x3_serialized.clone(), + relation: relation_parent_from_child_serialized.clone(), + ..Transform3D::clear_fields() }, // ]; let all_arch = [ - Transform3D::clear(), + Transform3D::clear_fields(), Transform3D::from_translation_scale([1.0, 2.0, 3.0], Scale3D::uniform(42.0)) .with_relation(TransformRelation::ChildFromParent), // Transform3D::from_translation_rotation( diff --git a/docs/snippets/all/archetypes/transform3d_axes.rs b/docs/snippets/all/archetypes/transform3d_axes.rs index 224e8b9351f8..bc8eb62d0d24 100644 --- a/docs/snippets/all/archetypes/transform3d_axes.rs +++ b/docs/snippets/all/archetypes/transform3d_axes.rs @@ -3,25 +3,29 @@ fn main() -> Result<(), Box> { let rec = rerun::RecordingStreamBuilder::new("rerun_example_transform3d_axes").spawn()?; - let base_axes = rerun::Transform3D::clear().with_axis_length(1.0); - let other_axes = rerun::Transform3D::clear().with_axis_length(0.5); - rec.set_time_sequence("step", 0); - rec.log("base", &base_axes)?; + rec.log( + "base", + &rerun::Transform3D::clear_fields().with_axis_length(1.0), + )?; for deg in 0..360 { rec.set_time_sequence("step", deg); rec.log( "base/rotated", - &other_axes.with_rotation(rerun::RotationAxisAngle::new( - [1.0, 1.0, 1.0], - rerun::Angle::from_degrees(deg as f32), - )), + &rerun::Transform3D::clear_fields() + .with_axis_length(0.5) + .with_rotation(rerun::RotationAxisAngle::new( + [1.0, 1.0, 1.0], + rerun::Angle::from_degrees(deg as f32), + )), )?; rec.log( "base/rotated/translated", - &other_axes.with_translation([2.0, 0.0, 0.0]), + &rerun::Transform3D::clear_fields() + .with_axis_length(0.5) + .with_translation([2.0, 0.0, 0.0]), )?; } From dd04366bf84d464c658e4f6b488bc5442d33376d Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Tue, 14 Jan 2025 15:02:40 +0100 Subject: [PATCH 28/57] Add `archetype_native` attribute and make `ContainerBlueprint` eager + partial (#8666) Introduces a new attribute that, when paired with an eager archetype, will also generate a native companion type with back-and-forth conversion methods. This is especially useful for blueprint archetypes (although there are definitely non-blueprint examples too), which are heavily used all across the viewer, and would be very painful to use otherwise. ```rust /// Whether we should generate an extra Rust object comprised of native Rust types. /// /// The generated object will have the name of the archetype, prefixed by `Native`, /// e.g. `NativePoints3D`. /// /// Applies only to *eager* archetypes. No-op otherwise. attribute "attr.rust.archetype_native"; ``` With this, we now should have all the tools required to port every remaining archetype (both blueprint and data). * Part of #8650 --- .../re_types_builder/src/codegen/rust/api.rs | 184 ++++++++- .../re_types_builder/src/codegen/rust/util.rs | 2 + crates/build/re_types_builder/src/lib.rs | 1 + crates/build/re_types_builder/src/objects.rs | 9 + .../re_types/definitions/attributes/rust.fbs | 8 + .../rerun/blueprint/archetypes/background.fbs | 2 +- .../archetypes/container_blueprint.fbs | 4 +- .../blueprint/archetypes/visual_bounds2d.fbs | 2 +- .../src/blueprint/archetypes/background.rs | 98 +++-- .../archetypes/container_blueprint.rs | 391 ++++++++++++------ .../re_types/src/blueprint/archetypes/mod.rs | 2 +- .../blueprint/archetypes/visual_bounds2d.rs | 77 ++-- .../re_viewport_blueprint/src/container.rs | 4 +- 13 files changed, 554 insertions(+), 230 deletions(-) diff --git a/crates/build/re_types_builder/src/codegen/rust/api.rs b/crates/build/re_types_builder/src/codegen/rust/api.rs index c60624a37b81..38a0eed4881e 100644 --- a/crates/build/re_types_builder/src/codegen/rust/api.rs +++ b/crates/build/re_types_builder/src/codegen/rust/api.rs @@ -25,8 +25,8 @@ use crate::{ ArrowRegistry, CodeGenerator, ElementType, Object, ObjectField, ObjectKind, Objects, Reporter, Type, ATTR_DEFAULT, ATTR_RERUN_COMPONENT_OPTIONAL, ATTR_RERUN_COMPONENT_RECOMMENDED, ATTR_RERUN_COMPONENT_REQUIRED, ATTR_RERUN_LOG_MISSING_AS_EMPTY, ATTR_RERUN_VIEW_IDENTIFIER, - ATTR_RUST_CUSTOM_CLAUSE, ATTR_RUST_DERIVE, ATTR_RUST_DERIVE_ONLY, ATTR_RUST_NEW_PUB_CRATE, - ATTR_RUST_REPR, + ATTR_RUST_ARCHETYPE_EAGER, ATTR_RUST_CUSTOM_CLAUSE, ATTR_RUST_DERIVE, ATTR_RUST_DERIVE_ONLY, + ATTR_RUST_NEW_PUB_CRATE, ATTR_RUST_REPR, }; use super::{ @@ -233,7 +233,15 @@ fn generate_mod_file( { let module_name = obj.snake_case_name(); let type_name = &obj.name; - code.push_str(&format!("pub use self::{module_name}::{type_name};\n")); + let native_type_name = format!("Native{type_name}"); + + if obj.requires_native_rust_archetype() { + code.push_str(&format!( + "pub use self::{module_name}::{{{type_name}, {native_type_name}}};\n" + )); + } else { + code.push_str(&format!("pub use self::{module_name}::{type_name};\n")); + } } // And then deprecated. if objects.iter().any(|obj| obj.deprecation_notice().is_some()) { @@ -245,10 +253,19 @@ fn generate_mod_file( { let module_name = obj.snake_case_name(); let type_name = &obj.name; + let native_type_name = format!("Native{type_name}"); + if obj.deprecation_notice().is_some() { code.push_str("#[allow(deprecated)]\n"); } - code.push_str(&format!("pub use self::{module_name}::{type_name};\n")); + + if obj.requires_native_rust_archetype() { + code.push_str(&format!( + "pub use self::{module_name}::{{{type_name}, {native_type_name}}};\n" + )); + } else { + code.push_str(&format!("pub use self::{module_name}::{type_name};\n")); + } } files_to_write.insert(path, code); @@ -264,6 +281,15 @@ fn quote_struct( ) -> TokenStream { assert!(obj.is_struct()); + // Certain eager archetypes might require the generation of an associated native archetype, as + // the internal viewer code heavily relies on it. + let obj_native = obj.requires_native_rust_archetype().then(|| { + let mut obj_native = obj.clone(); + obj_native.name = format!("Native{}", obj_native.name); + obj_native.attrs.remove(ATTR_RUST_ARCHETYPE_EAGER); + obj_native + }); + let Object { name, fields, .. } = obj; let name = format_ident!("{name}"); @@ -309,10 +335,12 @@ fn quote_struct( } else { quote! { pub struct #name { #(#quoted_fields,)* }} }; + let quoted_struct_native = quote_struct_native(reporter, objects, obj); let quoted_from_impl = quote_from_impl_from_obj(obj); - let quoted_trait_impls = quote_trait_impls_from_obj(reporter, arrow_registry, objects, obj); + let quoted_trait_impls = + quote_trait_impls_from_obj(reporter, arrow_registry, objects, obj, obj_native.as_ref()); let quoted_builder = quote_builder_from_obj(reporter, objects, obj); @@ -368,6 +396,8 @@ fn quote_struct( #quoted_deprecation_notice #quoted_struct + #quoted_struct_native + #quoted_trait_impls #quoted_from_impl @@ -380,6 +410,99 @@ fn quote_struct( tokens } +/// Certain eager archetypes might require the generation of an associated native archetype, as +/// the internal viewer code heavily relies on it. +fn quote_struct_native( + reporter: &Reporter, + objects: &Objects, + obj: &Object, +) -> Option { + assert!(obj.is_struct()); + + let obj_native = obj.requires_native_rust_archetype().then(|| { + let mut obj_native = obj.clone(); + obj_native.name = format!("Native{}", obj_native.name); + obj_native.attrs.remove(ATTR_RUST_ARCHETYPE_EAGER); + obj_native + }); + + let Object { name, .. } = obj; + + let name = format_ident!("{name}"); + + let derive_only = obj.is_attr_set(ATTR_RUST_DERIVE_ONLY); + let quoted_derive_clone_debug = if derive_only { + quote!() + } else { + quote_derive_clone_debug() + }; + + let is_tuple_struct = is_tuple_struct_from_obj(obj); + obj_native.as_ref().map(|obj_native| { + let native_name = format_ident!("{}", obj_native.name); + + let quoted_fields = obj_native + .fields + .iter() + .map(|obj_field| ObjectFieldTokenizer(reporter, obj_native, obj_field).quoted(objects)); + let quoted_struct = if is_tuple_struct { + quote! { pub struct #native_name(#(#quoted_fields,)*); } + } else { + quote! { pub struct #native_name { #(#quoted_fields,)* }} + }; + + let eager_fields_to_native_fields = obj.fields.iter().map(|field| { + let field_name = format_ident!("{}", field.name); + quote!(value.#field_name.clone().map(|batch| (batch.descriptor, batch.array))) + }); + let eager_to_native = quote! { + impl TryFrom<&#name> for #native_name { + type Error = crate::DeserializationError; + + #[rustfmt::skip] // so it doesn't take 1000 lines for no reason + fn try_from(value: &#name) -> Result { + use ::re_types_core::Archetype as _; + Self::from_arrow_components( + [ #(#eager_fields_to_native_fields),* ] + .into_iter() + .flatten(), + ) + } + } + }; + + let native_fields_to_eager_fields = obj_native.fields.iter().map(|field| { + let field_name = format_ident!("{}", field.name); + if field.is_nullable { + quote!(#field_name: value.#field_name.as_ref().and_then(|v| v.serialized())) + } else { + quote!(#field_name: value.#field_name.serialized()) + } + }); + let native_to_eager = quote! { + impl From<&#native_name> for #name { + #[rustfmt::skip] // so it doesn't take 1000 lines for no reason + #[inline] + fn from(value: &#native_name) -> Self { + Self { + #(#native_fields_to_eager_fields),* + } + } + } + }; + + quote! { + #[doc(hidden)] + #quoted_derive_clone_debug + #quoted_struct + + #eager_to_native + + #native_to_eager + } + }) +} + fn quote_union( reporter: &Reporter, arrow_registry: &ArrowRegistry, @@ -426,7 +549,8 @@ fn quote_union( } }); - let quoted_trait_impls = quote_trait_impls_from_obj(reporter, arrow_registry, objects, obj); + let quoted_trait_impls = + quote_trait_impls_from_obj(reporter, arrow_registry, objects, obj, None); let quoted_heap_size_bytes = { let quoted_matches = fields.iter().map(|obj_field| { @@ -574,7 +698,8 @@ fn quote_enum( } }); - let quoted_trait_impls = quote_trait_impls_from_obj(reporter, arrow_registry, objects, obj); + let quoted_trait_impls = + quote_trait_impls_from_obj(reporter, arrow_registry, objects, obj, None); let all = fields.iter().map(|field| { let name = format_ident!("{}", field.name); @@ -843,13 +968,14 @@ fn quote_trait_impls_from_obj( arrow_registry: &ArrowRegistry, objects: &Objects, obj: &Object, + obj_native: Option<&Object>, ) -> TokenStream { match obj.kind { ObjectKind::Datatype | ObjectKind::Component => { quote_trait_impls_for_datatype_or_component(objects, arrow_registry, obj) } - ObjectKind::Archetype => quote_trait_impls_for_archetype(obj), + ObjectKind::Archetype => quote_trait_impls_for_archetype(obj, obj_native), ObjectKind::View => quote_trait_impls_for_view(reporter, obj), } @@ -1049,7 +1175,7 @@ fn quote_trait_impls_for_datatype_or_component( } } -fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { +fn quote_trait_impls_for_archetype(obj: &Object, obj_native: Option<&Object>) -> TokenStream { #![allow(clippy::collapsible_else_if)] let Object { @@ -1238,7 +1364,7 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { }; // TODO(#7245): This goes away once all archetypes have been made eager. - let all_native_deserializers = { + let all_native_deserializers = |origin: TokenStream| { obj.fields.iter().map(|obj_field| { let obj_field_fqname = obj_field.fqname.as_str(); let field_name = format_ident!("{}", obj_field.name); @@ -1267,7 +1393,6 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { } }; - // NOTE: An archetype cannot have overlapped component types by definition, so use the // component's fqname to do the mapping. let quoted_deser = if is_nullable && !is_plural { @@ -1281,7 +1406,7 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { }; quote! { - if let Some(array) = arrays_by_descr.get(&Self::#descr_fn_name()) { + if let Some(array) = arrays_by_descr.get(&#origin::#descr_fn_name()) { <#component>::from_arrow_opt(&**array) .with_context(#obj_field_fqname)? #quoted_collection @@ -1291,7 +1416,7 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { } } else if is_nullable { quote! { - if let Some(array) = arrays_by_descr.get(&Self::#descr_fn_name()) { + if let Some(array) = arrays_by_descr.get(&#origin::#descr_fn_name()) { Some({ <#component>::from_arrow_opt(&**array) .with_context(#obj_field_fqname)? @@ -1304,7 +1429,7 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { } else { quote! {{ let array = arrays_by_descr - .get(&Self::#descr_fn_name()) + .get(&#origin::#descr_fn_name()) .ok_or_else(DeserializationError::missing_data) .with_context(#obj_field_fqname)?; @@ -1313,7 +1438,7 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { }; quote!(let #field_name = #quoted_deser;) - }) + }).collect_vec() }; let all_eager_deserializers = { @@ -1334,9 +1459,33 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { let all_deserializers = if obj.is_eager_rust_archetype() { quote!(#(#all_eager_deserializers;)*) } else { + let all_native_deserializers = all_native_deserializers(quote!(Self)); quote!(#(#all_native_deserializers;)*) }; + let from_arrow_components_native = obj_native.map(|obj_native| { + let native_name = format_ident!("{}", obj_native.name); + + let all_native_deserializers = all_native_deserializers(quote!(#name)); + quote! { + impl #native_name { + fn from_arrow_components( + arrow_data: impl IntoIterator, + ) -> DeserializationResult { + re_tracing::profile_function!(); + use ::re_types_core::{Loggable as _, ResultExt as _}; + + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + #(#all_native_deserializers;)* + + Ok(Self { + #(#quoted_field_names,)* + }) + } + } + } + }); + quote! { impl #name { #(#all_descriptor_methods)* @@ -1414,7 +1563,6 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - #all_deserializers Ok(Self { @@ -1423,6 +1571,8 @@ fn quote_trait_impls_for_archetype(obj: &Object) -> TokenStream { } } + #from_arrow_components_native + impl ::re_types_core::AsComponents for #name { #as_components_impl } @@ -1474,7 +1624,7 @@ fn quote_from_impl_from_obj(obj: &Object) -> TokenStream { let self_field_access = if obj_is_tuple_struct { quote!(self.0) } else { - quote!(self.#quoted_obj_field_name ) + quote!(self.#quoted_obj_field_name) }; let deref_impl = quote! { impl std::ops::Deref for #quoted_obj_name { diff --git a/crates/build/re_types_builder/src/codegen/rust/util.rs b/crates/build/re_types_builder/src/codegen/rust/util.rs index 671b3a31b161..8fce97eba7ce 100644 --- a/crates/build/re_types_builder/src/codegen/rust/util.rs +++ b/crates/build/re_types_builder/src/codegen/rust/util.rs @@ -133,6 +133,8 @@ pub fn string_from_quoted( let line_is_attr = trimmed.starts_with("#[allow(") || trimmed.starts_with("#[inline]") + || trimmed.starts_with("#[doc(hidden)]") + || trimmed.starts_with("#[rustfmt::skip]") || trimmed.starts_with("#[derive"); if line_is_attr && (!prev_line_was_attr && !prev_line_was_docstring) { diff --git a/crates/build/re_types_builder/src/lib.rs b/crates/build/re_types_builder/src/lib.rs index b891af2e3bff..487963a74e43 100644 --- a/crates/build/re_types_builder/src/lib.rs +++ b/crates/build/re_types_builder/src/lib.rs @@ -198,6 +198,7 @@ pub const ATTR_CPP_NO_FIELD_CTORS: &str = "attr.cpp.no_field_ctors"; pub const ATTR_CPP_RENAME_FIELD: &str = "attr.cpp.rename_field"; pub const ATTR_RUST_ARCHETYPE_EAGER: &str = "attr.rust.archetype_eager"; +pub const ATTR_RUST_ARCHETYPE_NATIVE: &str = "attr.rust.archetype_native"; pub const ATTR_RUST_CUSTOM_CLAUSE: &str = "attr.rust.custom_clause"; pub const ATTR_RUST_DERIVE: &str = "attr.rust.derive"; pub const ATTR_RUST_DERIVE_ONLY: &str = "attr.rust.derive_only"; diff --git a/crates/build/re_types_builder/src/objects.rs b/crates/build/re_types_builder/src/objects.rs index 519460d3d83b..c835346cc3f5 100644 --- a/crates/build/re_types_builder/src/objects.rs +++ b/crates/build/re_types_builder/src/objects.rs @@ -13,6 +13,7 @@ use crate::{ root_as_schema, Docs, FbsBaseType, FbsEnum, FbsEnumVal, FbsField, FbsKeyValue, FbsObject, FbsSchema, FbsType, Reporter, ATTR_RERUN_COMPONENT_OPTIONAL, ATTR_RERUN_COMPONENT_RECOMMENDED, ATTR_RERUN_COMPONENT_REQUIRED, ATTR_RERUN_OVERRIDE_TYPE, ATTR_RUST_ARCHETYPE_EAGER, + ATTR_RUST_ARCHETYPE_NATIVE, }; // --- @@ -694,6 +695,10 @@ impl Object { pub fn is_eager_rust_archetype(&self) -> bool { self.is_archetype() && self.is_attr_set(ATTR_RUST_ARCHETYPE_EAGER) } + + pub fn requires_native_rust_archetype(&self) -> bool { + self.is_eager_rust_archetype() && self.is_attr_set(ATTR_RUST_ARCHETYPE_NATIVE) + } } pub fn is_testing_fqname(fqname: &str) -> bool { @@ -1426,6 +1431,10 @@ impl Attributes { pub fn has(&self, name: impl AsRef) -> bool { self.0.contains_key(name.as_ref()) } + + pub fn remove(&mut self, name: impl AsRef) { + self.0.remove(name.as_ref()); + } } fn filepath_from_declaration_file( diff --git a/crates/store/re_types/definitions/attributes/rust.fbs b/crates/store/re_types/definitions/attributes/rust.fbs index 0d9b7b2a3e37..87d5904f3e81 100644 --- a/crates/store/re_types/definitions/attributes/rust.fbs +++ b/crates/store/re_types/definitions/attributes/rust.fbs @@ -42,6 +42,14 @@ attribute "attr.rust.new_pub_crate"; /// object will be generated in `re_viewport/src/blueprint`. attribute "attr.rust.override_crate"; +/// Whether we should generate an extra Rust object comprised of native Rust types. +/// +/// The generated object will have the name of the archetype, prefixed by `Native`, +/// e.g. `NativePoints3D`. +/// +/// Applies only to *eager* archetypes. No-op otherwise. +attribute "attr.rust.archetype_native"; + /// The generated Rust object should be eagerly serialized, i.e. only comprised of Arrow arrays. /// /// Applies only to archetypes. No-op otherwise. diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/background.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/background.fbs index 4216f2f8fe6b..5464e214ee4a 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/background.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/background.fbs @@ -5,7 +5,7 @@ namespace rerun.blueprint.archetypes; table Background ( "attr.python.aliases": "datatypes.Rgba32Like, blueprint_components.BackgroundKindLike", "attr.rerun.scope": "blueprint", - "attr.rust.derive": "Copy" + "attr.rust.archetype_eager" ) { // --- Required --- diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/container_blueprint.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/container_blueprint.fbs index 454ab1f93ff0..07232ba0b150 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/container_blueprint.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/container_blueprint.fbs @@ -4,7 +4,9 @@ namespace rerun.blueprint.archetypes; /// The description of a container. table ContainerBlueprint ( - "attr.rerun.scope": "blueprint" + "attr.rerun.scope": "blueprint", + "attr.rust.archetype_eager", + "attr.rust.archetype_native" ) { // --- Required --- diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/visual_bounds2d.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/visual_bounds2d.fbs index 38c38541640c..ea210ab47b96 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/visual_bounds2d.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/visual_bounds2d.fbs @@ -9,7 +9,7 @@ namespace rerun.blueprint.archetypes; /// based on the bounding-box of the data or other camera information present in the view. table VisualBounds2D ( "attr.rerun.scope": "blueprint", - "attr.rust.derive": "Copy" + "attr.rust.archetype_eager": "" ) { /// Controls the visible range of a 2D view. /// diff --git a/crates/store/re_types/src/blueprint/archetypes/background.rs b/crates/store/re_types/src/blueprint/archetypes/background.rs index 3aa96cdf3711..edb3d0f3287d 100644 --- a/crates/store/re_types/src/blueprint/archetypes/background.rs +++ b/crates/store/re_types/src/blueprint/archetypes/background.rs @@ -19,13 +19,13 @@ use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: Configuration for the background of a view. -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Default)] pub struct Background { /// The type of the background. - pub kind: crate::blueprint::components::BackgroundKind, + pub kind: Option, /// Color used for the solid background type. - pub color: Option, + pub color: Option, } impl Background { @@ -132,52 +132,24 @@ impl ::re_types_core::Archetype for Background { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let kind = { - let array = arrays_by_descr - .get(&Self::descriptor_kind()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.blueprint.archetypes.Background#kind")?; - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.Background#kind")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.blueprint.archetypes.Background#kind")? - }; - let color = if let Some(array) = arrays_by_descr.get(&Self::descriptor_color()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.Background#color")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let kind = arrays_by_descr + .get(&Self::descriptor_kind()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_kind())); + let color = arrays_by_descr + .get(&Self::descriptor_color()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_color())); Ok(Self { kind, color }) } } impl ::re_types_core::AsComponents for Background { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.kind as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_kind()), - } - }), - (self - .color - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_color()), - }), + Self::indicator().serialized(), + self.kind.clone(), + self.color.clone(), ] .into_iter() .flatten() @@ -192,15 +164,47 @@ impl Background { #[inline] pub fn new(kind: impl Into) -> Self { Self { - kind: kind.into(), + kind: try_serialize_field(Self::descriptor_kind(), [kind]), color: None, } } + /// Update only some specific fields of a `Background`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `Background`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + kind: Some(SerializedComponentBatch::new( + crate::blueprint::components::BackgroundKind::arrow_empty(), + Self::descriptor_kind(), + )), + color: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_color(), + )), + } + } + + /// The type of the background. + #[inline] + pub fn with_kind( + mut self, + kind: impl Into, + ) -> Self { + self.kind = try_serialize_field(Self::descriptor_kind(), [kind]); + self + } + /// Color used for the solid background type. #[inline] pub fn with_color(mut self, color: impl Into) -> Self { - self.color = Some(color.into()); + self.color = try_serialize_field(Self::descriptor_color(), [color]); self } } @@ -210,10 +214,4 @@ impl ::re_byte_size::SizeBytes for Background { fn heap_size_bytes(&self) -> u64 { self.kind.heap_size_bytes() + self.color.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - ::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/container_blueprint.rs b/crates/store/re_types/src/blueprint/archetypes/container_blueprint.rs index ccd1e4dbb08c..81eb205dd091 100644 --- a/crates/store/re_types/src/blueprint/archetypes/container_blueprint.rs +++ b/crates/store/re_types/src/blueprint/archetypes/container_blueprint.rs @@ -19,8 +19,52 @@ use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: The description of a container. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct ContainerBlueprint { + /// The class of the view. + pub container_kind: Option, + + /// The name of the container. + pub display_name: Option, + + /// `ContainerId`s or `ViewId`s that are children of this container. + pub contents: Option, + + /// The layout shares of each column in the container. + /// + /// For [`components::ContainerKind::Horizontal`][crate::blueprint::components::ContainerKind::Horizontal] containers, the length of this list should always match the number of contents. + /// + /// Ignored for [`components::ContainerKind::Vertical`][crate::blueprint::components::ContainerKind::Vertical] containers. + pub col_shares: Option, + + /// The layout shares of each row of the container. + /// + /// For [`components::ContainerKind::Vertical`][crate::blueprint::components::ContainerKind::Vertical] containers, the length of this list should always match the number of contents. + /// + /// Ignored for [`components::ContainerKind::Horizontal`][crate::blueprint::components::ContainerKind::Horizontal] containers. + pub row_shares: Option, + + /// Which tab is active. + /// + /// Only applies to `Tabs` containers. + pub active_tab: Option, + + /// Whether this container is visible. + /// + /// Defaults to true if not specified. + pub visible: Option, + + /// How many columns this grid should have. + /// + /// If unset, the grid layout will be auto. + /// + /// Ignored for [`components::ContainerKind::Horizontal`][crate::blueprint::components::ContainerKind::Horizontal]/[`components::ContainerKind::Vertical`][crate::blueprint::components::ContainerKind::Vertical] containers. + pub grid_columns: Option, +} + +#[doc(hidden)] +#[derive(Clone, Debug)] +pub struct NativeContainerBlueprint { /// The class of the view. pub container_kind: crate::blueprint::components::ContainerKind, @@ -62,6 +106,49 @@ pub struct ContainerBlueprint { pub grid_columns: Option, } +impl TryFrom<&ContainerBlueprint> for NativeContainerBlueprint { + type Error = crate::DeserializationError; + + #[rustfmt::skip] + fn try_from(value: &ContainerBlueprint) -> Result { + use ::re_types_core::Archetype as _; + Self::from_arrow_components( + [ + value + .container_kind + .clone() + .map(|batch| (batch.descriptor, batch.array)), + value.display_name.clone().map(|batch| (batch.descriptor, batch.array)), + value.contents.clone().map(|batch| (batch.descriptor, batch.array)), + value.col_shares.clone().map(|batch| (batch.descriptor, batch.array)), + value.row_shares.clone().map(|batch| (batch.descriptor, batch.array)), + value.active_tab.clone().map(|batch| (batch.descriptor, batch.array)), + value.visible.clone().map(|batch| (batch.descriptor, batch.array)), + value.grid_columns.clone().map(|batch| (batch.descriptor, batch.array)), + ] + .into_iter() + .flatten(), + ) + } +} + +impl From<&NativeContainerBlueprint> for ContainerBlueprint { + #[rustfmt::skip] + #[inline] + fn from(value: &NativeContainerBlueprint) -> Self { + Self { + container_kind: value.container_kind.serialized(), + display_name: value.display_name.as_ref().and_then(|v| v.serialized()), + contents: value.contents.as_ref().and_then(|v| v.serialized()), + col_shares: value.col_shares.as_ref().and_then(|v| v.serialized()), + row_shares: value.row_shares.as_ref().and_then(|v| v.serialized()), + active_tab: value.active_tab.as_ref().and_then(|v| v.serialized()), + visible: value.visible.as_ref().and_then(|v| v.serialized()), + grid_columns: value.grid_columns.as_ref().and_then(|v| v.serialized()), + } + } +} + impl ContainerBlueprint { /// Returns the [`ComponentDescriptor`] for [`Self::container_kind`]. #[inline] @@ -237,6 +324,62 @@ impl ::re_types_core::Archetype for ContainerBlueprint { } #[inline] + fn from_arrow_components( + arrow_data: impl IntoIterator, + ) -> DeserializationResult { + re_tracing::profile_function!(); + use ::re_types_core::{Loggable as _, ResultExt as _}; + let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); + let container_kind = arrays_by_descr + .get(&Self::descriptor_container_kind()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_container_kind()) + }); + let display_name = arrays_by_descr + .get(&Self::descriptor_display_name()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_display_name()) + }); + let contents = arrays_by_descr + .get(&Self::descriptor_contents()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_contents())); + let col_shares = arrays_by_descr + .get(&Self::descriptor_col_shares()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_col_shares()) + }); + let row_shares = arrays_by_descr + .get(&Self::descriptor_row_shares()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_row_shares()) + }); + let active_tab = arrays_by_descr + .get(&Self::descriptor_active_tab()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_active_tab()) + }); + let visible = arrays_by_descr + .get(&Self::descriptor_visible()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_visible())); + let grid_columns = arrays_by_descr + .get(&Self::descriptor_grid_columns()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_grid_columns()) + }); + Ok(Self { + container_kind, + display_name, + contents, + col_shares, + row_shares, + active_tab, + visible, + grid_columns, + }) + } +} + +impl NativeContainerBlueprint { fn from_arrow_components( arrow_data: impl IntoIterator, ) -> DeserializationResult { @@ -245,7 +388,7 @@ impl ::re_types_core::Archetype for ContainerBlueprint { let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); let container_kind = { let array = arrays_by_descr - .get(&Self::descriptor_container_kind()) + .get(&ContainerBlueprint::descriptor_container_kind()) .ok_or_else(DeserializationError::missing_data) .with_context("rerun.blueprint.archetypes.ContainerBlueprint#container_kind")?; ::from_arrow_opt(&**array) @@ -256,29 +399,33 @@ impl ::re_types_core::Archetype for ContainerBlueprint { .ok_or_else(DeserializationError::missing_data) .with_context("rerun.blueprint.archetypes.ContainerBlueprint#container_kind")? }; - let display_name = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_display_name()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ContainerBlueprint#display_name")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let contents = if let Some(array) = arrays_by_descr.get(&Self::descriptor_contents()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ContainerBlueprint#contents")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.blueprint.archetypes.ContainerBlueprint#contents")? - }) + let display_name = if let Some(array) = + arrays_by_descr.get(&ContainerBlueprint::descriptor_display_name()) + { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ContainerBlueprint#display_name")? + .into_iter() + .next() + .flatten() } else { None }; - let col_shares = if let Some(array) = arrays_by_descr.get(&Self::descriptor_col_shares()) { + let contents = + if let Some(array) = arrays_by_descr.get(&ContainerBlueprint::descriptor_contents()) { + Some({ + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ContainerBlueprint#contents")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .collect::>>() + .with_context("rerun.blueprint.archetypes.ContainerBlueprint#contents")? + }) + } else { + None + }; + let col_shares = if let Some(array) = + arrays_by_descr.get(&ContainerBlueprint::descriptor_col_shares()) + { Some({ ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.ContainerBlueprint#col_shares")? @@ -290,7 +437,9 @@ impl ::re_types_core::Archetype for ContainerBlueprint { } else { None }; - let row_shares = if let Some(array) = arrays_by_descr.get(&Self::descriptor_row_shares()) { + let row_shares = if let Some(array) = + arrays_by_descr.get(&ContainerBlueprint::descriptor_row_shares()) + { Some({ ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.ContainerBlueprint#row_shares")? @@ -302,7 +451,9 @@ impl ::re_types_core::Archetype for ContainerBlueprint { } else { None }; - let active_tab = if let Some(array) = arrays_by_descr.get(&Self::descriptor_active_tab()) { + let active_tab = if let Some(array) = + arrays_by_descr.get(&ContainerBlueprint::descriptor_active_tab()) + { ::from_arrow_opt(&**array) .with_context("rerun.blueprint.archetypes.ContainerBlueprint#active_tab")? .into_iter() @@ -311,25 +462,27 @@ impl ::re_types_core::Archetype for ContainerBlueprint { } else { None }; - let visible = if let Some(array) = arrays_by_descr.get(&Self::descriptor_visible()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ContainerBlueprint#visible")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let grid_columns = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_grid_columns()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ContainerBlueprint#grid_columns")? + let visible = + if let Some(array) = arrays_by_descr.get(&ContainerBlueprint::descriptor_visible()) { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ContainerBlueprint#visible")? .into_iter() .next() .flatten() } else { None }; + let grid_columns = if let Some(array) = + arrays_by_descr.get(&ContainerBlueprint::descriptor_grid_columns()) + { + ::from_arrow_opt(&**array) + .with_context("rerun.blueprint.archetypes.ContainerBlueprint#grid_columns")? + .into_iter() + .next() + .flatten() + } else { + None + }; Ok(Self { container_kind, display_name, @@ -344,73 +497,19 @@ impl ::re_types_core::Archetype for ContainerBlueprint { } impl ::re_types_core::AsComponents for ContainerBlueprint { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.container_kind as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_container_kind()), - } - }), - (self - .display_name - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_display_name()), - }), - (self - .contents - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_contents()), - }), - (self - .col_shares - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_col_shares()), - }), - (self - .row_shares - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_row_shares()), - }), - (self - .active_tab - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_active_tab()), - }), - (self - .visible - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_visible()), - }), - (self - .grid_columns - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_grid_columns()), - }), + Self::indicator().serialized(), + self.container_kind.clone(), + self.display_name.clone(), + self.contents.clone(), + self.col_shares.clone(), + self.row_shares.clone(), + self.active_tab.clone(), + self.visible.clone(), + self.grid_columns.clone(), ] .into_iter() .flatten() @@ -425,7 +524,10 @@ impl ContainerBlueprint { #[inline] pub fn new(container_kind: impl Into) -> Self { Self { - container_kind: container_kind.into(), + container_kind: try_serialize_field( + Self::descriptor_container_kind(), + [container_kind], + ), display_name: None, contents: None, col_shares: None, @@ -436,10 +538,67 @@ impl ContainerBlueprint { } } + /// Update only some specific fields of a `ContainerBlueprint`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `ContainerBlueprint`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + container_kind: Some(SerializedComponentBatch::new( + crate::blueprint::components::ContainerKind::arrow_empty(), + Self::descriptor_container_kind(), + )), + display_name: Some(SerializedComponentBatch::new( + crate::components::Name::arrow_empty(), + Self::descriptor_display_name(), + )), + contents: Some(SerializedComponentBatch::new( + crate::blueprint::components::IncludedContent::arrow_empty(), + Self::descriptor_contents(), + )), + col_shares: Some(SerializedComponentBatch::new( + crate::blueprint::components::ColumnShare::arrow_empty(), + Self::descriptor_col_shares(), + )), + row_shares: Some(SerializedComponentBatch::new( + crate::blueprint::components::RowShare::arrow_empty(), + Self::descriptor_row_shares(), + )), + active_tab: Some(SerializedComponentBatch::new( + crate::blueprint::components::ActiveTab::arrow_empty(), + Self::descriptor_active_tab(), + )), + visible: Some(SerializedComponentBatch::new( + crate::blueprint::components::Visible::arrow_empty(), + Self::descriptor_visible(), + )), + grid_columns: Some(SerializedComponentBatch::new( + crate::blueprint::components::GridColumns::arrow_empty(), + Self::descriptor_grid_columns(), + )), + } + } + + /// The class of the view. + #[inline] + pub fn with_container_kind( + mut self, + container_kind: impl Into, + ) -> Self { + self.container_kind = + try_serialize_field(Self::descriptor_container_kind(), [container_kind]); + self + } + /// The name of the container. #[inline] pub fn with_display_name(mut self, display_name: impl Into) -> Self { - self.display_name = Some(display_name.into()); + self.display_name = try_serialize_field(Self::descriptor_display_name(), [display_name]); self } @@ -449,7 +608,7 @@ impl ContainerBlueprint { mut self, contents: impl IntoIterator>, ) -> Self { - self.contents = Some(contents.into_iter().map(Into::into).collect()); + self.contents = try_serialize_field(Self::descriptor_contents(), contents); self } @@ -463,7 +622,7 @@ impl ContainerBlueprint { mut self, col_shares: impl IntoIterator>, ) -> Self { - self.col_shares = Some(col_shares.into_iter().map(Into::into).collect()); + self.col_shares = try_serialize_field(Self::descriptor_col_shares(), col_shares); self } @@ -477,7 +636,7 @@ impl ContainerBlueprint { mut self, row_shares: impl IntoIterator>, ) -> Self { - self.row_shares = Some(row_shares.into_iter().map(Into::into).collect()); + self.row_shares = try_serialize_field(Self::descriptor_row_shares(), row_shares); self } @@ -489,7 +648,7 @@ impl ContainerBlueprint { mut self, active_tab: impl Into, ) -> Self { - self.active_tab = Some(active_tab.into()); + self.active_tab = try_serialize_field(Self::descriptor_active_tab(), [active_tab]); self } @@ -501,7 +660,7 @@ impl ContainerBlueprint { mut self, visible: impl Into, ) -> Self { - self.visible = Some(visible.into()); + self.visible = try_serialize_field(Self::descriptor_visible(), [visible]); self } @@ -515,7 +674,7 @@ impl ContainerBlueprint { mut self, grid_columns: impl Into, ) -> Self { - self.grid_columns = Some(grid_columns.into()); + self.grid_columns = try_serialize_field(Self::descriptor_grid_columns(), [grid_columns]); self } } @@ -532,16 +691,4 @@ impl ::re_byte_size::SizeBytes for ContainerBlueprint { + self.visible.heap_size_bytes() + self.grid_columns.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - ::is_pod() - && >::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/mod.rs b/crates/store/re_types/src/blueprint/archetypes/mod.rs index 92d1c164ee4e..e226ce3141b4 100644 --- a/crates/store/re_types/src/blueprint/archetypes/mod.rs +++ b/crates/store/re_types/src/blueprint/archetypes/mod.rs @@ -26,7 +26,7 @@ mod visible_time_ranges_ext; mod visual_bounds2d; pub use self::background::Background; -pub use self::container_blueprint::ContainerBlueprint; +pub use self::container_blueprint::{ContainerBlueprint, NativeContainerBlueprint}; pub use self::dataframe_query::DataframeQuery; pub use self::force_center::ForceCenter; pub use self::force_collision_radius::ForceCollisionRadius; diff --git a/crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs b/crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs index 8066f0e81f7d..6efa80af2144 100644 --- a/crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs +++ b/crates/store/re_types/src/blueprint/archetypes/visual_bounds2d.rs @@ -25,12 +25,12 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// If no visual bounds are set, it will be determined automatically, /// based on the bounding-box of the data or other camera information present in the view. -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Default)] pub struct VisualBounds2D { /// Controls the visible range of a 2D view. /// /// Use this to control pan & zoom of the view. - pub range: crate::blueprint::components::VisualBounds2D, + pub range: Option, } impl VisualBounds2D { @@ -126,39 +126,21 @@ impl ::re_types_core::Archetype for VisualBounds2D { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let range = { - let array = arrays_by_descr - .get(&Self::descriptor_range()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.blueprint.archetypes.VisualBounds2D#range")?; - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.VisualBounds2D#range")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.blueprint.archetypes.VisualBounds2D#range")? - }; + let range = arrays_by_descr + .get(&Self::descriptor_range()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_range())); Ok(Self { range }) } } impl ::re_types_core::AsComponents for VisualBounds2D { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; - [ - Some(Self::indicator()), - (Some(&self.range as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_range()), - } - }), - ] - .into_iter() - .flatten() - .collect() + [Self::indicator().serialized(), self.range.clone()] + .into_iter() + .flatten() + .collect() } } @@ -169,9 +151,39 @@ impl VisualBounds2D { #[inline] pub fn new(range: impl Into) -> Self { Self { - range: range.into(), + range: try_serialize_field(Self::descriptor_range(), [range]), } } + + /// Update only some specific fields of a `VisualBounds2D`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `VisualBounds2D`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + range: Some(SerializedComponentBatch::new( + crate::blueprint::components::VisualBounds2D::arrow_empty(), + Self::descriptor_range(), + )), + } + } + + /// Controls the visible range of a 2D view. + /// + /// Use this to control pan & zoom of the view. + #[inline] + pub fn with_range( + mut self, + range: impl Into, + ) -> Self { + self.range = try_serialize_field(Self::descriptor_range(), [range]); + self + } } impl ::re_byte_size::SizeBytes for VisualBounds2D { @@ -179,9 +191,4 @@ impl ::re_byte_size::SizeBytes for VisualBounds2D { fn heap_size_bytes(&self) -> u64 { self.range.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - ::is_pod() - } } diff --git a/crates/viewer/re_viewport_blueprint/src/container.rs b/crates/viewer/re_viewport_blueprint/src/container.rs index af0b03fb810f..f6873eaa7d67 100644 --- a/crates/viewer/re_viewport_blueprint/src/container.rs +++ b/crates/viewer/re_viewport_blueprint/src/container.rs @@ -76,7 +76,7 @@ impl ContainerBlueprint { // is the marker that the have been cleared and not an error. let container_kind = results.component_instance::(0)?; - let blueprint_archetypes::ContainerBlueprint { + let blueprint_archetypes::NativeContainerBlueprint { container_kind, display_name, contents, @@ -85,7 +85,7 @@ impl ContainerBlueprint { active_tab, visible, grid_columns, - } = blueprint_archetypes::ContainerBlueprint { + } = blueprint_archetypes::NativeContainerBlueprint { container_kind, display_name: results.component_instance(0), contents: results.component_batch(), From ecdc4d74fc819b70a7a6e6179d9c9af4fb0e1a45 Mon Sep 17 00:00:00 2001 From: Zeljko Mihaljcic <7150613+zehiko@users.noreply.github.com> Date: Tue, 14 Jan 2025 16:16:34 +0100 Subject: [PATCH 29/57] gRPC spec update: define recording schema protobuf types and expose the schema via new endpoint (#8651) ### What Define column descriptors in the protobuf spec and the relevant type conversions. Add new endpoint for fetching the schema that returns a list of column descriptors. Also updated the example script to use the next endpoint and print the schema. --- Cargo.lock | 3 + crates/store/re_chunk_store/Cargo.toml | 3 +- .../src/protobuf_conversions.rs | 156 ++++++++++++++++++ .../re_protos/proto/rerun/v0/common.proto | 36 ++++ .../proto/rerun/v0/remote_store.proto | 11 ++ .../store/re_protos/src/v0/rerun.common.v0.rs | 85 ++++++++++ .../re_protos/src/v0/rerun.remote_store.v0.rs | 95 +++++++++++ examples/python/remote/metadata.py | 10 ++ rerun_py/rerun_bindings/rerun_bindings.pyi | 17 ++ rerun_py/src/remote.rs | 43 ++++- 10 files changed, 455 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bbd30938aff3..66fdf6678a5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5605,6 +5605,8 @@ dependencies = [ "hashbrown 0.14.5", "num-traits", "rustc_version", + "serde", + "serde_derive", "simdutf8", ] @@ -5733,6 +5735,7 @@ dependencies = [ "re_tracing", "re_types", "re_types_core", + "serde_json", "similar-asserts", "thiserror 1.0.65", "tinyvec", diff --git a/crates/store/re_chunk_store/Cargo.toml b/crates/store/re_chunk_store/Cargo.toml index 5feff61a7562..b4d65bf4e554 100644 --- a/crates/store/re_chunk_store/Cargo.toml +++ b/crates/store/re_chunk_store/Cargo.toml @@ -42,13 +42,14 @@ re_types_core.workspace = true ahash.workspace = true anyhow.workspace = true arrow.workspace = true -arrow2 = { workspace = true, features = ["compute_concatenate"] } +arrow2 = { workspace = true, features = ["compute_concatenate", "serde_types"] } document-features.workspace = true indent.workspace = true itertools.workspace = true nohash-hasher.workspace = true once_cell.workspace = true parking_lot = { workspace = true, features = ["arc_lock"] } +serde_json.workspace = true thiserror.workspace = true web-time.workspace = true diff --git a/crates/store/re_chunk_store/src/protobuf_conversions.rs b/crates/store/re_chunk_store/src/protobuf_conversions.rs index 4f37e7b3bf5a..020cc3523106 100644 --- a/crates/store/re_chunk_store/src/protobuf_conversions.rs +++ b/crates/store/re_chunk_store/src/protobuf_conversions.rs @@ -1,3 +1,4 @@ +use re_protos::invalid_field; use re_protos::missing_field; use re_protos::TypeConversionError; use std::collections::BTreeMap; @@ -257,6 +258,112 @@ impl From for re_protos::common::v0::Query { } } +impl TryFrom for re_protos::common::v0::ColumnDescriptor { + type Error = TypeConversionError; + + fn try_from(value: crate::ColumnDescriptor) -> Result { + match value { + crate::ColumnDescriptor::Time(time_descriptor) => Ok(Self { + descriptor_type: Some( + re_protos::common::v0::column_descriptor::DescriptorType::TimeColumn( + re_protos::common::v0::TimeColumnDescriptor { + timeline: Some(re_protos::common::v0::Timeline { + name: time_descriptor.timeline.name().to_string(), + }), + datatype: serde_json::to_string(&time_descriptor.datatype).map_err( + |err| invalid_field!(Self, "time column descriptor", err), + )?, + }, + ), + ), + }), + crate::ColumnDescriptor::Component(component_descriptor) => Ok(Self { + descriptor_type: Some( + re_protos::common::v0::column_descriptor::DescriptorType::ComponentColumn( + re_protos::common::v0::ComponentColumnDescriptor { + entity_path: Some(component_descriptor.entity_path.into()), + archetype_name: component_descriptor + .archetype_name + .map(|an| an.to_string()), + archetype_field_name: component_descriptor + .archetype_field_name + .map(|afn| afn.to_string()), + component_name: component_descriptor.component_name.to_string(), + datatype: serde_json::to_string(&component_descriptor.store_datatype) + .map_err(|err| { + invalid_field!(Self, "component column descriptor", err) + })?, + is_static: component_descriptor.is_static, + is_tombstone: component_descriptor.is_tombstone, + is_semantically_empty: component_descriptor.is_semantically_empty, + is_indicator: component_descriptor.is_indicator, + }, + ), + ), + }), + } + } +} + +impl TryFrom for crate::ColumnDescriptor { + type Error = TypeConversionError; + + fn try_from(value: re_protos::common::v0::ColumnDescriptor) -> Result { + let descriptor = value.descriptor_type.ok_or(missing_field!( + re_protos::common::v0::ColumnDescriptor, + "descriptor_type", + ))?; + + match descriptor { + re_protos::common::v0::column_descriptor::DescriptorType::TimeColumn( + time_descriptor, + ) => Ok(Self::Time(crate::TimeColumnDescriptor { + timeline: time_descriptor + .timeline + .ok_or(missing_field!( + re_protos::common::v0::TimeColumnDescriptor, + "timeline", + ))? + .into(), + datatype: serde_json::from_str(&time_descriptor.datatype).map_err(|err| { + invalid_field!( + re_protos::common::v0::ColumnDescriptor, + "time column descriptor", + err + ) + })?, + })), + re_protos::common::v0::column_descriptor::DescriptorType::ComponentColumn( + component_descriptor, + ) => Ok(Self::Component(crate::ComponentColumnDescriptor { + entity_path: component_descriptor + .entity_path + .ok_or(missing_field!( + re_protos::common::v0::ComponentColumnDescriptor, + "entity_path", + ))? + .try_into()?, + archetype_name: component_descriptor.archetype_name.map(Into::into), + archetype_field_name: component_descriptor.archetype_field_name.map(Into::into), + component_name: component_descriptor.component_name.into(), + store_datatype: serde_json::from_str(&component_descriptor.datatype).map_err( + |err| { + invalid_field!( + re_protos::common::v0::ColumnDescriptor, + "component column descriptor", + err + ) + }, + )?, + is_static: component_descriptor.is_static, + is_tombstone: component_descriptor.is_tombstone, + is_semantically_empty: component_descriptor.is_semantically_empty, + is_indicator: component_descriptor.is_indicator, + })), + } + } +} + #[cfg(test)] mod tests { use re_protos::common::v0::{ @@ -335,4 +442,53 @@ mod tests { assert_eq!(grpc_query_before, grpc_query_after); } + + #[test] + fn test_time_column_descriptor_conversion() { + let time_descriptor = crate::TimeColumnDescriptor { + timeline: crate::Timeline::log_time(), + datatype: arrow2::datatypes::DataType::Timestamp( + arrow2::datatypes::TimeUnit::Nanosecond, + None, + ), + }; + + let descriptor = crate::ColumnDescriptor::Time(time_descriptor.clone()); + + let proto_descriptor: re_protos::common::v0::ColumnDescriptor = + descriptor.try_into().unwrap(); + let descriptor_after = proto_descriptor.try_into().unwrap(); + let crate::ColumnDescriptor::Time(time_descriptor_after) = descriptor_after else { + panic!("Expected TimeColumnDescriptor") + }; + + assert_eq!(time_descriptor, time_descriptor_after); + } + + #[test] + fn test_component_column_descriptor_conversion() { + let component_descriptor = crate::ComponentColumnDescriptor { + entity_path: re_log_types::EntityPath::from("/some/path"), + archetype_name: Some("archetype".to_owned().into()), + archetype_field_name: Some("field".to_owned().into()), + component_name: re_chunk::ComponentName::new("component"), + store_datatype: arrow2::datatypes::DataType::Int64, + is_static: true, + is_tombstone: false, + is_semantically_empty: false, + is_indicator: true, + }; + + let descriptor = crate::ColumnDescriptor::Component(component_descriptor.clone()); + + let proto_descriptor: re_protos::common::v0::ColumnDescriptor = + descriptor.try_into().unwrap(); + let descriptor_after = proto_descriptor.try_into().unwrap(); + let crate::ColumnDescriptor::Component(component_descriptor_after) = descriptor_after + else { + panic!("Expected ComponentColumnDescriptor") + }; + + assert_eq!(component_descriptor, component_descriptor_after); + } } diff --git a/crates/store/re_protos/proto/rerun/v0/common.proto b/crates/store/re_protos/proto/rerun/v0/common.proto index 47f77b7e6dd7..3d6521e1ecf5 100644 --- a/crates/store/re_protos/proto/rerun/v0/common.proto +++ b/crates/store/re_protos/proto/rerun/v0/common.proto @@ -102,6 +102,42 @@ message Query { SparseFillStrategy sparse_fill_strategy = 11; } +message ColumnDescriptor { + oneof descriptor_type { + TimeColumnDescriptor time_column = 1; + ComponentColumnDescriptor component_column = 2; + } +} + +message TimeColumnDescriptor { + /// The timeline this column is associated with. + Timeline timeline = 1; + /// The Arrow datatype of the column. + string datatype = 2; +} + +/// Describes a data/component column, such as `Position3D`. +message ComponentColumnDescriptor { + /// The path of the entity. + EntityPath entity_path = 1; + /// Optional name of the `Archetype` associated with this data. + optional string archetype_name = 2; + /// Optional name of the field within `Archetype` associated with this data. + optional string archetype_field_name = 3; + /// Semantic name associated with this data. + string component_name = 4; + /// The Arrow datatype of the column. + string datatype = 5; + /// Whether the column is a static column. + bool is_static = 6; + /// Whether the column is a tombstone column. + bool is_tombstone = 7; + /// Whether the column is an indicator column. + bool is_indicator = 8; + /// Whether the column is semantically empty. + bool is_semantically_empty = 9; +} + message ColumnSelection { repeated ColumnSelector columns = 1; } diff --git a/crates/store/re_protos/proto/rerun/v0/remote_store.proto b/crates/store/re_protos/proto/rerun/v0/remote_store.proto index 54499d69458a..86dbdd42bb31 100644 --- a/crates/store/re_protos/proto/rerun/v0/remote_store.proto +++ b/crates/store/re_protos/proto/rerun/v0/remote_store.proto @@ -12,6 +12,7 @@ service StorageNode { // metadata API calls rpc QueryCatalog(QueryCatalogRequest) returns (stream DataframePart) {} rpc UpdateCatalog(UpdateCatalogRequest) returns (UpdateCatalogResponse) {} + rpc GetRecordingSchema(GetRecordingSchemaRequest) returns (GetRecordingSchemaResponse) {} // TODO(zehiko) support registering more than one recording at a time rpc RegisterRecording(RegisterRecordingRequest) returns (DataframePart) {} @@ -31,6 +32,16 @@ message DataframePart { bytes payload = 1000; } +// ---------------- GetRecordingSchema ------------------ + +message GetRecordingSchemaRequest { + rerun.common.v0.RecordingId recording_id = 1; +} + +message GetRecordingSchemaResponse { + repeated rerun.common.v0.ColumnDescriptor column_descriptors = 1; +} + // ---------------- RegisterRecording ------------------ message RegisterRecordingRequest { diff --git a/crates/store/re_protos/src/v0/rerun.common.v0.rs b/crates/store/re_protos/src/v0/rerun.common.v0.rs index 99bcbbd61774..eabb6cc3118e 100644 --- a/crates/store/re_protos/src/v0/rerun.common.v0.rs +++ b/crates/store/re_protos/src/v0/rerun.common.v0.rs @@ -161,6 +161,91 @@ impl ::prost::Name for Query { } } #[derive(Clone, PartialEq, ::prost::Message)] +pub struct ColumnDescriptor { + #[prost(oneof = "column_descriptor::DescriptorType", tags = "1, 2")] + pub descriptor_type: ::core::option::Option, +} +/// Nested message and enum types in `ColumnDescriptor`. +pub mod column_descriptor { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum DescriptorType { + #[prost(message, tag = "1")] + TimeColumn(super::TimeColumnDescriptor), + #[prost(message, tag = "2")] + ComponentColumn(super::ComponentColumnDescriptor), + } +} +impl ::prost::Name for ColumnDescriptor { + const NAME: &'static str = "ColumnDescriptor"; + const PACKAGE: &'static str = "rerun.common.v0"; + fn full_name() -> ::prost::alloc::string::String { + "rerun.common.v0.ColumnDescriptor".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/rerun.common.v0.ColumnDescriptor".into() + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TimeColumnDescriptor { + /// / The timeline this column is associated with. + #[prost(message, optional, tag = "1")] + pub timeline: ::core::option::Option, + /// / The Arrow datatype of the column. + #[prost(string, tag = "2")] + pub datatype: ::prost::alloc::string::String, +} +impl ::prost::Name for TimeColumnDescriptor { + const NAME: &'static str = "TimeColumnDescriptor"; + const PACKAGE: &'static str = "rerun.common.v0"; + fn full_name() -> ::prost::alloc::string::String { + "rerun.common.v0.TimeColumnDescriptor".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/rerun.common.v0.TimeColumnDescriptor".into() + } +} +/// / Describes a data/component column, such as `Position3D`. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ComponentColumnDescriptor { + /// / The path of the entity. + #[prost(message, optional, tag = "1")] + pub entity_path: ::core::option::Option, + /// / Optional name of the `Archetype` associated with this data. + #[prost(string, optional, tag = "2")] + pub archetype_name: ::core::option::Option<::prost::alloc::string::String>, + /// / Optional name of the field within `Archetype` associated with this data. + #[prost(string, optional, tag = "3")] + pub archetype_field_name: ::core::option::Option<::prost::alloc::string::String>, + /// / Semantic name associated with this data. + #[prost(string, tag = "4")] + pub component_name: ::prost::alloc::string::String, + /// / The Arrow datatype of the column. + #[prost(string, tag = "5")] + pub datatype: ::prost::alloc::string::String, + /// / Whether the column is a static column. + #[prost(bool, tag = "6")] + pub is_static: bool, + /// / Whether the column is a tombstone column. + #[prost(bool, tag = "7")] + pub is_tombstone: bool, + /// / Whether the column is an indicator column. + #[prost(bool, tag = "8")] + pub is_indicator: bool, + /// / Whether the column is semantically empty. + #[prost(bool, tag = "9")] + pub is_semantically_empty: bool, +} +impl ::prost::Name for ComponentColumnDescriptor { + const NAME: &'static str = "ComponentColumnDescriptor"; + const PACKAGE: &'static str = "rerun.common.v0"; + fn full_name() -> ::prost::alloc::string::String { + "rerun.common.v0.ComponentColumnDescriptor".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/rerun.common.v0.ComponentColumnDescriptor".into() + } +} +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ColumnSelection { #[prost(message, repeated, tag = "1")] pub columns: ::prost::alloc::vec::Vec, diff --git a/crates/store/re_protos/src/v0/rerun.remote_store.v0.rs b/crates/store/re_protos/src/v0/rerun.remote_store.v0.rs index 7f9198564bbe..13a5f0d65df5 100644 --- a/crates/store/re_protos/src/v0/rerun.remote_store.v0.rs +++ b/crates/store/re_protos/src/v0/rerun.remote_store.v0.rs @@ -20,6 +20,36 @@ impl ::prost::Name for DataframePart { } } #[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetRecordingSchemaRequest { + #[prost(message, optional, tag = "1")] + pub recording_id: ::core::option::Option, +} +impl ::prost::Name for GetRecordingSchemaRequest { + const NAME: &'static str = "GetRecordingSchemaRequest"; + const PACKAGE: &'static str = "rerun.remote_store.v0"; + fn full_name() -> ::prost::alloc::string::String { + "rerun.remote_store.v0.GetRecordingSchemaRequest".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/rerun.remote_store.v0.GetRecordingSchemaRequest".into() + } +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetRecordingSchemaResponse { + #[prost(message, repeated, tag = "1")] + pub column_descriptors: ::prost::alloc::vec::Vec, +} +impl ::prost::Name for GetRecordingSchemaResponse { + const NAME: &'static str = "GetRecordingSchemaResponse"; + const PACKAGE: &'static str = "rerun.remote_store.v0"; + fn full_name() -> ::prost::alloc::string::String { + "rerun.remote_store.v0.GetRecordingSchemaResponse".into() + } + fn type_url() -> ::prost::alloc::string::String { + "/rerun.remote_store.v0.GetRecordingSchemaResponse".into() + } +} +#[derive(Clone, PartialEq, ::prost::Message)] pub struct RegisterRecordingRequest { /// human readable description of the recording #[prost(string, tag = "1")] @@ -496,6 +526,25 @@ pub mod storage_node_client { )); self.inner.unary(req, path, codec).await } + pub async fn get_recording_schema( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> + { + self.inner.ready().await.map_err(|e| { + tonic::Status::unknown(format!("Service was not ready: {}", e.into())) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/rerun.remote_store.v0.StorageNode/GetRecordingSchema", + ); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new( + "rerun.remote_store.v0.StorageNode", + "GetRecordingSchema", + )); + self.inner.unary(req, path, codec).await + } /// TODO(zehiko) support registering more than one recording at a time pub async fn register_recording( &mut self, @@ -606,6 +655,10 @@ pub mod storage_node_server { &self, request: tonic::Request, ) -> std::result::Result, tonic::Status>; + async fn get_recording_schema( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; /// TODO(zehiko) support registering more than one recording at a time async fn register_recording( &self, @@ -865,6 +918,48 @@ pub mod storage_node_server { }; Box::pin(fut) } + "/rerun.remote_store.v0.StorageNode/GetRecordingSchema" => { + #[allow(non_camel_case_types)] + struct GetRecordingSchemaSvc(pub Arc); + impl + tonic::server::UnaryService + for GetRecordingSchemaSvc + { + type Response = super::GetRecordingSchemaResponse; + type Future = BoxFuture, tonic::Status>; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::get_recording_schema(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GetRecordingSchemaSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } "/rerun.remote_store.v0.StorageNode/RegisterRecording" => { #[allow(non_camel_case_types)] struct RegisterRecordingSvc(pub Arc); diff --git a/examples/python/remote/metadata.py b/examples/python/remote/metadata.py index 188d46e81e91..8e83de23d801 100644 --- a/examples/python/remote/metadata.py +++ b/examples/python/remote/metadata.py @@ -14,6 +14,7 @@ subparsers = parser.add_subparsers(dest="subcommand") print_cmd = subparsers.add_parser("print", help="Print everything") + print_schema_cmd = subparsers.add_parser("print-schema", help="Print schema for a recording in the catalog") register_cmd = subparsers.add_parser("register", help="Register a new recording") update_cmd = subparsers.add_parser("update", help="Update metadata for a recording") @@ -26,6 +27,8 @@ print_cmd.add_argument("--columns", nargs="*", help="Define which columns to print") print_cmd.add_argument("--recording-ids", nargs="*", help="Select specific recordings to print") + print_schema_cmd.add_argument("recording_id", help="Recording ID to print schema for") + args = parser.parse_args() # Register the new rrd @@ -58,3 +61,10 @@ print(new_metadata) conn.update_catalog(new_metadata) + + elif args.subcommand == "print-schema": + id = args.recording_id + + schema = conn.get_recording_schema(id) + for column in schema: + print(column) diff --git a/rerun_py/rerun_bindings/rerun_bindings.pyi b/rerun_py/rerun_bindings/rerun_bindings.pyi index b9c4854e9602..442a1a843351 100644 --- a/rerun_py/rerun_bindings/rerun_bindings.pyi +++ b/rerun_py/rerun_bindings/rerun_bindings.pyi @@ -593,6 +593,23 @@ class StorageNodeClient: """ ... + def get_recording_schema(self, id: str) -> Schema: + """ + Get the schema for a recording in the storage node. + + Parameters + ---------- + id : str + The id of the recording to get the schema for. + + Returns + ------- + Schema + The schema of the recording. + + """ + ... + def register(self, storage_url: str, metadata: Optional[TableLike] = None) -> str: """ Register a recording along with some metadata. diff --git a/rerun_py/src/remote.rs b/rerun_py/src/remote.rs index e0a7ceb7d4c5..ed0d7d779e00 100644 --- a/rerun_py/src/remote.rs +++ b/rerun_py/src/remote.rs @@ -25,14 +25,15 @@ use re_protos::{ common::v0::RecordingId, remote_store::v0::{ storage_node_client::StorageNodeClient, CatalogFilter, ColumnProjection, - FetchRecordingRequest, QueryCatalogRequest, QueryRequest, RecordingType, - RegisterRecordingRequest, UpdateCatalogRequest, + FetchRecordingRequest, GetRecordingSchemaRequest, QueryCatalogRequest, QueryRequest, + RecordingType, RegisterRecordingRequest, UpdateCatalogRequest, }, + TypeConversionError, }; use re_sdk::{ApplicationId, ComponentName, StoreId, StoreKind, Time, Timeline}; use tokio_stream::StreamExt; -use crate::dataframe::{ComponentLike, PyRecording, PyRecordingHandle, PyRecordingView}; +use crate::dataframe::{ComponentLike, PyRecording, PyRecordingHandle, PyRecordingView, PySchema}; /// Register the `rerun.remote` module. pub(crate) fn register(m: &Bound<'_, PyModule>) -> PyResult<()> { @@ -257,6 +258,42 @@ impl PyStorageNodeClient { Ok(PyArrowType(Box::new(reader))) } + #[pyo3(signature = (id,))] + /// Get the schema for a recording in the storage node. + /// + /// Parameters + /// ---------- + /// id : str + /// The id of the recording to get the schema for. + /// + /// Returns + /// ------- + /// Schema + /// The schema of the recording. + fn get_recording_schema(&mut self, id: String) -> PyResult { + self.runtime.block_on(async { + let request = GetRecordingSchemaRequest { + recording_id: Some(RecordingId { id }), + }; + + let column_descriptors = self + .client + .get_recording_schema(request) + .await + .map_err(|err| PyRuntimeError::new_err(err.to_string()))? + .into_inner() + .column_descriptors + .into_iter() + .map(|cd| cd.try_into()) + .collect::, _>>() + .map_err(|err: TypeConversionError| PyRuntimeError::new_err(err.to_string()))?; + + Ok(PySchema { + schema: column_descriptors, + }) + }) + } + /// Register a recording along with some metadata. /// /// Parameters From 39067923a3b0842cb529f0c340c1d43eca7b894a Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 14 Jan 2025 16:25:35 +0100 Subject: [PATCH 30/57] Fix performance regression due to extra arrow round-tripping (#8684) --- crates/store/re_chunk/src/chunk.rs | 18 ++++++++++++++++-- crates/store/re_chunk/src/merge.rs | 2 +- crates/store/re_chunk/src/migration.rs | 2 +- crates/store/re_chunk/src/transport.rs | 2 +- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/crates/store/re_chunk/src/chunk.rs b/crates/store/re_chunk/src/chunk.rs index 936c1cb6ef81..c47f0c4663a5 100644 --- a/crates/store/re_chunk/src/chunk.rs +++ b/crates/store/re_chunk/src/chunk.rs @@ -83,6 +83,20 @@ impl ChunkComponents { .map(|la| la.into()) } + #[inline] + pub fn insert_descriptor_arrow2( + &mut self, + component_desc: ComponentDescriptor, + list_array: Arrow2ListArray, + ) -> Option> { + // TODO(cmc): revert me + let component_desc = component_desc.untagged(); + self.0 + .entry(component_desc.component_name) + .or_default() + .insert(component_desc, list_array) + } + /// Returns all list arrays for the given component name. /// /// I.e semantically equivalent to `get("MyComponent:*.*")` @@ -181,7 +195,7 @@ impl FromIterator<(ComponentDescriptor, Arrow2ListArray)> for ChunkComponen let mut this = Self::default(); { for (component_desc, list_array) in iter { - this.insert_descriptor(component_desc, list_array.into()); + this.insert_descriptor_arrow2(component_desc, list_array); } } this @@ -956,7 +970,7 @@ impl Chunk { list_array: Arrow2ListArray, ) -> ChunkResult<()> { self.components - .insert_descriptor(component_desc, list_array.into()); + .insert_descriptor_arrow2(component_desc, list_array); self.sanity_check() } diff --git a/crates/store/re_chunk/src/merge.rs b/crates/store/re_chunk/src/merge.rs index 5236b8a02813..af80cfef1343 100644 --- a/crates/store/re_chunk/src/merge.rs +++ b/crates/store/re_chunk/src/merge.rs @@ -173,7 +173,7 @@ impl Chunk { let components = { let mut per_name = ChunkComponents::default(); for (component_desc, list_array) in components { - per_name.insert_descriptor(component_desc.clone(), list_array.into()); + per_name.insert_descriptor_arrow2(component_desc.clone(), list_array); } per_name }; diff --git a/crates/store/re_chunk/src/migration.rs b/crates/store/re_chunk/src/migration.rs index d641fc5f3713..fe50b9a53e20 100644 --- a/crates/store/re_chunk/src/migration.rs +++ b/crates/store/re_chunk/src/migration.rs @@ -88,7 +88,7 @@ impl Chunk { } for (desc, list_array) in components_patched { - chunk.components.insert_descriptor(desc, list_array.into()); + chunk.components.insert_descriptor_arrow2(desc, list_array); } chunk diff --git a/crates/store/re_chunk/src/transport.rs b/crates/store/re_chunk/src/transport.rs index 3239102b0416..c690b067c740 100644 --- a/crates/store/re_chunk/src/transport.rs +++ b/crates/store/re_chunk/src/transport.rs @@ -705,7 +705,7 @@ impl Chunk { let component_desc = TransportChunk::component_descriptor_from_field(field); if components - .insert_descriptor(component_desc, column.clone().into()) + .insert_descriptor_arrow2(component_desc, column.clone()) .is_some() { return Err(ChunkError::Malformed { From d4f99a1e66cb99d9d2b44c5f33e51a6c3fc86d80 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 14 Jan 2025 17:02:27 +0100 Subject: [PATCH 31/57] Partially revert `TimeColumnDescriptor` refactor (#8685) * Reverts rerun-io/rerun#8658 * Why? Because it conflicted with https://github.com/rerun-io/rerun/pull/8651 --- crates/store/re_chunk_store/src/dataframe.rs | 34 ++++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/crates/store/re_chunk_store/src/dataframe.rs b/crates/store/re_chunk_store/src/dataframe.rs index 95b70a779ecc..0484798837cb 100644 --- a/crates/store/re_chunk_store/src/dataframe.rs +++ b/crates/store/re_chunk_store/src/dataframe.rs @@ -4,7 +4,6 @@ use std::collections::{BTreeMap, BTreeSet}; use std::ops::Deref; use std::ops::DerefMut; -use arrow::datatypes::DataType as ArrowDatatype; use arrow2::{ array::ListArray as ArrowListArray, datatypes::{DataType as Arrow2Datatype, Field as Arrow2Field}, @@ -46,7 +45,7 @@ impl ColumnDescriptor { #[inline] pub fn datatype(&self) -> Arrow2Datatype { match self { - Self::Time(descr) => descr.datatype().into(), + Self::Time(descr) => descr.datatype.clone(), Self::Component(descr) => descr.returned_datatype(), } } @@ -80,9 +79,10 @@ impl ColumnDescriptor { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct TimeColumnDescriptor { /// The timeline this column is associated with. - timeline: Timeline, + pub timeline: Timeline, - is_null: bool, + /// The Arrow datatype of the column. + pub datatype: Arrow2Datatype, } impl PartialOrd for TimeColumnDescriptor { @@ -97,7 +97,7 @@ impl Ord for TimeColumnDescriptor { fn cmp(&self, other: &Self) -> std::cmp::Ordering { let Self { timeline, - is_null: _, + datatype: _, } = self; timeline.cmp(&other.timeline) } @@ -105,41 +105,40 @@ impl Ord for TimeColumnDescriptor { impl TimeColumnDescriptor { /// Used when returning a null column, i.e. when a lookup failed. + #[inline] pub fn new_null(name: TimelineName) -> Self { Self { // TODO(cmc): I picked a sequence here because I have to pick something. // It doesn't matter, only the name will remain in the Arrow schema anyhow. timeline: Timeline::new_sequence(name), - is_null: true, + datatype: Arrow2Datatype::Null, } } + #[inline] pub fn timeline(&self) -> Timeline { self.timeline } + #[inline] pub fn name(&self) -> &TimelineName { self.timeline.name() } + #[inline] pub fn typ(&self) -> re_log_types::TimeType { self.timeline.typ() } #[inline] - pub fn datatype(&self) -> ArrowDatatype { - let Self { timeline, is_null } = self; - if *is_null { - ArrowDatatype::Null - } else { - timeline.typ().datatype() - } + pub fn datatype(&self) -> &Arrow2Datatype { + &self.datatype } fn metadata(&self) -> arrow2::datatypes::Metadata { let Self { timeline, - is_null: _, + datatype: _, } = self; std::iter::once(Some(( @@ -152,8 +151,9 @@ impl TimeColumnDescriptor { #[inline] pub fn to_arrow_field(&self) -> Arrow2Field { + let Self { timeline, datatype } = self; let nullable = true; // Time column must be nullable since static data doesn't have a time. - Arrow2Field::new(self.name().to_string(), self.datatype().into(), nullable) + Arrow2Field::new(timeline.name().to_string(), datatype.clone(), nullable) .with_metadata(self.metadata()) } } @@ -735,7 +735,7 @@ impl ChunkStore { let timelines = self.all_timelines_sorted().into_iter().map(|timeline| { ColumnDescriptor::Time(TimeColumnDescriptor { timeline, - is_null: false, + datatype: timeline.datatype().into(), }) }); @@ -809,7 +809,7 @@ impl ChunkStore { TimeColumnDescriptor { timeline, - is_null: false, + datatype: timeline.datatype().into(), } } From c07eb6ef0ae4c653850279f9b557dc03f0986d76 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 14 Jan 2025 18:23:43 +0100 Subject: [PATCH 32/57] Port `TransportChunk::schema` to arrow-rs (#8687) * Part of #3741 --- Cargo.lock | 1 + crates/store/re_chunk/src/arrow.rs | 33 +-- crates/store/re_chunk/src/arrow2_util.rs | 33 ++- crates/store/re_chunk/src/transport.rs | 219 ++++++++++-------- crates/store/re_dataframe/src/query.rs | 60 ++--- crates/store/re_grpc_client/Cargo.toml | 1 + crates/store/re_grpc_client/src/lib.rs | 39 ++-- .../viewer/re_chunk_store_ui/src/chunk_ui.rs | 23 +- rerun_py/src/arrow.rs | 2 +- rerun_py/src/remote.rs | 17 +- 10 files changed, 217 insertions(+), 211 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 66fdf6678a5d..85eeabf7fead 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6009,6 +6009,7 @@ dependencies = [ name = "re_grpc_client" version = "0.22.0-alpha.1+dev" dependencies = [ + "arrow", "re_chunk", "re_error", "re_log", diff --git a/crates/store/re_chunk/src/arrow.rs b/crates/store/re_chunk/src/arrow.rs index 4f10fc039c45..32642e298555 100644 --- a/crates/store/re_chunk/src/arrow.rs +++ b/crates/store/re_chunk/src/arrow.rs @@ -1,6 +1,5 @@ use arrow::{ array::{make_array, RecordBatch}, - datatypes::{Field, Schema}, error::ArrowError, }; @@ -13,28 +12,15 @@ impl TransportChunk { /// but does incur overhead of generating an alternative representation of the arrow- /// related rust structures that refer to those data buffers. pub fn try_to_arrow_record_batch(&self) -> Result { - let fields: Vec = self - .schema - .fields - .iter() - .map(|f| f.clone().into()) - .collect(); - - let metadata = self.schema.metadata.clone().into_iter().collect(); - - let schema = Schema::new_with_metadata(fields, metadata); - let columns: Vec<_> = self - .data - .columns() - .iter() - .map(|arr2_array| { + .all_columns() + .map(|(_field, arr2_array)| { let data = arrow2::array::to_data(arr2_array.as_ref()); make_array(data) }) .collect(); - RecordBatch::try_new(std::sync::Arc::new(schema), columns) + RecordBatch::try_new(self.schema(), columns) } /// Create a [`TransportChunk`] from an arrow-rs [`RecordBatch`]. @@ -43,17 +29,6 @@ impl TransportChunk { /// but does incur overhead of generating an alternative representation of the arrow- /// related rust structures that refer to those data buffers. pub fn from_arrow_record_batch(batch: &RecordBatch) -> Self { - let fields: Vec = batch - .schema() - .fields - .iter() - .map(|f| f.clone().into()) - .collect(); - - let metadata = batch.schema().metadata.clone().into_iter().collect(); - - let schema = arrow2::datatypes::Schema::from(fields).with_metadata(metadata); - let columns: Vec<_> = batch .columns() .iter() @@ -62,6 +37,6 @@ impl TransportChunk { let data = arrow2::chunk::Chunk::new(columns); - Self { schema, data } + Self::new(batch.schema(), data) } } diff --git a/crates/store/re_chunk/src/arrow2_util.rs b/crates/store/re_chunk/src/arrow2_util.rs index 99ad03eefdf2..cebfa8505e31 100644 --- a/crates/store/re_chunk/src/arrow2_util.rs +++ b/crates/store/re_chunk/src/arrow2_util.rs @@ -1,3 +1,4 @@ +use arrow::datatypes::Schema as ArrowSchema; use arrow2::{ array::{ Array as Arrow2Array, BooleanArray as Arrow2BooleanArray, @@ -438,7 +439,7 @@ pub fn take_array( // --- -use arrow2::{chunk::Chunk as Arrow2Chunk, datatypes::Schema as Arrow2Schema}; +use arrow2::chunk::Chunk as Arrow2Chunk; /// Concatenate multiple [`TransportChunk`]s into one. /// @@ -446,24 +447,32 @@ use arrow2::{chunk::Chunk as Arrow2Chunk, datatypes::Schema as Arrow2Schema}; /// * `arrow2` doesn't have a `RecordBatch` type, therefore we emulate that using our `TransportChunk`s. /// * `arrow-rs` does have one, and it natively supports concatenation. pub fn concatenate_record_batches( - schema: Arrow2Schema, + schema: impl Into, batches: &[TransportChunk], ) -> anyhow::Result { - assert!(batches.iter().map(|batch| batch.schema_ref()).all_equal()); + let schema: ArrowSchema = schema.into(); + anyhow::ensure!( + batches + .iter() + .all(|batch| batch.schema_ref().as_ref() == &schema), + "concatenate_record_batches: all batches must have the same schema" + ); - let mut arrays = Vec::new(); + let mut output_columns = Vec::new(); if !batches.is_empty() { for (i, _field) in schema.fields.iter().enumerate() { - let array = concat_arrays( - &batches - .iter() - .map(|batch| &*batch.data[i] as &dyn Arrow2Array) - .collect_vec(), - )?; - arrays.push(array); + let arrays: Option> = batches.iter().map(|batch| batch.column(i)).collect(); + let arrays = arrays.ok_or_else(|| { + anyhow::anyhow!("concatenate_record_batches: all batches must have the same schema") + })?; + let array = concat_arrays(&arrays)?; + output_columns.push(array); } } - Ok(TransportChunk::new(schema, Arrow2Chunk::new(arrays))) + Ok(TransportChunk::new( + schema, + Arrow2Chunk::new(output_columns), + )) } diff --git a/crates/store/re_chunk/src/transport.rs b/crates/store/re_chunk/src/transport.rs index c690b067c740..3fe57fad8d09 100644 --- a/crates/store/re_chunk/src/transport.rs +++ b/crates/store/re_chunk/src/transport.rs @@ -1,28 +1,32 @@ -use arrow::array::{ - Array as ArrowArray, ArrayRef as ArrowArrayRef, RecordBatch as ArrowRecordBatch, - StructArray as ArrowStructArray, +use std::sync::Arc; + +use arrow::{ + array::{ + Array as ArrowArray, ArrayRef as ArrowArrayRef, RecordBatch as ArrowRecordBatch, + StructArray as ArrowStructArray, + }, + datatypes::{Field as ArrowField, Schema as ArrowSchema, SchemaRef as ArrowSchemaRef}, }; use arrow2::{ - array::{Array as Arrow2Array, ListArray}, + array::{Array as Arrow2Array, ListArray as Arrow2ListArray}, chunk::Chunk as Arrow2Chunk, - datatypes::{ - DataType as Arrow2Datatype, Field as ArrowField, Metadata as Arrow2Metadata, - Schema as Arrow2Schema, TimeUnit as ArrowTimeUnit, - }, + datatypes::{DataType as Arrow2Datatype, TimeUnit as Arrow2TimeUnit}, }; use itertools::Itertools; use nohash_hasher::IntMap; +use tap::Tap as _; use re_byte_size::SizeBytes as _; use re_log_types::{EntityPath, Timeline}; use re_types_core::{Component as _, ComponentDescriptor, Loggable as _}; -use tap::Tap as _; use crate::{ arrow_util::into_arrow_ref, chunk::ChunkComponents, Chunk, ChunkError, ChunkId, ChunkResult, RowId, TimeColumn, }; +pub type ArrowMetadata = std::collections::HashMap; + // --- /// A [`Chunk`] that is ready for transport. Obtained by calling [`Chunk::to_transport`]. @@ -42,10 +46,10 @@ pub struct TransportChunk { /// /// Take a look at the `TransportChunk::CHUNK_METADATA_*` and `TransportChunk::FIELD_METADATA_*` /// constants for more information about available metadata. - pub schema: Arrow2Schema, + schema: ArrowSchemaRef, /// All the control, time and component data. - pub data: Arrow2Chunk>, + data: Arrow2Chunk>, } impl std::fmt::Display for TransportChunk { @@ -54,12 +58,7 @@ impl std::fmt::Display for TransportChunk { // TODO(#3741): simplify code when we have migrated to arrow-rs re_format_arrow::format_dataframe( &self.schema.metadata.clone().into_iter().collect(), - &self - .schema - .fields - .iter() - .map(|field| arrow::datatypes::Field::from(field.clone())) - .collect(), + &self.schema.fields, &self .data .iter() @@ -72,7 +71,7 @@ impl std::fmt::Display for TransportChunk { impl TransportChunk { pub fn new( - schema: impl Into, + schema: impl Into, columns: impl Into>>, ) -> Self { Self { @@ -103,7 +102,7 @@ impl TryFrom for ArrowRecordBatch { fn try_from(chunk: TransportChunk) -> Result { let TransportChunk { schema, data } = chunk; Self::try_new( - schema.into(), + schema, data.columns() .iter() .map(|column| column.clone().into()) @@ -115,44 +114,44 @@ impl TryFrom for ArrowRecordBatch { // TODO(#6572): Relying on Arrow's native schema metadata feature is bound to fail, we need to // switch to something more powerful asap. impl TransportChunk { - /// The key used to identify a Rerun [`ChunkId`] in chunk-level [`Arrow2Schema`] metadata. + /// The key used to identify a Rerun [`ChunkId`] in chunk-level [`ArrowSchema`] metadata. pub const CHUNK_METADATA_KEY_ID: &'static str = "rerun.id"; - /// The key used to identify a Rerun [`EntityPath`] in chunk-level [`Arrow2Schema`] metadata. + /// The key used to identify a Rerun [`EntityPath`] in chunk-level [`ArrowSchema`] metadata. pub const CHUNK_METADATA_KEY_ENTITY_PATH: &'static str = "rerun.entity_path"; /// The key used to identify the size in bytes of the data, once loaded in memory, in chunk-level - /// [`Arrow2Schema`] metadata. + /// [`ArrowSchema`] metadata. pub const CHUNK_METADATA_KEY_HEAP_SIZE_BYTES: &'static str = "rerun.heap_size_bytes"; - /// The marker used to identify whether a chunk is sorted in chunk-level [`Arrow2Schema`] metadata. + /// The marker used to identify whether a chunk is sorted in chunk-level [`ArrowSchema`] metadata. /// /// The associated value is irrelevant -- if this marker is present, then it is true. /// /// Chunks are ascendingly sorted by their `RowId` column. pub const CHUNK_METADATA_MARKER_IS_SORTED_BY_ROW_ID: &'static str = "rerun.is_sorted"; - /// The key used to identify the kind of a Rerun column in field-level [`Arrow2Schema`] metadata. + /// The key used to identify the kind of a Rerun column in field-level [`ArrowSchema`] metadata. /// /// That is: control columns (e.g. `row_id`), time columns or component columns. pub const FIELD_METADATA_KEY_KIND: &'static str = "rerun.kind"; - /// The value used to identify a Rerun time column in field-level [`Arrow2Schema`] metadata. + /// The value used to identify a Rerun time column in field-level [`ArrowSchema`] metadata. pub const FIELD_METADATA_VALUE_KIND_TIME: &'static str = "time"; - /// The value used to identify a Rerun control column in field-level [`Arrow2Schema`] metadata. + /// The value used to identify a Rerun control column in field-level [`ArrowSchema`] metadata. pub const FIELD_METADATA_VALUE_KIND_CONTROL: &'static str = "control"; - /// The value used to identify a Rerun data column in field-level [`Arrow2Schema`] metadata. + /// The value used to identify a Rerun data column in field-level [`ArrowSchema`] metadata. pub const FIELD_METADATA_VALUE_KIND_DATA: &'static str = "data"; - /// The key used to identify the [`crate::ArchetypeName`] in field-level [`Arrow2Schema`] metadata. + /// The key used to identify the [`crate::ArchetypeName`] in field-level [`ArrowSchema`] metadata. pub const FIELD_METADATA_KEY_ARCHETYPE_NAME: &'static str = "rerun.archetype_name"; - /// The key used to identify the [`crate::ArchetypeFieldName`] in field-level [`Arrow2Schema`] metadata. + /// The key used to identify the [`crate::ArchetypeFieldName`] in field-level [`ArrowSchema`] metadata. pub const FIELD_METADATA_KEY_ARCHETYPE_FIELD_NAME: &'static str = "rerun.archetype_field_name"; - /// The marker used to identify whether a column is sorted in field-level [`Arrow2Schema`] metadata. + /// The marker used to identify whether a column is sorted in field-level [`ArrowSchema`] metadata. /// /// The associated value is irrelevant -- if this marker is present, then it is true. /// @@ -162,9 +161,9 @@ impl TransportChunk { pub const FIELD_METADATA_MARKER_IS_SORTED_BY_TIME: &'static str = Self::CHUNK_METADATA_MARKER_IS_SORTED_BY_ROW_ID; - /// Returns the appropriate chunk-level [`Arrow2Schema`] metadata for a Rerun [`ChunkId`]. + /// Returns the appropriate chunk-level [`ArrowSchema`] metadata for a Rerun [`ChunkId`]. #[inline] - pub fn chunk_metadata_id(id: ChunkId) -> Arrow2Metadata { + pub fn chunk_metadata_id(id: ChunkId) -> ArrowMetadata { [ ( Self::CHUNK_METADATA_KEY_ID.to_owned(), @@ -174,9 +173,9 @@ impl TransportChunk { .into() } - /// Returns the appropriate chunk-level [`Arrow2Schema`] metadata for the in-memory size in bytes. + /// Returns the appropriate chunk-level [`ArrowSchema`] metadata for the in-memory size in bytes. #[inline] - pub fn chunk_metadata_heap_size_bytes(heap_size_bytes: u64) -> Arrow2Metadata { + pub fn chunk_metadata_heap_size_bytes(heap_size_bytes: u64) -> ArrowMetadata { [ ( Self::CHUNK_METADATA_KEY_HEAP_SIZE_BYTES.to_owned(), @@ -186,9 +185,9 @@ impl TransportChunk { .into() } - /// Returns the appropriate chunk-level [`Arrow2Schema`] metadata for a Rerun [`EntityPath`]. + /// Returns the appropriate chunk-level [`ArrowSchema`] metadata for a Rerun [`EntityPath`]. #[inline] - pub fn chunk_metadata_entity_path(entity_path: &EntityPath) -> Arrow2Metadata { + pub fn chunk_metadata_entity_path(entity_path: &EntityPath) -> ArrowMetadata { [ ( Self::CHUNK_METADATA_KEY_ENTITY_PATH.to_owned(), @@ -198,9 +197,9 @@ impl TransportChunk { .into() } - /// Returns the appropriate chunk-level [`Arrow2Schema`] metadata for an `IS_SORTED` marker. + /// Returns the appropriate chunk-level [`ArrowSchema`] metadata for an `IS_SORTED` marker. #[inline] - pub fn chunk_metadata_is_sorted() -> Arrow2Metadata { + pub fn chunk_metadata_is_sorted() -> ArrowMetadata { [ ( Self::CHUNK_METADATA_MARKER_IS_SORTED_BY_ROW_ID.to_owned(), @@ -210,9 +209,9 @@ impl TransportChunk { .into() } - /// Returns the appropriate field-level [`Arrow2Schema`] metadata for a Rerun time column. + /// Returns the appropriate field-level [`ArrowSchema`] metadata for a Rerun time column. #[inline] - pub fn field_metadata_time_column() -> Arrow2Metadata { + pub fn field_metadata_time_column() -> ArrowMetadata { [ ( Self::FIELD_METADATA_KEY_KIND.to_owned(), @@ -222,9 +221,9 @@ impl TransportChunk { .into() } - /// Returns the appropriate field-level [`Arrow2Schema`] metadata for a Rerun control column. + /// Returns the appropriate field-level [`ArrowSchema`] metadata for a Rerun control column. #[inline] - pub fn field_metadata_control_column() -> Arrow2Metadata { + pub fn field_metadata_control_column() -> ArrowMetadata { [ ( Self::FIELD_METADATA_KEY_KIND.to_owned(), @@ -234,9 +233,9 @@ impl TransportChunk { .into() } - /// Returns the appropriate field-level [`Arrow2Schema`] metadata for a Rerun data column. + /// Returns the appropriate field-level [`ArrowSchema`] metadata for a Rerun data column. #[inline] - pub fn field_metadata_data_column() -> Arrow2Metadata { + pub fn field_metadata_data_column() -> ArrowMetadata { [ ( Self::FIELD_METADATA_KEY_KIND.to_owned(), @@ -246,9 +245,9 @@ impl TransportChunk { .into() } - /// Returns the appropriate field-level [`Arrow2Schema`] metadata for an `IS_SORTED` marker. + /// Returns the appropriate field-level [`ArrowSchema`] metadata for an `IS_SORTED` marker. #[inline] - pub fn field_metadata_is_sorted() -> Arrow2Metadata { + pub fn field_metadata_is_sorted() -> ArrowMetadata { [ ( Self::FIELD_METADATA_MARKER_IS_SORTED_BY_TIME.to_owned(), @@ -261,7 +260,7 @@ impl TransportChunk { #[inline] pub fn field_metadata_component_descriptor( component_desc: &ComponentDescriptor, - ) -> Arrow2Metadata { + ) -> ArrowMetadata { component_desc .archetype_name .iter() @@ -287,13 +286,13 @@ impl TransportChunk { pub fn component_descriptor_from_field(field: &ArrowField) -> ComponentDescriptor { ComponentDescriptor { archetype_name: field - .metadata + .metadata() .get(Self::FIELD_METADATA_KEY_ARCHETYPE_NAME) .cloned() .map(Into::into), - component_name: field.name.clone().into(), + component_name: field.name().clone().into(), archetype_field_name: field - .metadata + .metadata() .get(Self::FIELD_METADATA_KEY_ARCHETYPE_FIELD_NAME) .cloned() .map(Into::into), @@ -345,10 +344,19 @@ impl TransportChunk { } #[inline] - pub fn schema_ref(&self) -> &Arrow2Schema { + pub fn schema(&self) -> ArrowSchemaRef { + self.schema.clone() + } + + #[inline] + pub fn schema_ref(&self) -> &ArrowSchemaRef { &self.schema } + pub fn insert_metadata(&mut self, key: String, value: String) { + Arc::make_mut(&mut self.schema).metadata.insert(key, value); + } + /// Looks in the chunk metadata for the `IS_SORTED` marker. /// /// It is possible that a chunk is sorted but didn't set that marker. @@ -360,6 +368,12 @@ impl TransportChunk { .contains_key(Self::CHUNK_METADATA_MARKER_IS_SORTED_BY_ROW_ID) } + /// Access specific column + #[inline] + pub fn column(&self, index: usize) -> Option<&dyn Arrow2Array> { + self.data.get(index).map(|c| c.as_ref()) + } + /// Iterates all columns of the specified `kind`. /// /// See: @@ -376,9 +390,14 @@ impl TransportChunk { .iter() .enumerate() .filter_map(|(i, field)| { - let actual_kind = field.metadata.get(Self::FIELD_METADATA_KEY_KIND); + let actual_kind = field.metadata().get(Self::FIELD_METADATA_KEY_KIND); (actual_kind.map(|s| s.as_str()) == Some(kind)) - .then(|| self.data.columns().get(i).map(|column| (field, column))) + .then(|| { + self.data + .columns() + .get(i) + .map(|column| (field.as_ref(), column)) + }) .flatten() }) } @@ -389,7 +408,17 @@ impl TransportChunk { .fields .iter() .enumerate() - .filter_map(|(i, field)| self.data.columns().get(i).map(|column| (field, column))) + .filter_map(|(i, field)| { + self.data + .columns() + .get(i) + .map(|column| (field.as_ref(), column)) + }) + } + + #[inline] + pub fn all_columns_collected(&self) -> Vec<&dyn Arrow2Array> { + self.data.iter().map(|c| c.as_ref()).collect() } /// Iterates all control columns present in this chunk. @@ -460,7 +489,8 @@ impl Chunk { components, } = self; - let mut schema = Arrow2Schema::default(); + let mut fields: Vec = vec![]; + let mut metadata = std::collections::HashMap::default(); let mut columns: Vec> = Vec::with_capacity(1 /* row_ids */ + timelines.len() + components.len()); @@ -468,24 +498,16 @@ impl Chunk { { re_tracing::profile_scope!("metadata"); - schema - .metadata - .extend(TransportChunk::chunk_metadata_id(*id)); + metadata.extend(TransportChunk::chunk_metadata_id(*id)); - schema - .metadata - .extend(TransportChunk::chunk_metadata_entity_path(entity_path)); + metadata.extend(TransportChunk::chunk_metadata_entity_path(entity_path)); - schema - .metadata - .extend(TransportChunk::chunk_metadata_heap_size_bytes( - self.heap_size_bytes(), - )); + metadata.extend(TransportChunk::chunk_metadata_heap_size_bytes( + self.heap_size_bytes(), + )); if *is_sorted { - schema - .metadata - .extend(TransportChunk::chunk_metadata_is_sorted()); + metadata.extend(TransportChunk::chunk_metadata_is_sorted()); } } @@ -493,10 +515,10 @@ impl Chunk { { re_tracing::profile_scope!("row ids"); - schema.fields.push( + fields.push( ArrowField::new( RowId::descriptor().to_string(), - RowId::arrow_datatype().clone().into(), + RowId::arrow_datatype().clone(), false, ) .with_metadata( @@ -527,18 +549,15 @@ impl Chunk { } = info; let nullable = false; // timelines within a single chunk are always dense - let field = ArrowField::new( - timeline.name().to_string(), - timeline.datatype().into(), - nullable, - ) - .with_metadata({ - let mut metadata = TransportChunk::field_metadata_time_column(); - if *is_sorted { - metadata.extend(TransportChunk::field_metadata_is_sorted()); - } - metadata - }); + let field = + ArrowField::new(timeline.name().to_string(), timeline.datatype(), nullable) + .with_metadata({ + let mut metadata = TransportChunk::field_metadata_time_column(); + if *is_sorted { + metadata.extend(TransportChunk::field_metadata_is_sorted()); + } + metadata + }); let times = info.times_array(); @@ -546,10 +565,11 @@ impl Chunk { }) .collect_vec(); - timelines.sort_by(|(field1, _times1), (field2, _times2)| field1.name.cmp(&field2.name)); + timelines + .sort_by(|(field1, _times1), (field2, _times2)| field1.name().cmp(field2.name())); for (field, times) in timelines { - schema.fields.push(field); + fields.push(field); columns.push(times.into()); } } @@ -564,7 +584,7 @@ impl Chunk { .map(|(component_desc, list_array)| { let field = ArrowField::new( component_desc.component_name.to_string(), - list_array.data_type().clone(), + list_array.data_type().clone().into(), true, ) .with_metadata({ @@ -581,14 +601,17 @@ impl Chunk { }) .collect_vec(); - components.sort_by(|(field1, _data1), (field2, _data2)| field1.name.cmp(&field2.name)); + components + .sort_by(|(field1, _data1), (field2, _data2)| field1.name().cmp(field2.name())); for (field, data) in components { - schema.fields.push(field); + fields.push(field); columns.push(data); } } + let schema = ArrowSchema::new_with_metadata(fields, metadata); + Ok(TransportChunk::new(schema, Arrow2Chunk::new(columns))) } @@ -619,7 +642,7 @@ impl Chunk { let Some(row_ids) = transport.controls().find_map(|(field, column)| { // TODO(cmc): disgusting, but good enough for now. - (field.name == RowId::descriptor().component_name.as_str()).then_some(column) + (field.name() == RowId::descriptor().component_name.as_str()).then_some(column) }) else { return Err(ChunkError::Malformed { reason: format!("missing row_id column ({:?})", transport.schema), @@ -648,15 +671,15 @@ impl Chunk { for (field, column) in transport.timelines() { // See also [`Timeline::datatype`] let timeline = match column.data_type().to_logical_type() { - Arrow2Datatype::Int64 => Timeline::new_sequence(field.name.as_str()), - Arrow2Datatype::Timestamp(ArrowTimeUnit::Nanosecond, None) => { - Timeline::new_temporal(field.name.as_str()) + Arrow2Datatype::Int64 => Timeline::new_sequence(field.name().as_str()), + Arrow2Datatype::Timestamp(Arrow2TimeUnit::Nanosecond, None) => { + Timeline::new_temporal(field.name().as_str()) } _ => { return Err(ChunkError::Malformed { reason: format!( "time column '{}' is not deserializable ({:?})", - field.name, + field.name(), column.data_type() ), }); @@ -665,12 +688,12 @@ impl Chunk { let times = TimeColumn::read_array(&ArrowArrayRef::from(column.clone())).map_err( |err| ChunkError::Malformed { - reason: format!("Bad time column '{}': {err}", field.name), + reason: format!("Bad time column '{}': {err}", field.name()), }, )?; let is_sorted = field - .metadata + .metadata() .contains_key(TransportChunk::FIELD_METADATA_MARKER_IS_SORTED_BY_TIME); let time_column = TimeColumn::new(is_sorted.then_some(true), timeline, times); @@ -678,7 +701,7 @@ impl Chunk { return Err(ChunkError::Malformed { reason: format!( "time column '{}' was specified more than once", - field.name, + field.name(), ), }); } @@ -694,7 +717,7 @@ impl Chunk { for (field, column) in transport.components() { let column = column .as_any() - .downcast_ref::>() + .downcast_ref::>() .ok_or_else(|| ChunkError::Malformed { reason: format!( "The outer array in a chunked component batch must be a sparse list, got {:?}", @@ -711,7 +734,7 @@ impl Chunk { return Err(ChunkError::Malformed { reason: format!( "component column '{}' was specified more than once", - field.name, + field.name(), ), }); } diff --git a/crates/store/re_dataframe/src/query.rs b/crates/store/re_dataframe/src/query.rs index 16801c116489..955e2099b944 100644 --- a/crates/store/re_dataframe/src/query.rs +++ b/crates/store/re_dataframe/src/query.rs @@ -1397,7 +1397,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -1432,7 +1432,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -1479,7 +1479,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -1525,7 +1525,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -1577,7 +1577,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -1632,7 +1632,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -1675,7 +1675,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -1729,7 +1729,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = "[]"; similar_asserts::assert_eq!(expected, got); @@ -1758,7 +1758,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = "[]"; similar_asserts::assert_eq!(expected, got); @@ -1787,7 +1787,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -1826,7 +1826,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -1881,7 +1881,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = "[]"; similar_asserts::assert_eq!(expected, got); @@ -1921,7 +1921,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -1971,7 +1971,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = "[]"; similar_asserts::assert_eq!(expected, got); @@ -2007,7 +2007,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -2058,7 +2058,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -2131,7 +2131,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -2219,7 +2219,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -2273,7 +2273,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -2314,7 +2314,7 @@ mod tests { // static clear semantics in general are pretty unhinged right now, especially when // ranges are involved. // It's extremely niche, our time is better spent somewhere else right now. - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -2374,8 +2374,8 @@ mod tests { &query_handle.batch_iter().take(3).collect_vec(), )?; - let expected = format!("{:#?}", expected.data.iter().collect_vec()); - let got = format!("{:#?}", got.data.iter().collect_vec()); + let expected = format!("{:#?}", expected.all_columns_collected()); + let got = format!("{:#?}", got.all_columns_collected()); similar_asserts::assert_eq!(expected, got); } @@ -2415,8 +2415,8 @@ mod tests { &query_handle.batch_iter().take(3).collect_vec(), )?; - let expected = format!("{:#?}", expected.data.iter().collect_vec()); - let got = format!("{:#?}", got.data.iter().collect_vec()); + let expected = format!("{:#?}", expected.all_columns_collected()); + let got = format!("{:#?}", got.all_columns_collected()); similar_asserts::assert_eq!(expected, got); } @@ -2459,8 +2459,8 @@ mod tests { &query_handle.batch_iter().take(3).collect_vec(), )?; - let expected = format!("{:#?}", expected.data.iter().collect_vec()); - let got = format!("{:#?}", got.data.iter().collect_vec()); + let expected = format!("{:#?}", expected.all_columns_collected()); + let got = format!("{:#?}", got.all_columns_collected()); similar_asserts::assert_eq!(expected, got); } @@ -2497,8 +2497,8 @@ mod tests { &query_handle.batch_iter().take(3).collect_vec(), )?; - let expected = format!("{:#?}", expected.data.iter().collect_vec()); - let got = format!("{:#?}", got.data.iter().collect_vec()); + let expected = format!("{:#?}", expected.all_columns_collected()); + let got = format!("{:#?}", got.all_columns_collected()); similar_asserts::assert_eq!(expected, got); } @@ -2565,7 +2565,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ @@ -2609,7 +2609,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.data.iter().collect_vec()); + let got = format!("{:#?}", dataframe.all_columns_collected()); let expected = unindent::unindent( "\ [ diff --git a/crates/store/re_grpc_client/Cargo.toml b/crates/store/re_grpc_client/Cargo.toml index 7fcc26102500..7b167c564a5a 100644 --- a/crates/store/re_grpc_client/Cargo.toml +++ b/crates/store/re_grpc_client/Cargo.toml @@ -29,6 +29,7 @@ re_protos.workspace = true re_smart_channel.workspace = true re_types.workspace = true +arrow.workspace = true thiserror.workspace = true tokio-stream.workspace = true url.workspace = true diff --git a/crates/store/re_grpc_client/src/lib.rs b/crates/store/re_grpc_client/src/lib.rs index 75bb835ec146..0be4b33f743e 100644 --- a/crates/store/re_grpc_client/src/lib.rs +++ b/crates/store/re_grpc_client/src/lib.rs @@ -17,11 +17,11 @@ use url::Url; // ---------------------------------------------------------------------------- -use std::error::Error; use std::sync::Arc; +use std::{collections::HashMap, error::Error}; +use arrow::datatypes::{DataType as ArrowDataType, Field as ArrowField}; use arrow2::array::Utf8Array as Arrow2Utf8Array; -use arrow2::datatypes::Field as Arrow2Field; use re_chunk::{ Arrow2Array, Chunk, ChunkBuilder, ChunkId, EntityPath, RowId, Timeline, TransportChunk, }; @@ -275,7 +275,7 @@ pub fn store_info_from_catalog_chunk( let (_field, data) = tc .components() - .find(|(f, _)| f.name == "application_id") + .find(|(f, _)| f.name() == "application_id") .ok_or(StreamError::ChunkError(re_chunk::ChunkError::Malformed { reason: "no application_id field found".to_owned(), }))?; @@ -289,7 +289,7 @@ pub fn store_info_from_catalog_chunk( let (_field, data) = tc .components() - .find(|(f, _)| f.name == "start_time") + .find(|(f, _)| f.name() == "start_time") .ok_or(StreamError::ChunkError(re_chunk::ChunkError::Malformed { reason: "no start_time field found".to_owned(), }))?; @@ -402,7 +402,7 @@ async fn stream_catalog_async( )?; fields.push( - Arrow2Field::new( + ArrowField::new( RowId::name().to_string(), // need to rename to Rerun Chunk expected control field row_id_field.data_type().clone(), false, /* not nullable */ @@ -420,11 +420,11 @@ async fn stream_catalog_async( // now add all the 'data' fields - we slice each column array into individual arrays and then convert the whole lot into a ListArray for (field, data) in input.components() { let data_field_inner = - Arrow2Field::new("item", field.data_type().clone(), true /* nullable */); + ArrowField::new("item", field.data_type().clone(), true /* nullable */); - let data_field = Arrow2Field::new( - field.name.clone(), - arrow2::datatypes::DataType::List(Arc::new(data_field_inner.clone())), + let data_field = ArrowField::new( + field.name().clone(), + ArrowDataType::List(Arc::new(data_field_inner.clone())), false, /* not nullable */ ) .with_metadata(TransportChunk::field_metadata_data_column()); @@ -440,7 +440,7 @@ async fn stream_catalog_async( #[allow(clippy::unwrap_used)] // we know we've given the right field type let data_field_array: arrow2::array::ListArray = re_chunk::arrow2_util::arrays_to_list_array( - data_field_inner.data_type().clone(), + data_field_inner.data_type().clone().into(), &data_arrays, ) .unwrap(); @@ -449,16 +449,17 @@ async fn stream_catalog_async( arrays.push(Box::new(data_field_array)); } - let mut schema = arrow2::datatypes::Schema::from(fields); - schema.metadata.insert( - TransportChunk::CHUNK_METADATA_KEY_ENTITY_PATH.to_owned(), - "catalog".to_owned(), - ); + let schema = { + let metadata = HashMap::from_iter([( + TransportChunk::CHUNK_METADATA_KEY_ENTITY_PATH.to_owned(), + "catalog".to_owned(), + )]); + arrow::datatypes::Schema::new_with_metadata(fields, metadata) + }; // modified and enriched TransportChunk let mut tc = TransportChunk::new(schema, arrow2::chunk::Chunk::new(arrays)); - - tc.schema.metadata.insert( + tc.insert_metadata( TransportChunk::CHUNK_METADATA_KEY_ID.to_owned(), ChunkId::new().to_string(), ); @@ -497,10 +498,10 @@ async fn stream_catalog_async( .map(|e| Some(e.as_ref())) .collect::>(); - let rec_id_field = Arrow2Field::new("item", arrow2::datatypes::DataType::Utf8, true); + let rec_id_field = ArrowField::new("item", ArrowDataType::Utf8, true); #[allow(clippy::unwrap_used)] // we know we've given the right field type let uris = re_chunk::arrow2_util::arrays_to_list_array( - rec_id_field.data_type().clone(), + rec_id_field.data_type().clone().into(), &recording_id_arrays, ) .unwrap(); diff --git a/crates/viewer/re_chunk_store_ui/src/chunk_ui.rs b/crates/viewer/re_chunk_store_ui/src/chunk_ui.rs index 0efbee8c4067..fdce2d37c6db 100644 --- a/crates/viewer/re_chunk_store_ui/src/chunk_ui.rs +++ b/crates/viewer/re_chunk_store_ui/src/chunk_ui.rs @@ -194,24 +194,25 @@ impl ChunkUi { // Returns true if the user wants to exit the chunk viewer. fn chunk_info_ui(&self, ui: &mut egui::Ui) -> bool { - let metadata_ui = |ui: &mut egui::Ui, metadata: &BTreeMap| { - for (key, value) in metadata { - ui.list_item_flat_noninteractive( - list_item::PropertyContent::new(key).value_text(value), - ); - } - }; + let metadata_ui = + |ui: &mut egui::Ui, metadata: &std::collections::HashMap| { + for (key, value) in metadata.iter().sorted() { + ui.list_item_flat_noninteractive( + list_item::PropertyContent::new(key).value_text(value), + ); + } + }; let fields_ui = |ui: &mut egui::Ui, transport: &TransportChunk| { for field in &transport.schema_ref().fields { - ui.push_id(field.name.clone(), |ui| { - ui.list_item_collapsible_noninteractive_label(&field.name, false, |ui| { + ui.push_id(field.name().clone(), |ui| { + ui.list_item_collapsible_noninteractive_label(field.name(), false, |ui| { ui.list_item_collapsible_noninteractive_label("Data type", false, |ui| { - ui.label(format!("{:#?}", field.data_type)); + ui.label(format!("{:#?}", field.data_type())); }); ui.list_item_collapsible_noninteractive_label("Metadata", false, |ui| { - metadata_ui(ui, &field.metadata); + metadata_ui(ui, field.metadata()); }); }); }); diff --git a/rerun_py/src/arrow.rs b/rerun_py/src/arrow.rs index e150be7fc33b..87a6968e5f07 100644 --- a/rerun_py/src/arrow.rs +++ b/rerun_py/src/arrow.rs @@ -70,7 +70,7 @@ pub fn array_to_rust( datatype.clone(), true, ) - .with_metadata(metadata); + .with_metadata(metadata.into_iter().collect()); // TODO(#3741) Ok((arr2_array, field)) } diff --git a/rerun_py/src/remote.rs b/rerun_py/src/remote.rs index ed0d7d779e00..b7aa30b30d1a 100644 --- a/rerun_py/src/remote.rs +++ b/rerun_py/src/remote.rs @@ -4,7 +4,7 @@ use std::collections::BTreeSet; use arrow::{ array::{RecordBatch, RecordBatchIterator, RecordBatchReader}, - datatypes::Schema, + datatypes::Schema as ArrowSchema, ffi_stream::ArrowArrayStreamReader, pyarrow::PyArrowType, }; @@ -168,17 +168,12 @@ impl PyStorageNodeClient { let schema = batches .first() - .map(|batch| batch.schema.clone()) - .unwrap_or_default(); - - let fields: Vec = - schema.fields.iter().map(|f| f.clone().into()).collect(); - let metadata = schema.metadata.clone().into_iter().collect(); - let schema = arrow::datatypes::Schema::new_with_metadata(fields, metadata); + .map(|batch| batch.schema()) + .unwrap_or_else(|| ArrowSchema::empty().into()); Ok(RecordBatchIterator::new( batches.into_iter().map(|tc| tc.try_to_arrow_record_batch()), - std::sync::Arc::new(schema), + schema, )) }); @@ -248,7 +243,7 @@ impl PyStorageNodeClient { let schema = record_batches .first() .and_then(|batch| batch.as_ref().ok().map(|batch| batch.schema())) - .unwrap_or(std::sync::Arc::new(Schema::empty())); + .unwrap_or(std::sync::Arc::new(ArrowSchema::empty())); let reader = RecordBatchIterator::new(record_batches, schema); @@ -352,7 +347,7 @@ impl PyStorageNodeClient { let recording_id = metadata .all_columns() - .find(|(field, _data)| field.name == "rerun_recording_id") + .find(|(field, _data)| field.name() == "rerun_recording_id") .map(|(_field, data)| data) .ok_or(PyRuntimeError::new_err("No rerun_recording_id"))? .as_any() From 20b0b11aa361b96bcb6c3b1651abe844f030d4ec Mon Sep 17 00:00:00 2001 From: Zeljko Mihaljcic <7150613+zehiko@users.noreply.github.com> Date: Tue, 14 Jan 2025 19:16:36 +0100 Subject: [PATCH 33/57] Fix doc comment for SN client rust binding (#8688) Fix CI: https://github.com/rerun-io/rerun/actions/runs/12771569525 --- rerun_py/src/remote.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rerun_py/src/remote.rs b/rerun_py/src/remote.rs index b7aa30b30d1a..a19d779787b0 100644 --- a/rerun_py/src/remote.rs +++ b/rerun_py/src/remote.rs @@ -259,12 +259,12 @@ impl PyStorageNodeClient { /// Parameters /// ---------- /// id : str - /// The id of the recording to get the schema for. + /// The id of the recording to get the schema for. /// /// Returns /// ------- /// Schema - /// The schema of the recording. + /// The schema of the recording. fn get_recording_schema(&mut self, id: String) -> PyResult { self.runtime.block_on(async { let request = GetRecordingSchemaRequest { From b2b7f916a49cbdf79055c1cc9da5e2de871beee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jochen=20G=C3=B6rtler?= Date: Tue, 14 Jan 2025 19:24:26 +0100 Subject: [PATCH 34/57] Fix flaky `re_graph_view` test by removing dynamically-placed node (#8683) ### What Title. The downside of this is that we now skip the actual layout algorithm entirely, as all nodes are placed at fixed positions. I somehow need to figure out where the determinism in `fjadra` is coming from: * https://github.com/grtlr/fjadra/issues/5 --------- Co-authored-by: Clement Rey --- crates/viewer/re_view_graph/Cargo.toml | 1 + crates/viewer/re_view_graph/tests/basic.rs | 6 ++++-- .../re_view_graph/tests/snapshots/self_and_multi_edges.png | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/viewer/re_view_graph/Cargo.toml b/crates/viewer/re_view_graph/Cargo.toml index 4da414d45aef..576f8330d97c 100644 --- a/crates/viewer/re_view_graph/Cargo.toml +++ b/crates/viewer/re_view_graph/Cargo.toml @@ -43,4 +43,5 @@ nohash-hasher.workspace = true [dev-dependencies] egui_kittest.workspace = true re_chunk_store.workspace = true +re_viewer_context = { workspace = true, features = ["testing"] } re_viewport.workspace = true diff --git a/crates/viewer/re_view_graph/tests/basic.rs b/crates/viewer/re_view_graph/tests/basic.rs index c34fb9e7fc31..e5f41e850ec1 100644 --- a/crates/viewer/re_view_graph/tests/basic.rs +++ b/crates/viewer/re_view_graph/tests/basic.rs @@ -89,9 +89,11 @@ pub fn self_and_multi_edges() { components::GraphEdge(("B", "A").into()), // duplicated self-edges components::GraphEdge(("A", "A").into()), + // TODO(grtlr): investigate instabilities in the graph layout to be able + // to test dynamically placed nodes. // implicit edges - components::GraphEdge(("B", "C").into()), - components::GraphEdge(("C", "C").into()), + // components::GraphEdge(("B", "C").into()), + // components::GraphEdge(("C", "C").into()), ]; let directed = components::GraphType::Directed; diff --git a/crates/viewer/re_view_graph/tests/snapshots/self_and_multi_edges.png b/crates/viewer/re_view_graph/tests/snapshots/self_and_multi_edges.png index 717de4e62c9a..19135e629724 100644 --- a/crates/viewer/re_view_graph/tests/snapshots/self_and_multi_edges.png +++ b/crates/viewer/re_view_graph/tests/snapshots/self_and_multi_edges.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:545e27567603726522bf898e05427a462752c345d77d603762713e1735020db0 -size 24359 +oid sha256:7c9674e1320b5f097078357c41fd56d16007ad30d12a9296ee8c77c35f52b0d2 +size 22355 From 72006c7ebe77c606f1ef7a7d7c7bb68226df6242 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 14 Jan 2025 19:55:02 +0100 Subject: [PATCH 35/57] Handle empty line strips in the viewer (#8653) --- Cargo.lock | 1 + crates/utils/re_log/src/lib.rs | 3 + crates/utils/re_log/src/setup.rs | 76 +++++++++++++++---- crates/viewer/re_renderer/Cargo.toml | 2 + crates/viewer/re_renderer/src/config.rs | 69 +++++++++++++++++ crates/viewer/re_renderer/src/context_test.rs | 46 +++++++++++ crates/viewer/re_renderer/src/lib.rs | 3 + .../viewer/re_renderer/src/renderer/lines.rs | 46 ++++++++++- .../re_viewer_context/src/test_context.rs | 64 +--------------- 9 files changed, 233 insertions(+), 77 deletions(-) create mode 100644 crates/viewer/re_renderer/src/context_test.rs diff --git a/Cargo.lock b/Cargo.lock index 85eeabf7fead..82426fe6b5d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6290,6 +6290,7 @@ dependencies = [ "ordered-float", "parking_lot", "pathdiff", + "pollster 0.4.0", "profiling", "re_arrow2", "re_build_tools", diff --git a/crates/utils/re_log/src/lib.rs b/crates/utils/re_log/src/lib.rs index debe25a13802..79d705821913 100644 --- a/crates/utils/re_log/src/lib.rs +++ b/crates/utils/re_log/src/lib.rs @@ -44,6 +44,9 @@ pub use multi_logger::{add_boxed_logger, add_logger, MultiLoggerNotSetupError}; #[cfg(feature = "setup")] pub use setup::setup_logging; +#[cfg(all(feature = "setup", not(target_arch = "wasm32")))] +pub use setup::PanicOnWarnScope; + /// Re-exports of other crates. pub mod external { pub use log; diff --git a/crates/utils/re_log/src/setup.rs b/crates/utils/re_log/src/setup.rs index 59b7e44e4a14..08e46b59cf8d 100644 --- a/crates/utils/re_log/src/setup.rs +++ b/crates/utils/re_log/src/setup.rs @@ -1,5 +1,7 @@ //! Function to setup logging in binaries and web apps. +use std::sync::atomic::AtomicIsize; + /// Automatically does the right thing depending on target environment (native vs. web). /// /// Directs [`log`] calls to stderr on native. @@ -50,12 +52,10 @@ pub fn setup_logging() { stderr_logger.parse_filters(&log_filter); crate::add_boxed_logger(Box::new(stderr_logger.build())).expect("Failed to install logger"); - - if env_var_bool("RERUN_PANIC_ON_WARN") == Some(true) { - crate::add_boxed_logger(Box::new(PanicOnWarn {})) - .expect("Failed to enable RERUN_PANIC_ON_WARN"); - crate::info!("RERUN_PANIC_ON_WARN: any warning or error will cause Rerun to panic."); - } + crate::add_boxed_logger(Box::new(PanicOnWarn { + always_enabled: env_var_bool("RERUN_PANIC_ON_WARN") == Some(true), + })) + .expect("Failed to install panic-on-warn logger"); } #[cfg(target_arch = "wasm32")] @@ -75,6 +75,43 @@ pub fn setup_logging() { // ---------------------------------------------------------------------------- +thread_local! { + static PANIC_ON_WARN_SCOPE_DEPTH: AtomicIsize = const { AtomicIsize::new(0) }; +} + +/// Scope for enabling panic on warn/error log messages temporariliy on the current thread (!). +/// +/// Use this in tests to ensure that there's no errors & warnings. +/// Note that we can't enable this for all threads since threads run in parallel and may not want to set this. +#[cfg(not(target_arch = "wasm32"))] +pub struct PanicOnWarnScope { + // The panic scope should decrease the same thread-local value, so it musn't be Send or Sync. + not_send_sync: std::marker::PhantomData>, +} + +#[cfg(not(target_arch = "wasm32"))] +impl PanicOnWarnScope { + /// Enable panic on warn & error log messages for as long as this scope is alive. + #[expect(clippy::new_without_default)] + pub fn new() -> Self { + PANIC_ON_WARN_SCOPE_DEPTH.with(|enabled| { + enabled.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + }); + Self { + not_send_sync: Default::default(), + } + } +} + +#[cfg(not(target_arch = "wasm32"))] +impl Drop for PanicOnWarnScope { + fn drop(&mut self) { + PANIC_ON_WARN_SCOPE_DEPTH.with(|enabled| { + enabled.fetch_sub(1, std::sync::atomic::Ordering::Relaxed); + }); + } +} + #[cfg(not(target_arch = "wasm32"))] fn env_var_bool(name: &str) -> Option { std::env::var(name).ok() @@ -91,25 +128,34 @@ fn env_var_bool(name: &str) -> Option { } #[cfg(not(target_arch = "wasm32"))] -struct PanicOnWarn {} +struct PanicOnWarn { + always_enabled: bool, +} #[cfg(not(target_arch = "wasm32"))] impl log::Log for PanicOnWarn { fn enabled(&self, metadata: &log::Metadata<'_>) -> bool { match metadata.level() { - log::Level::Error | log::Level::Warn => true, + log::Level::Error | log::Level::Warn => { + self.always_enabled + || PANIC_ON_WARN_SCOPE_DEPTH + .with(|enabled| enabled.load(std::sync::atomic::Ordering::Relaxed) > 0) + } log::Level::Info | log::Level::Debug | log::Level::Trace => false, } } fn log(&self, record: &log::Record<'_>) { - let level = match record.level() { - log::Level::Error => "error", - log::Level::Warn => "warning", - log::Level::Info | log::Level::Debug | log::Level::Trace => return, - }; - - panic!("{level} logged with RERUN_PANIC_ON_WARN: {}", record.args()); + // `enabled` isn't called automatically by the `log!` macros, so we have to call it here. + // (it is only used by `log_enabled!`) + if self.enabled(record.metadata()) { + let level = match record.level() { + log::Level::Error => "error", + log::Level::Warn => "warning", + log::Level::Info | log::Level::Debug | log::Level::Trace => return, + }; + panic!("{level} logged with RERUN_PANIC_ON_WARN: {}", record.args()); + } } fn flush(&self) {} diff --git a/crates/viewer/re_renderer/Cargo.toml b/crates/viewer/re_renderer/Cargo.toml index da706aa443e7..7f13833c7c1b 100644 --- a/crates/viewer/re_renderer/Cargo.toml +++ b/crates/viewer/re_renderer/Cargo.toml @@ -106,6 +106,8 @@ wasm-bindgen.workspace = true [dev-dependencies] +re_log = { workspace = true, features = ["setup"] } +pollster.workspace = true unindent.workspace = true # For build.rs: diff --git a/crates/viewer/re_renderer/src/config.rs b/crates/viewer/re_renderer/src/config.rs index 93a5b24f9d4f..57ece87f6269 100644 --- a/crates/viewer/re_renderer/src/config.rs +++ b/crates/viewer/re_renderer/src/config.rs @@ -325,6 +325,9 @@ impl DeviceCaps { } } +/// Returns an instance descriptor with settings preferred by `re_renderer`. +/// +/// `re_renderer` should work fine with any instance descriptor, but those are the settings we generally assume. pub fn instance_descriptor(force_backend: Option<&str>) -> wgpu::InstanceDescriptor { let backends = if let Some(force_backend) = force_backend { if let Some(backend) = parse_graphics_backend(force_backend) { @@ -366,6 +369,72 @@ pub fn instance_descriptor(force_backend: Option<&str>) -> wgpu::InstanceDescrip } } +/// Returns an instance descriptor that is suitable for testing. +pub fn testing_instance_descriptor() -> wgpu::InstanceDescriptor { + // We don't test on GL & DX12 right now (and don't want to do so by mistake!). + // Several reasons for this: + // * our CI is setup to draw with native Mac & lavapipe + // * we generally prefer Vulkan over DX12 on Windows since it reduces the + // number of backends and wgpu's DX12 backend isn't as far along as of writing. + // * we don't want to use the GL backend here since we regard it as a fallback only + // (TODO(andreas): Ideally we'd test that as well to check it is well-behaved, + // but for now we only want to have a look at the happy path) + let backends = wgpu::Backends::VULKAN | wgpu::Backends::METAL; + + let flags = ( + wgpu::InstanceFlags::ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER | wgpu::InstanceFlags::VALIDATION + // TODO(andreas): GPU based validation layer sounds like a great idea, + // but as of writing this makes tests crash on my Windows machine! + // It looks like the crash is in the Vulkan/Nvidia driver, but further investigation is needed. + // | wgpu::InstanceFlags::GPU_BASED_VALIDATION + ) + .with_env(); // Allow overwriting flags via env vars. + + wgpu::InstanceDescriptor { + backends, + flags, + ..instance_descriptor(None) + } +} + +/// Selects an adapter for testing, preferring software rendering if available. +/// +/// Panics if no adapter was found. +#[cfg(native)] +pub fn select_testing_adapter(instance: &wgpu::Instance) -> wgpu::Adapter { + let mut adapters = instance.enumerate_adapters(wgpu::Backends::all()); + assert!(!adapters.is_empty(), "No graphics adapter found!"); + + re_log::debug!("Found the following adapters:"); + for adapter in &adapters { + re_log::debug!("* {}", crate::adapter_info_summary(&adapter.get_info())); + } + + // Adapters are already sorted by preferred backend by wgpu, but let's be explicit. + adapters.sort_by_key(|a| match a.get_info().backend { + wgpu::Backend::Metal => 0, + wgpu::Backend::Vulkan => 1, + wgpu::Backend::Dx12 => 2, + wgpu::Backend::Gl => 4, + wgpu::Backend::BrowserWebGpu => 6, + wgpu::Backend::Empty => 7, + }); + + // Prefer CPU adapters, otherwise if we can't, prefer discrete GPU over integrated GPU. + adapters.sort_by_key(|a| match a.get_info().device_type { + wgpu::DeviceType::Cpu => 0, // CPU is the best for our purposes! + wgpu::DeviceType::DiscreteGpu => 1, + wgpu::DeviceType::Other + | wgpu::DeviceType::IntegratedGpu + | wgpu::DeviceType::VirtualGpu => 2, + }); + + let adapter = adapters.remove(0); + re_log::info!("Picked adapter: {:?}", adapter.get_info()); + + adapter +} + /// Backends that are officially supported by `re_renderer`. /// /// Other backend might work as well, but lack of support isn't regarded as a bug. diff --git a/crates/viewer/re_renderer/src/context_test.rs b/crates/viewer/re_renderer/src/context_test.rs new file mode 100644 index 000000000000..3805072a66d9 --- /dev/null +++ b/crates/viewer/re_renderer/src/context_test.rs @@ -0,0 +1,46 @@ +//! Extensions for the [`RenderContext`] for testing. + +use std::sync::Arc; + +use crate::{config, RenderContext}; + +impl RenderContext { + /// Creates a new [`RenderContext`] for testing. + pub fn new_test() -> Self { + let instance = wgpu::Instance::new(config::testing_instance_descriptor()); + let adapter = config::select_testing_adapter(&instance); + let device_caps = config::DeviceCaps::from_adapter(&adapter) + .expect("Failed to determine device capabilities"); + let (device, queue) = + pollster::block_on(adapter.request_device(&device_caps.device_descriptor(), None)) + .expect("Failed to request device."); + + Self::new( + &adapter, + Arc::new(device), + Arc::new(queue), + wgpu::TextureFormat::Rgba8Unorm, + ) + .expect("Failed to create RenderContext") + } + + /// Executes a test frame. + /// + /// Note that this "executes" a frame in thus far that it doesn't necessarily draw anything, + /// depending on what the callback does. + pub fn execute_test_frame(&mut self, create_gpu_work: impl FnOnce(&mut Self) -> I) + where + I: IntoIterator, + { + self.begin_frame(); + let command_buffers = create_gpu_work(self); + self.before_submit(); + self.queue.submit(command_buffers); + + // Wait for all GPU work to finish. + self.device.poll(wgpu::Maintain::Wait); + + // Start a new frame in order to handle the previous' frame errors. + self.begin_frame(); + } +} diff --git a/crates/viewer/re_renderer/src/lib.rs b/crates/viewer/re_renderer/src/lib.rs index 72fdade72dd1..3864ff138a0c 100644 --- a/crates/viewer/re_renderer/src/lib.rs +++ b/crates/viewer/re_renderer/src/lib.rs @@ -40,6 +40,9 @@ mod transform; mod wgpu_buffer_types; mod wgpu_resources; +#[cfg(test)] +mod context_test; + #[cfg(not(load_shaders_from_disk))] #[rustfmt::skip] // it's auto-generated mod workspace_shaders; diff --git a/crates/viewer/re_renderer/src/renderer/lines.rs b/crates/viewer/re_renderer/src/renderer/lines.rs index c10fec15aa32..da554618b8ce 100644 --- a/crates/viewer/re_renderer/src/renderer/lines.rs +++ b/crates/viewer/re_renderer/src/renderer/lines.rs @@ -343,7 +343,7 @@ impl LineDrawData { let line_renderer = ctx.renderer::(); - if strips_buffer.is_empty() { + if strips_buffer.is_empty() || vertices_buffer.is_empty() { return Ok(Self { bind_group_all_lines: None, bind_group_all_lines_outline_mask: None, @@ -762,3 +762,47 @@ impl Renderer for LineRenderer { Ok(()) } } + +#[cfg(test)] +mod tests { + use crate::{view_builder::TargetConfiguration, Rgba}; + + use super::*; + + // Regression test for https://github.com/rerun-io/rerun/issues/8639 + #[test] + fn empty_strips() { + re_log::setup_logging(); + re_log::PanicOnWarnScope::new(); + + RenderContext::new_test().execute_test_frame(|ctx| { + let mut view = ViewBuilder::new(ctx, TargetConfiguration::default()); + + let empty = LineDrawableBuilder::new(ctx); + view.queue_draw(empty.into_draw_data().unwrap()); + + // This is the case that triggered + // https://github.com/rerun-io/rerun/issues/8639 + // The others are here for completeness. + let mut empty_batch = LineDrawableBuilder::new(ctx); + empty_batch + .batch("empty batch") + .add_strip(std::iter::empty()); + view.queue_draw(empty_batch.into_draw_data().unwrap()); + + let mut empty_batch_between_non_empty = LineDrawableBuilder::new(ctx); + empty_batch_between_non_empty + .batch("non-empty batch") + .add_strip([glam::Vec3::ZERO, glam::Vec3::ZERO].into_iter()); + empty_batch_between_non_empty + .batch("empty batch") + .add_strip(std::iter::empty()); + empty_batch_between_non_empty + .batch("non-empty batch") + .add_strip([glam::Vec3::ZERO, glam::Vec3::ZERO].into_iter()); + view.queue_draw(empty_batch_between_non_empty.into_draw_data().unwrap()); + + [view.draw(ctx, Rgba::BLACK).unwrap()] + }); + } +} diff --git a/crates/viewer/re_viewer_context/src/test_context.rs b/crates/viewer/re_viewer_context/src/test_context.rs index baf122c5c77b..b19223205dc9 100644 --- a/crates/viewer/re_viewer_context/src/test_context.rs +++ b/crates/viewer/re_viewer_context/src/test_context.rs @@ -162,67 +162,8 @@ static SHARED_WGPU_RENDERER_SETUP: Lazy = Lazy::new(init_shared_renderer_setup); fn init_shared_renderer_setup() -> SharedWgpuResources { - // TODO(andreas, emilk/egui#5506): Use centralized wgpu setup logic that… - // * lives mostly in re_renderer and is shared with viewer & renderer examples - // * can be told to prefer software rendering - // * can be told to match a specific device tier - - // We rely a lot on logging in the viewer to identify issues. - // Make sure logging is set up if it hasn't been done yet. - //let _ = env_logger::builder().is_test(true).try_init(); - let _ = env_logger::builder() - .filter_level(re_log::external::log::LevelFilter::Trace) - .is_test(false) - .try_init(); - - // We don't test on GL & DX12 right now (and don't want to do so by mistake!). - // Several reasons for this: - // * our CI is setup to draw with native Mac & lavapipe - // * we generally prefer Vulkan over DX12 on Windows since it reduces the - // number of backends and wgpu's DX12 backend isn't as far along as of writing. - // * we don't want to use the GL backend here since we regard it as a fallback only - // (TODO(andreas): Ideally we'd test that as well to check it is well-behaved, - // but for now we only want to have a look at the happy path) - let backends = wgpu::Backends::VULKAN | wgpu::Backends::METAL; - let flags = (wgpu::InstanceFlags::ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER - | wgpu::InstanceFlags::VALIDATION - | wgpu::InstanceFlags::GPU_BASED_VALIDATION) - .with_env(); // Allow overwriting flags via env vars. - let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { - backends, - flags, - ..Default::default() - }); - - let mut adapters = instance.enumerate_adapters(backends); - assert!(!adapters.is_empty(), "No graphics adapter found!"); - re_log::info!("Found the following adapters:"); - for adapter in &adapters { - re_log::info!("* {}", egui_wgpu::adapter_info_summary(&adapter.get_info())); - } - - // Adapters are already sorted by preferred backend by wgpu, but let's be explicit. - adapters.sort_by_key(|a| match a.get_info().backend { - wgpu::Backend::Metal => 0, - wgpu::Backend::Vulkan => 1, - wgpu::Backend::Dx12 => 2, - wgpu::Backend::Gl => 4, - wgpu::Backend::BrowserWebGpu => 6, - wgpu::Backend::Empty => 7, - }); - - // Prefer CPU adapters, otherwise if we can't, prefer discrete GPU over integrated GPU. - adapters.sort_by_key(|a| match a.get_info().device_type { - wgpu::DeviceType::Cpu => 0, // CPU is the best for our purposes! - wgpu::DeviceType::DiscreteGpu => 1, - wgpu::DeviceType::Other - | wgpu::DeviceType::IntegratedGpu - | wgpu::DeviceType::VirtualGpu => 2, - }); - - let adapter = adapters.remove(0); - re_log::info!("Picked adapter: {:?}", adapter.get_info()); - + let instance = wgpu::Instance::new(re_renderer::config::testing_instance_descriptor()); + let adapter = re_renderer::config::select_testing_adapter(&instance); let device_caps = re_renderer::config::DeviceCaps::from_adapter(&adapter) .expect("Failed to determine device capabilities"); let (device, queue) = @@ -271,6 +212,7 @@ impl TestContext { /// IMPORTANT: call [`Self::handle_system_commands`] after calling this function if your test /// relies on system commands. pub fn run(&self, egui_ctx: &egui::Context, func: impl FnOnce(&ViewerContext<'_>)) { + re_log::PanicOnWarnScope::new(); // TODO(andreas): There should be a way to opt-out of this. re_ui::apply_style_and_install_loaders(egui_ctx); let store_context = StoreContext { From af428282dce556097fe2117c219698bdbcedb1e3 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 15 Jan 2025 06:20:35 +0100 Subject: [PATCH 36/57] Update `re_arrow2` (#8694) Fix failing CI --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 82426fe6b5d7..6f8bc2ab28ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5584,7 +5584,7 @@ dependencies = [ [[package]] name = "re_arrow2" version = "0.18.1" -source = "git+https://github.com/rerun-io/re_arrow2.git?branch=main#e8576708a1b41b493980ecb995e808aefcfa1fbc" +source = "git+https://github.com/rerun-io/re_arrow2.git?branch=main#61ac48418df229584155c5f669477bedf76d4505" dependencies = [ "ahash", "arrow-array", diff --git a/Cargo.toml b/Cargo.toml index 7574f393ff2d..55544dbf3bd3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -153,7 +153,7 @@ anyhow = { version = "1.0", default-features = false } argh = "0.1.12" array-init = "2.1" arrow = { version = "53.1", default-features = false } -arrow2 = { package = "re_arrow2", version = "0.18" } +arrow2 = { package = "re_arrow2", version = "0.18", features = ["arrow"] } async-executor = "1.0" backtrace = "0.3" bincode = "1.3" From efee5ad42a78344e4d32ad13533d051263c6fb6a Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 15 Jan 2025 09:12:24 +0100 Subject: [PATCH 37/57] Create `re_arrow_util` (#8689) ### Related * Part of https://github.com/rerun-io/rerun/issues/3741 ### Details Adds crate `re_arrow_util`. Adds two traits for downcasting `arrow` and `arrow2` arrays in such a way that we cannot accidentally cast one into another. This will be very important for the arrow migration. It also makes the code shorter. --- ARCHITECTURE.md | 1 + Cargo.lock | 23 ++++++ Cargo.toml | 3 +- clippy.toml | 18 ++--- crates/store/re_chunk/Cargo.toml | 1 + crates/store/re_chunk/src/batcher.rs | 3 +- crates/store/re_chunk/src/builder.rs | 3 +- crates/store/re_chunk/src/chunk.rs | 34 ++++----- .../re_chunk/src/concat_record_batches.rs | 40 ++++++++++ crates/store/re_chunk/src/iter.rs | 28 +++---- crates/store/re_chunk/src/lib.rs | 3 +- crates/store/re_chunk/src/merge.rs | 16 ++-- crates/store/re_chunk/src/migration.rs | 8 +- crates/store/re_chunk/src/shuffle.rs | 2 +- crates/store/re_chunk/src/slice.rs | 8 +- crates/store/re_chunk/src/transport.rs | 21 +++--- crates/store/re_chunk/tests/memory_test.rs | 32 +++----- crates/store/re_chunk_store/Cargo.toml | 1 + crates/store/re_chunk_store/src/writes.rs | 2 +- crates/store/re_dataframe/Cargo.toml | 1 + crates/store/re_dataframe/src/lib.rs | 4 +- crates/store/re_dataframe/src/query.rs | 9 ++- crates/store/re_format_arrow/Cargo.toml | 6 +- crates/store/re_format_arrow/src/lib.rs | 7 +- crates/store/re_grpc_client/Cargo.toml | 1 + crates/store/re_grpc_client/src/lib.rs | 11 ++- crates/store/re_log_types/Cargo.toml | 1 + .../re_log_types/src/example_components.rs | 19 ++--- crates/store/re_query/Cargo.toml | 1 + crates/store/re_query/examples/latest_at.rs | 4 +- crates/store/re_types_core/Cargo.toml | 1 + crates/store/re_types_core/src/tuid.rs | 6 +- crates/top/rerun_c/Cargo.toml | 1 + crates/top/rerun_c/src/lib.rs | 11 +-- crates/utils/re_arrow_util/Cargo.toml | 31 ++++++++ crates/utils/re_arrow_util/README.md | 10 +++ .../re_arrow_util}/src/arrow2_util.rs | 74 ++++++++----------- .../re_arrow_util}/src/arrow_util.rs | 30 +++++++- crates/utils/re_arrow_util/src/lib.rs | 7 ++ crates/viewer/re_ui/Cargo.toml | 5 +- crates/viewer/re_ui/src/arrow_ui.rs | 6 +- crates/viewer/re_view_dataframe/Cargo.toml | 1 + .../src/display_record_batch.rs | 10 +-- rerun_py/Cargo.toml | 1 + rerun_py/src/arrow.rs | 3 +- rerun_py/src/dataframe.rs | 7 +- rerun_py/src/remote.rs | 4 +- rerun_py/src/video.rs | 7 +- 48 files changed, 320 insertions(+), 206 deletions(-) create mode 100644 crates/store/re_chunk/src/concat_record_batches.rs create mode 100644 crates/utils/re_arrow_util/Cargo.toml create mode 100644 crates/utils/re_arrow_util/README.md rename crates/{store/re_chunk => utils/re_arrow_util}/src/arrow2_util.rs (91%) rename crates/{store/re_chunk => utils/re_arrow_util}/src/arrow_util.rs (91%) create mode 100644 crates/utils/re_arrow_util/src/lib.rs diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index ccfe5dcc570d..a4976c373956 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -210,6 +210,7 @@ Update instructions: | Crate | Description | |--------------------|--------------------------------------------------------------------------------------| | re_analytics | Rerun's analytics SDK | +| re_arrow_util | Helpers for working with arrow | | re_byte_size | Calculate the heap-allocated size of values at runtime | | re_capabilities | Capability tokens | | re_case | Case conversions, the way Rerun likes them | diff --git a/Cargo.lock b/Cargo.lock index 6f8bc2ab28ca..950cec6514a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5610,6 +5610,17 @@ dependencies = [ "simdutf8", ] +[[package]] +name = "re_arrow_util" +version = "0.22.0-alpha.1+dev" +dependencies = [ + "arrow", + "itertools 0.13.0", + "re_arrow2", + "re_log", + "re_tracing", +] + [[package]] name = "re_blueprint_tree" version = "0.22.0-alpha.1+dev" @@ -5692,6 +5703,7 @@ dependencies = [ "nohash-hasher", "rand", "re_arrow2", + "re_arrow_util", "re_byte_size", "re_error", "re_format", @@ -5725,6 +5737,7 @@ dependencies = [ "parking_lot", "rand", "re_arrow2", + "re_arrow_util", "re_byte_size", "re_chunk", "re_format", @@ -5904,6 +5917,7 @@ dependencies = [ "nohash-hasher", "rayon", "re_arrow2", + "re_arrow_util", "re_chunk", "re_chunk_store", "re_log", @@ -6001,6 +6015,7 @@ dependencies = [ "arrow", "comfy-table", "itertools 0.13.0", + "re_arrow_util", "re_tuid", "re_types_core", ] @@ -6010,6 +6025,7 @@ name = "re_grpc_client" version = "0.22.0-alpha.1+dev" dependencies = [ "arrow", + "re_arrow_util", "re_chunk", "re_error", "re_log", @@ -6123,6 +6139,7 @@ dependencies = [ "num-derive", "num-traits", "re_arrow2", + "re_arrow_util", "re_build_info", "re_byte_size", "re_format", @@ -6226,6 +6243,7 @@ dependencies = [ "paste", "rand", "re_arrow2", + "re_arrow_util", "re_byte_size", "re_chunk", "re_chunk_store", @@ -6585,6 +6603,7 @@ dependencies = [ "nohash-hasher", "once_cell", "re_arrow2", + "re_arrow_util", "re_byte_size", "re_case", "re_error", @@ -6613,6 +6632,7 @@ dependencies = [ "once_cell", "parking_lot", "rand", + "re_arrow_util", "re_entity_db", "re_format", "re_log", @@ -6707,6 +6727,7 @@ dependencies = [ "egui", "egui_table", "itertools 0.13.0", + "re_arrow_util", "re_chunk_store", "re_dataframe", "re_error", @@ -7371,6 +7392,7 @@ dependencies = [ "once_cell", "parking_lot", "re_arrow2", + "re_arrow_util", "re_log", "re_sdk", "re_video", @@ -7394,6 +7416,7 @@ dependencies = [ "pyo3-build-config", "rand", "re_arrow2", + "re_arrow_util", "re_build_info", "re_build_tools", "re_chunk", diff --git a/Cargo.toml b/Cargo.toml index 55544dbf3bd3..ae3606935004 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,6 +72,8 @@ rerun-cli = { path = "crates/top/rerun-cli", version = "=0.22.0-alpha.1", defaul # crates/utils: re_analytics = { path = "crates/utils/re_analytics", version = "=0.22.0-alpha.1", default-features = false } +re_arrow_util = { path = "crates/utils/re_arrow_util", version = "=0.22.0-alpha.1", default-features = false } +re_byte_size = { path = "crates/utils/re_byte_size", version = "=0.22.0-alpha.1", default-features = false } re_capabilities = { path = "crates/utils/re_capabilities", version = "=0.22.0-alpha.1", default-features = false } re_case = { path = "crates/utils/re_case", version = "=0.22.0-alpha.1", default-features = false } re_crash_handler = { path = "crates/utils/re_crash_handler", version = "=0.22.0-alpha.1", default-features = false } @@ -80,7 +82,6 @@ re_format = { path = "crates/utils/re_format", version = "=0.22.0-alpha.1", defa re_int_histogram = { path = "crates/utils/re_int_histogram", version = "=0.22.0-alpha.1", default-features = false } re_log = { path = "crates/utils/re_log", version = "=0.22.0-alpha.1", default-features = false } re_memory = { path = "crates/utils/re_memory", version = "=0.22.0-alpha.1", default-features = false } -re_byte_size = { path = "crates/utils/re_byte_size", version = "=0.22.0-alpha.1", default-features = false } re_smart_channel = { path = "crates/utils/re_smart_channel", version = "=0.22.0-alpha.1", default-features = false } re_string_interner = { path = "crates/utils/re_string_interner", version = "=0.22.0-alpha.1", default-features = false } re_tracing = { path = "crates/utils/re_tracing", version = "=0.22.0-alpha.1", default-features = false } diff --git a/clippy.toml b/clippy.toml index 01e482ba6bdd..7a3595366c79 100644 --- a/clippy.toml +++ b/clippy.toml @@ -50,19 +50,19 @@ disallowed-methods = [ { path = "std::panic::catch_unwind", reason = "We compile with `panic = 'abort'`" }, { path = "std::thread::spawn", reason = "Use `std::thread::Builder` and name the thread" }, - { path = "arrow::compute::concat", reason = "Use `re_chunk::arrow_util::concat_arrays` instead, which has better memory management" }, - { path = "arrow::compute::filter", reason = "Use `re_chunk::arrow_util::filter_array` instead" }, - { path = "arrow::compute::take", reason = "Use `re_chunk::arrow_util::take_array` instead" }, + { path = "arrow::compute::concat", reason = "Use `re_arrow_util::arrow_util::concat_arrays` instead, which has better memory management" }, + { path = "arrow::compute::filter", reason = "Use `re_arrow_util::arrow_util::filter_array` instead" }, + { path = "arrow::compute::take", reason = "Use `re_arrow_util::arrow_util::take_array` instead" }, { path = "arrow::datatypes::Schema::new", reason = "Use `arrow::datatypes::Schema::new_with_metadata` instead. There is usually some metadata you want to preserve." }, # Specify both `arrow2` and `re_arrow2` -- clippy gets lost in all the package renaming happening. - { path = "arrow2::compute::concatenate::concatenate", reason = "Use `re_chunk::arrow2_util::concat_arrays` instead, which has proper early outs" }, - { path = "arrow2::compute::filter::filter", reason = "Use `re_chunk::arrow2_util::filter_array` instead, which has proper early outs" }, - { path = "arrow2::compute::take::take", reason = "Use `re_chunk::arrow2_util::take_array` instead, which has proper early outs" }, - { path = "re_arrow2::compute::concatenate::concatenate", reason = "Use `re_chunk::arrow2_util::concat_arrays` instead, which has proper early outs" }, - { path = "re_arrow2::compute::filter::filter", reason = "Use `re_chunk::arrow2_util::filter_array` instead, which has proper early outs" }, - { path = "re_arrow2::compute::take::take", reason = "Use `re_chunk::arrow2_util::take_array` instead, which has proper early outs" }, + { path = "arrow2::compute::concatenate::concatenate", reason = "Use `re_arrow_util::arrow2_util::concat_arrays` instead, which has proper early outs" }, + { path = "arrow2::compute::filter::filter", reason = "Use `re_arrow_util::arrow2_util::filter_array` instead, which has proper early outs" }, + { path = "arrow2::compute::take::take", reason = "Use `re_arrow_util::arrow2_util::take_array` instead, which has proper early outs" }, + { path = "re_arrow2::compute::concatenate::concatenate", reason = "Use `re_arrow_util::arrow2_util::concat_arrays` instead, which has proper early outs" }, + { path = "re_arrow2::compute::filter::filter", reason = "Use `re_arrow_util::arrow2_util::filter_array` instead, which has proper early outs" }, + { path = "re_arrow2::compute::take::take", reason = "Use `re_arrow_util::arrow2_util::take_array` instead, which has proper early outs" }, # There are many things that aren't allowed on wasm, # but we cannot disable them all here (because of e.g. https://github.com/rust-lang/rust-clippy/issues/10406) diff --git a/crates/store/re_chunk/Cargo.toml b/crates/store/re_chunk/Cargo.toml index 38a9e5b8c963..d3e285ca2a53 100644 --- a/crates/store/re_chunk/Cargo.toml +++ b/crates/store/re_chunk/Cargo.toml @@ -37,6 +37,7 @@ arrow = ["arrow2/arrow"] [dependencies] # Rerun +re_arrow_util.workspace = true re_byte_size.workspace = true re_error.workspace = true re_format.workspace = true diff --git a/crates/store/re_chunk/src/batcher.rs b/crates/store/re_chunk/src/batcher.rs index b1f4a61d0afe..db897b8267f5 100644 --- a/crates/store/re_chunk/src/batcher.rs +++ b/crates/store/re_chunk/src/batcher.rs @@ -9,11 +9,12 @@ use arrow::buffer::ScalarBuffer as ArrowScalarBuffer; use crossbeam::channel::{Receiver, Sender}; use nohash_hasher::IntMap; +use re_arrow_util::arrow_util; use re_byte_size::SizeBytes as _; use re_log_types::{EntityPath, ResolvedTimeRange, TimeInt, TimePoint, Timeline}; use re_types_core::ComponentDescriptor; -use crate::{arrow_util, chunk::ChunkComponents, Chunk, ChunkId, ChunkResult, RowId, TimeColumn}; +use crate::{chunk::ChunkComponents, Chunk, ChunkId, ChunkResult, RowId, TimeColumn}; // --- diff --git a/crates/store/re_chunk/src/builder.rs b/crates/store/re_chunk/src/builder.rs index e08e20132fab..fe8f40228d78 100644 --- a/crates/store/re_chunk/src/builder.rs +++ b/crates/store/re_chunk/src/builder.rs @@ -2,10 +2,11 @@ use arrow::{array::ArrayRef, datatypes::DataType as ArrowDatatype}; use itertools::Itertools; use nohash_hasher::IntMap; +use re_arrow_util::arrow_util; use re_log_types::{EntityPath, TimeInt, TimePoint, Timeline}; use re_types_core::{AsComponents, ComponentBatch, ComponentDescriptor, SerializedComponentBatch}; -use crate::{arrow_util, chunk::ChunkComponents, Chunk, ChunkId, ChunkResult, RowId, TimeColumn}; +use crate::{chunk::ChunkComponents, Chunk, ChunkId, ChunkResult, RowId, TimeColumn}; // --- diff --git a/crates/store/re_chunk/src/chunk.rs b/crates/store/re_chunk/src/chunk.rs index c47f0c4663a5..72827a1b81e5 100644 --- a/crates/store/re_chunk/src/chunk.rs +++ b/crates/store/re_chunk/src/chunk.rs @@ -15,6 +15,7 @@ use arrow2::{ use itertools::{izip, Itertools}; use nohash_hasher::IntMap; +use re_arrow_util::ArrowArrayDowncastRef as _; use re_byte_size::SizeBytes as _; use re_log_types::{EntityPath, ResolvedTimeRange, Time, TimeInt, TimePoint, Timeline}; use re_types_core::{ @@ -445,8 +446,7 @@ impl Chunk { let row_ids = ::to_arrow(&row_ids) // Unwrap: native RowIds cannot fail to serialize. .unwrap() - .as_any() - .downcast_ref::() + .downcast_array_ref::() // Unwrap: RowId schema is known in advance to be a struct array -- always. .unwrap() .clone(); @@ -501,8 +501,7 @@ impl Chunk { let row_ids = ::to_arrow(&row_ids) // Unwrap: native RowIds cannot fail to serialize. .unwrap() - .as_any() - .downcast_ref::() + .downcast_array_ref::() // Unwrap: RowId schema is known in advance to be a struct array -- always. .unwrap() .clone(); @@ -876,8 +875,7 @@ impl Chunk { .map_err(|err| ChunkError::Malformed { reason: format!("RowIds failed to serialize: {err}"), })? - .as_any() - .downcast_ref::() + .downcast_array_ref::() // NOTE: impossible, but better safe than sorry. .ok_or_else(|| ChunkError::Malformed { reason: "RowIds failed to downcast".to_owned(), @@ -1131,21 +1129,18 @@ impl TimeColumn { } // Sequence timelines are i64, but time columns are nanoseconds (also as i64). - if let Some(times) = array.as_any().downcast_ref::() { + if let Some(times) = array.downcast_array_ref::() { Ok(times.values().clone()) - } else if let Some(times) = array - .as_any() - .downcast_ref::() + } else if let Some(times) = + array.downcast_array_ref::() { Ok(times.values().clone()) - } else if let Some(times) = array - .as_any() - .downcast_ref::() + } else if let Some(times) = + array.downcast_array_ref::() { Ok(times.values().clone()) - } else if let Some(times) = array - .as_any() - .downcast_ref::() + } else if let Some(times) = + array.downcast_array_ref::() { Ok(times.values().clone()) } else { @@ -1224,13 +1219,10 @@ impl Chunk { }; #[allow(clippy::unwrap_used)] - let times = times.as_any().downcast_ref::().unwrap(); // sanity checked + let times = times.downcast_array_ref::().unwrap(); // sanity checked #[allow(clippy::unwrap_used)] - let counters = counters - .as_any() - .downcast_ref::() - .unwrap(); // sanity checked + let counters = counters.downcast_array_ref::().unwrap(); // sanity checked (times, counters) } diff --git a/crates/store/re_chunk/src/concat_record_batches.rs b/crates/store/re_chunk/src/concat_record_batches.rs new file mode 100644 index 000000000000..beae93c6a655 --- /dev/null +++ b/crates/store/re_chunk/src/concat_record_batches.rs @@ -0,0 +1,40 @@ +use crate::TransportChunk; + +use arrow::datatypes::Schema as ArrowSchema; +use arrow2::chunk::Chunk as Arrow2Chunk; + +/// Concatenate multiple [`TransportChunk`]s into one. +/// +/// This is a temporary method that we use while waiting to migrate towards `arrow-rs`. +/// * `arrow2` doesn't have a `RecordBatch` type, therefore we emulate that using our `TransportChunk`s. +/// * `arrow-rs` does have one, and it natively supports concatenation. +pub fn concatenate_record_batches( + schema: impl Into, + batches: &[TransportChunk], +) -> anyhow::Result { + let schema: ArrowSchema = schema.into(); + anyhow::ensure!( + batches + .iter() + .all(|batch| batch.schema_ref().as_ref() == &schema), + "concatenate_record_batches: all batches must have the same schema" + ); + + let mut output_columns = Vec::new(); + + if !batches.is_empty() { + for (i, _field) in schema.fields.iter().enumerate() { + let arrays: Option> = batches.iter().map(|batch| batch.column(i)).collect(); + let arrays = arrays.ok_or_else(|| { + anyhow::anyhow!("concatenate_record_batches: all batches must have the same schema") + })?; + let array = re_arrow_util::arrow2_util::concat_arrays(&arrays)?; + output_columns.push(array); + } + } + + Ok(TransportChunk::new( + schema, + Arrow2Chunk::new(output_columns), + )) +} diff --git a/crates/store/re_chunk/src/iter.rs b/crates/store/re_chunk/src/iter.rs index f86d28919172..46ee88a42b27 100644 --- a/crates/store/re_chunk/src/iter.rs +++ b/crates/store/re_chunk/src/iter.rs @@ -12,6 +12,7 @@ use arrow2::{ }; use itertools::{izip, Itertools}; +use re_arrow_util::Arrow2ArrayDowncastRef as _; use re_log_types::{TimeInt, TimePoint, Timeline}; use re_types_core::{ArrowBuffer, ArrowString, Component, ComponentName}; @@ -250,8 +251,7 @@ impl Chunk { let Some(struct_array) = list_array .values() - .as_any() - .downcast_ref::() + .downcast_array2_ref::() else { if cfg!(debug_assertions) { panic!("downcast failed for {component_name}, data discarded"); @@ -317,7 +317,7 @@ fn slice_as_native<'a, T: arrow2::types::NativeType + arrow::datatypes::ArrowNat array: &'a dyn Arrow2Array, component_offsets: impl Iterator + 'a, ) -> impl Iterator + 'a { - let Some(values) = array.as_any().downcast_ref::>() else { + let Some(values) = array.downcast_array2_ref::>() else { if cfg!(debug_assertions) { panic!("downcast failed for {component_name}, data discarded"); } else { @@ -373,7 +373,7 @@ fn slice_as_array_native< where [T; N]: bytemuck::Pod, { - let Some(fixed_size_list_array) = array.as_any().downcast_ref::() + let Some(fixed_size_list_array) = array.downcast_array2_ref::() else { if cfg!(debug_assertions) { panic!("downcast failed for {component_name}, data discarded"); @@ -385,8 +385,7 @@ where let Some(values) = fixed_size_list_array .values() - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() else { if cfg!(debug_assertions) { panic!("downcast failed for {component_name}, data discarded"); @@ -445,7 +444,7 @@ fn slice_as_buffer_native<'a, T: arrow2::types::NativeType + arrow::datatypes::A array: &'a dyn Arrow2Array, component_offsets: impl Iterator + 'a, ) -> impl Iterator>> + 'a { - let Some(inner_list_array) = array.as_any().downcast_ref::>() else { + let Some(inner_list_array) = array.downcast_array2_ref::>() else { if cfg!(debug_assertions) { panic!("downcast failed for {component_name}, data discarded"); } else { @@ -456,8 +455,7 @@ fn slice_as_buffer_native<'a, T: arrow2::types::NativeType + arrow::datatypes::A let Some(values) = inner_list_array .values() - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() else { if cfg!(debug_assertions) { panic!("downcast failed for {component_name}, data discarded"); @@ -524,7 +522,7 @@ fn slice_as_array_list_native< where [T; N]: bytemuck::Pod, { - let Some(inner_list_array) = array.as_any().downcast_ref::>() else { + let Some(inner_list_array) = array.downcast_array2_ref::>() else { if cfg!(debug_assertions) { panic!("downcast failed for {component_name}, data discarded"); } else { @@ -538,8 +536,7 @@ where let Some(fixed_size_list_array) = inner_list_array .values() - .as_any() - .downcast_ref::() + .downcast_array2_ref::() else { if cfg!(debug_assertions) { panic!("downcast failed for {component_name}, data discarded"); @@ -551,8 +548,7 @@ where let Some(values) = fixed_size_list_array .values() - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() else { if cfg!(debug_assertions) { panic!("downcast failed for {component_name}, data discarded"); @@ -618,7 +614,7 @@ impl ChunkComponentSlicer for String { array: &'a dyn Arrow2Array, component_offsets: impl Iterator + 'a, ) -> impl Iterator> + 'a { - let Some(utf8_array) = array.as_any().downcast_ref::>() else { + let Some(utf8_array) = array.downcast_array2_ref::>() else { if cfg!(debug_assertions) { panic!("downcast failed for {component_name}, data discarded"); } else { @@ -650,7 +646,7 @@ impl ChunkComponentSlicer for bool { array: &'a dyn Arrow2Array, component_offsets: impl Iterator + 'a, ) -> impl Iterator> + 'a { - let Some(values) = array.as_any().downcast_ref::() else { + let Some(values) = array.downcast_array2_ref::() else { if cfg!(debug_assertions) { panic!("downcast failed for {component_name}, data discarded"); } else { diff --git a/crates/store/re_chunk/src/lib.rs b/crates/store/re_chunk/src/lib.rs index b4edc54d1ce6..30ff3c5820da 100644 --- a/crates/store/re_chunk/src/lib.rs +++ b/crates/store/re_chunk/src/lib.rs @@ -4,10 +4,9 @@ #![doc = document_features::document_features!()] //! -pub mod arrow2_util; -pub mod arrow_util; mod builder; mod chunk; +pub mod concat_record_batches; mod helpers; mod id; mod iter; diff --git a/crates/store/re_chunk/src/merge.rs b/crates/store/re_chunk/src/merge.rs index af80cfef1343..16d4e1ad5bb8 100644 --- a/crates/store/re_chunk/src/merge.rs +++ b/crates/store/re_chunk/src/merge.rs @@ -4,11 +4,12 @@ use arrow2::array::{Array as Arrow2Array, ListArray as Arrow2ListArray}; use itertools::{izip, Itertools}; use nohash_hasher::IntMap; -use crate::{ - arrow2_util, arrow_util, chunk::ChunkComponents, Chunk, ChunkError, ChunkId, ChunkResult, - TimeColumn, +use re_arrow_util::{ + arrow2_util, arrow_util, Arrow2ArrayDowncastRef as _, ArrowArrayDowncastRef as _, }; +use crate::{chunk::ChunkComponents, Chunk, ChunkError, ChunkId, ChunkResult, TimeColumn}; + // --- impl Chunk { @@ -52,8 +53,7 @@ impl Chunk { #[allow(clippy::unwrap_used)] // concatenating 2 RowId arrays must yield another RowId array row_ids - .as_any() - .downcast_ref::() + .downcast_array_ref::() .unwrap() .clone() }; @@ -109,8 +109,7 @@ impl Chunk { let list_array = arrow2_util::concat_arrays(&[lhs_list_array, rhs_list_array]).ok()?; let list_array = list_array - .as_any() - .downcast_ref::>()? + .downcast_array2_ref::>()? .clone(); Some((component_desc.clone(), list_array)) @@ -151,8 +150,7 @@ impl Chunk { let list_array = arrow2_util::concat_arrays(&[lhs_list_array, rhs_list_array]).ok()?; let list_array = list_array - .as_any() - .downcast_ref::>()? + .downcast_array2_ref::>()? .clone(); Some((component_desc.clone(), list_array)) diff --git a/crates/store/re_chunk/src/migration.rs b/crates/store/re_chunk/src/migration.rs index fe50b9a53e20..65866002f858 100644 --- a/crates/store/re_chunk/src/migration.rs +++ b/crates/store/re_chunk/src/migration.rs @@ -1,8 +1,9 @@ use arrow2::array::{Array, Utf8Array}; - use itertools::Itertools; use nohash_hasher::IntMap; +use re_arrow_util::{arrow2_util, Arrow2ArrayDowncastRef as _}; + use crate::Chunk; impl Chunk { @@ -51,7 +52,7 @@ impl Chunk { .iter() .map(|utf8_array| { utf8_array.map(|array| { - let Some(array) = array.as_any().downcast_ref::>() + let Some(array) = array.downcast_array2_ref::>() else { // Unreachable, just avoiding unwraps. return array; @@ -78,8 +79,7 @@ impl Chunk { .map(|a| a.as_deref() as Option<&dyn Array>) .collect_vec(); - if let Some(list_array_patched) = - crate::arrow2_util::arrays_to_list_array_opt(&arrays) + if let Some(list_array_patched) = arrow2_util::arrays_to_list_array_opt(&arrays) { *list_array = list_array_patched; } diff --git a/crates/store/re_chunk/src/shuffle.rs b/crates/store/re_chunk/src/shuffle.rs index 4b15f425def6..ef2ccb586a17 100644 --- a/crates/store/re_chunk/src/shuffle.rs +++ b/crates/store/re_chunk/src/shuffle.rs @@ -279,7 +279,7 @@ impl Chunk { ArrowOffsets::try_from_lengths(sorted_arrays.iter().map(|array| array.len())) .unwrap(); #[allow(clippy::unwrap_used)] // these are slices of the same outer array - let values = crate::arrow2_util::concat_arrays(&sorted_arrays).unwrap(); + let values = re_arrow_util::arrow2_util::concat_arrays(&sorted_arrays).unwrap(); let validity = original .validity() .map(|validity| swaps.iter().map(|&from| validity.get_bit(from)).collect()); diff --git a/crates/store/re_chunk/src/slice.rs b/crates/store/re_chunk/src/slice.rs index 782f97cacb0b..dc233225bf34 100644 --- a/crates/store/re_chunk/src/slice.rs +++ b/crates/store/re_chunk/src/slice.rs @@ -5,10 +5,13 @@ use arrow2::array::{ use itertools::Itertools; use nohash_hasher::IntSet; +use re_arrow_util::arrow2_util; +use re_arrow_util::arrow_util; +use re_arrow_util::Arrow2ArrayDowncastRef as _; use re_log_types::Timeline; use re_types_core::{ComponentDescriptor, ComponentName}; -use crate::{arrow2_util, arrow_util, Chunk, RowId, TimeColumn}; +use crate::{Chunk, RowId, TimeColumn}; // --- @@ -386,8 +389,7 @@ impl Chunk { #[allow(clippy::unwrap_used)] filtered .with_validity(None) - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() // Unwrap: cannot possibly fail -- going from a ListArray back to a ListArray. .unwrap() .clone() diff --git a/crates/store/re_chunk/src/transport.rs b/crates/store/re_chunk/src/transport.rs index 3fe57fad8d09..5f0a9c17e162 100644 --- a/crates/store/re_chunk/src/transport.rs +++ b/crates/store/re_chunk/src/transport.rs @@ -2,8 +2,7 @@ use std::sync::Arc; use arrow::{ array::{ - Array as ArrowArray, ArrayRef as ArrowArrayRef, RecordBatch as ArrowRecordBatch, - StructArray as ArrowStructArray, + ArrayRef as ArrowArrayRef, RecordBatch as ArrowRecordBatch, StructArray as ArrowStructArray, }, datatypes::{Field as ArrowField, Schema as ArrowSchema, SchemaRef as ArrowSchemaRef}, }; @@ -16,14 +15,14 @@ use itertools::Itertools; use nohash_hasher::IntMap; use tap::Tap as _; +use re_arrow_util::{ + arrow_util::into_arrow_ref, Arrow2ArrayDowncastRef as _, ArrowArrayDowncastRef as _, +}; use re_byte_size::SizeBytes as _; use re_log_types::{EntityPath, Timeline}; use re_types_core::{Component as _, ComponentDescriptor, Loggable as _}; -use crate::{ - arrow_util::into_arrow_ref, chunk::ChunkComponents, Chunk, ChunkError, ChunkId, ChunkResult, - RowId, TimeColumn, -}; +use crate::{chunk::ChunkComponents, Chunk, ChunkError, ChunkId, ChunkResult, RowId, TimeColumn}; pub type ArrowMetadata = std::collections::HashMap; @@ -650,8 +649,7 @@ impl Chunk { }; ArrowArrayRef::from(row_ids.clone()) - .as_any() - .downcast_ref::() + .downcast_array_ref::() .ok_or_else(|| ChunkError::Malformed { reason: format!( "RowId data has the wrong datatype: expected {:?} but got {:?} instead", @@ -716,8 +714,7 @@ impl Chunk { for (field, column) in transport.components() { let column = column - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() .ok_or_else(|| ChunkError::Malformed { reason: format!( "The outer array in a chunked component batch must be a sparse list, got {:?}", @@ -791,13 +788,13 @@ impl Chunk { #[cfg(test)] mod tests { use nohash_hasher::IntMap; + + use re_arrow_util::arrow2_util; use re_log_types::{ example_components::{MyColor, MyPoint}, Timeline, }; - use crate::arrow2_util; - use super::*; #[test] diff --git a/crates/store/re_chunk/tests/memory_test.rs b/crates/store/re_chunk/tests/memory_test.rs index 84ae71fd25a3..5352508cf310 100644 --- a/crates/store/re_chunk/tests/memory_test.rs +++ b/crates/store/re_chunk/tests/memory_test.rs @@ -62,7 +62,7 @@ use arrow2::{ offset::Offsets as Arrow2Offsets, }; use itertools::Itertools; -use re_chunk::arrow2_util; +use re_arrow_util::{arrow2_util, Arrow2ArrayDowncastRef as _}; // --- concat --- @@ -140,12 +140,10 @@ fn concat_single_is_noop() { { let unconcatenated = unconcatenated - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() .unwrap(); let concatenated = concatenated - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() .unwrap(); assert!( @@ -203,13 +201,11 @@ fn filter_does_allocate() { { let unfiltered = unfiltered .values() - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() .unwrap(); let filtered = filtered .values() - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() .unwrap(); assert!( @@ -269,13 +265,11 @@ fn filter_empty_or_full_is_noop() { { let unfiltered = unfiltered .values() - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() .unwrap(); let filtered = filtered .values() - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() .unwrap(); assert!( @@ -338,13 +332,11 @@ fn take_does_not_allocate() { { let untaken = untaken .values() - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() .unwrap(); let taken = taken .values() - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() .unwrap(); assert!( @@ -400,13 +392,11 @@ fn take_empty_or_full_is_noop() { { let untaken = untaken .values() - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() .unwrap(); let taken = taken .values() - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() .unwrap(); assert!( diff --git a/crates/store/re_chunk_store/Cargo.toml b/crates/store/re_chunk_store/Cargo.toml index b4d65bf4e554..eb9a6c598e3a 100644 --- a/crates/store/re_chunk_store/Cargo.toml +++ b/crates/store/re_chunk_store/Cargo.toml @@ -27,6 +27,7 @@ deadlock_detection = ["parking_lot/deadlock_detection"] [dependencies] # Rerun dependencies: +re_arrow_util.workspace = true re_byte_size.workspace = true re_chunk.workspace = true re_format.workspace = true diff --git a/crates/store/re_chunk_store/src/writes.rs b/crates/store/re_chunk_store/src/writes.rs index 45cbadc43bb5..01688903247a 100644 --- a/crates/store/re_chunk_store/src/writes.rs +++ b/crates/store/re_chunk_store/src/writes.rs @@ -387,7 +387,7 @@ impl ChunkStore { }); { let is_semantically_empty = - re_chunk::arrow2_util::is_list_array_semantically_empty(list_array); + re_arrow_util::arrow2_util::is_list_array_semantically_empty(list_array); column_metadata_state.is_semantically_empty &= is_semantically_empty; } diff --git a/crates/store/re_dataframe/Cargo.toml b/crates/store/re_dataframe/Cargo.toml index 185614733cc8..af5cce5c268a 100644 --- a/crates/store/re_dataframe/Cargo.toml +++ b/crates/store/re_dataframe/Cargo.toml @@ -26,6 +26,7 @@ default = [] [dependencies] # Rerun dependencies: +re_arrow_util.workspace = true re_chunk.workspace = true re_chunk_store.workspace = true re_log.workspace = true diff --git a/crates/store/re_dataframe/src/lib.rs b/crates/store/re_dataframe/src/lib.rs index 964ec466c789..58e2d4c4dddf 100644 --- a/crates/store/re_dataframe/src/lib.rs +++ b/crates/store/re_dataframe/src/lib.rs @@ -9,7 +9,9 @@ pub use self::query::QueryHandle; #[doc(no_inline)] pub use self::external::arrow2::chunk::Chunk as Arrow2Chunk; #[doc(no_inline)] -pub use self::external::re_chunk::{arrow2_util::concatenate_record_batches, TransportChunk}; +pub use self::external::re_chunk::{ + concat_record_batches::concatenate_record_batches, TransportChunk, +}; #[doc(no_inline)] pub use self::external::re_chunk_store::{ ChunkStoreConfig, ChunkStoreHandle, ColumnSelector, ComponentColumnSelector, Index, IndexRange, diff --git a/crates/store/re_dataframe/src/query.rs b/crates/store/re_dataframe/src/query.rs index 955e2099b944..4834b631dff4 100644 --- a/crates/store/re_dataframe/src/query.rs +++ b/crates/store/re_dataframe/src/query.rs @@ -19,6 +19,7 @@ use arrow2::{ use itertools::Itertools; use nohash_hasher::{IntMap, IntSet}; +use re_arrow_util::Arrow2ArrayDowncastRef as _; use re_chunk::{ external::arrow::array::ArrayRef, Chunk, ComponentName, EntityPath, RangeQuery, RowId, TimeInt, Timeline, UnitChunkShared, @@ -261,7 +262,7 @@ impl QueryHandle { archetype_name: descr.archetype_name, archetype_field_name: descr.archetype_field_name, }, - re_chunk::arrow2_util::new_list_array_of_empties( + re_arrow_util::arrow2_util::new_list_array_of_empties( child_datatype, chunk.num_rows(), ), @@ -518,8 +519,7 @@ impl QueryHandle { let values = list_array .values() - .as_any() - .downcast_ref::()?; + .downcast_array2_ref::()?; let indices = Arrow2PrimitiveArray::from_vec( values @@ -1324,7 +1324,8 @@ mod tests { use std::sync::Arc; use re_chunk::{ - arrow2_util::concatenate_record_batches, Chunk, ChunkId, RowId, TimePoint, TransportChunk, + concat_record_batches::concatenate_record_batches, Chunk, ChunkId, RowId, TimePoint, + TransportChunk, }; use re_chunk_store::{ ChunkStore, ChunkStoreConfig, ChunkStoreHandle, ResolvedTimeRange, TimeInt, diff --git a/crates/store/re_format_arrow/Cargo.toml b/crates/store/re_format_arrow/Cargo.toml index 1801d1154b3d..6287819d6ecb 100644 --- a/crates/store/re_format_arrow/Cargo.toml +++ b/crates/store/re_format_arrow/Cargo.toml @@ -20,11 +20,13 @@ all-features = true [dependencies] -arrow.workspace = true -itertools.workspace = true +re_arrow_util.workspace = true re_tuid.workspace = true re_types_core.workspace = true # tuid serialization +arrow.workspace = true +itertools.workspace = true + # native dependencies: [target.'cfg(not(target_arch = "wasm32"))'.dependencies] comfy-table = { workspace = true, features = ["tty"] } diff --git a/crates/store/re_format_arrow/src/lib.rs b/crates/store/re_format_arrow/src/lib.rs index 423f1d8db865..28af79ae8be5 100644 --- a/crates/store/re_format_arrow/src/lib.rs +++ b/crates/store/re_format_arrow/src/lib.rs @@ -8,8 +8,9 @@ use arrow::{ util::display::{ArrayFormatter, FormatOptions}, }; use comfy_table::{presets, Cell, Row, Table}; - use itertools::Itertools as _; + +use re_arrow_util::ArrowArrayDowncastRef as _; use re_tuid::Tuid; use re_types_core::Loggable as _; @@ -55,9 +56,7 @@ fn parse_tuid(array: &dyn Array, index: usize) -> Option { match array.data_type() { // Legacy MsgId lists: just grab the first value, they're all identical - DataType::List(_) => { - parse_inner(&array.as_any().downcast_ref::()?.value(index), 0) - } + DataType::List(_) => parse_inner(&array.downcast_array_ref::()?.value(index), 0), // New control columns: it's not a list to begin with! _ => parse_inner(array, index), } diff --git a/crates/store/re_grpc_client/Cargo.toml b/crates/store/re_grpc_client/Cargo.toml index 7b167c564a5a..b3eed2d127c3 100644 --- a/crates/store/re_grpc_client/Cargo.toml +++ b/crates/store/re_grpc_client/Cargo.toml @@ -20,6 +20,7 @@ all-features = true [dependencies] +re_arrow_util.workspace = true re_chunk.workspace = true re_error.workspace = true re_log.workspace = true diff --git a/crates/store/re_grpc_client/src/lib.rs b/crates/store/re_grpc_client/src/lib.rs index 0be4b33f743e..62ee365c1a9e 100644 --- a/crates/store/re_grpc_client/src/lib.rs +++ b/crates/store/re_grpc_client/src/lib.rs @@ -3,6 +3,7 @@ mod address; pub use address::{InvalidRedapAddress, RedapAddress}; +use re_arrow_util::Arrow2ArrayDowncastRef as _; use re_chunk::external::arrow2; use re_log_encoding::codec::wire::decoder::Decode; use re_log_types::external::re_types_core::ComponentDescriptor; @@ -280,8 +281,7 @@ pub fn store_info_from_catalog_chunk( reason: "no application_id field found".to_owned(), }))?; let app_id = data - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() .ok_or(StreamError::ChunkError(re_chunk::ChunkError::Malformed { reason: format!("application_id must be a utf8 array: {:?}", tc.schema_ref()), }))? @@ -294,8 +294,7 @@ pub fn store_info_from_catalog_chunk( reason: "no start_time field found".to_owned(), }))?; let start_time = data - .as_any() - .downcast_ref::() + .downcast_array2_ref::() .ok_or(StreamError::ChunkError(re_chunk::ChunkError::Malformed { reason: format!("start_time must be an int64 array: {:?}", tc.schema_ref()), }))? @@ -439,7 +438,7 @@ async fn stream_catalog_async( let data_arrays = sliced.iter().map(|e| Some(e.as_ref())).collect::>(); #[allow(clippy::unwrap_used)] // we know we've given the right field type let data_field_array: arrow2::array::ListArray = - re_chunk::arrow2_util::arrays_to_list_array( + re_arrow_util::arrow2_util::arrays_to_list_array( data_field_inner.data_type().clone().into(), &data_arrays, ) @@ -500,7 +499,7 @@ async fn stream_catalog_async( let rec_id_field = ArrowField::new("item", ArrowDataType::Utf8, true); #[allow(clippy::unwrap_used)] // we know we've given the right field type - let uris = re_chunk::arrow2_util::arrays_to_list_array( + let uris = re_arrow_util::arrow2_util::arrays_to_list_array( rec_id_field.data_type().clone().into(), &recording_id_arrays, ) diff --git a/crates/store/re_log_types/Cargo.toml b/crates/store/re_log_types/Cargo.toml index fcf98b9794e7..2437bbf3e5bf 100644 --- a/crates/store/re_log_types/Cargo.toml +++ b/crates/store/re_log_types/Cargo.toml @@ -42,6 +42,7 @@ serde = [ [dependencies] # Rerun +re_arrow_util.workspace = true re_build_info.workspace = true re_byte_size.workspace = true re_format.workspace = true diff --git a/crates/store/re_log_types/src/example_components.rs b/crates/store/re_log_types/src/example_components.rs index 43cd251bde33..06e1da14a4c8 100644 --- a/crates/store/re_log_types/src/example_components.rs +++ b/crates/store/re_log_types/src/example_components.rs @@ -2,6 +2,7 @@ use std::sync::Arc; +use re_arrow_util::ArrowArrayDowncastRef as _; use re_byte_size::SizeBytes; use re_types_core::{Component, ComponentDescriptor, DeserializationError, Loggable}; @@ -116,8 +117,7 @@ impl Loggable for MyPoint { data: &dyn arrow::array::Array, ) -> re_types_core::DeserializationResult>> { let array = data - .as_any() - .downcast_ref::() + .downcast_array_ref::() .ok_or(DeserializationError::downcast_error::< arrow::array::StructArray, >())?; @@ -126,14 +126,12 @@ impl Loggable for MyPoint { let y_array = array.columns()[1].as_ref(); let xs = x_array - .as_any() - .downcast_ref::() + .downcast_array_ref::() .ok_or(DeserializationError::downcast_error::< arrow::array::Float32Array, >())?; let ys = y_array - .as_any() - .downcast_ref::() + .downcast_array_ref::() .ok_or(DeserializationError::downcast_error::< arrow::array::Float32Array, >())?; @@ -235,8 +233,7 @@ impl Loggable for MyPoint64 { data: &dyn arrow::array::Array, ) -> re_types_core::DeserializationResult>> { let array = data - .as_any() - .downcast_ref::() + .downcast_array_ref::() .ok_or(DeserializationError::downcast_error::< arrow::array::StructArray, >())?; @@ -245,14 +242,12 @@ impl Loggable for MyPoint64 { let y_array = array.columns()[1].as_ref(); let xs = x_array - .as_any() - .downcast_ref::() + .downcast_array_ref::() .ok_or(DeserializationError::downcast_error::< arrow::array::Float64Array, >())?; let ys = y_array - .as_any() - .downcast_ref::() + .downcast_array_ref::() .ok_or(DeserializationError::downcast_error::< arrow::array::Float64Array, >())?; diff --git a/crates/store/re_query/Cargo.toml b/crates/store/re_query/Cargo.toml index 389d3e749ff5..c41b0c74bb32 100644 --- a/crates/store/re_query/Cargo.toml +++ b/crates/store/re_query/Cargo.toml @@ -28,6 +28,7 @@ codegen = [] [dependencies] # Rerun dependencies: +re_arrow_util.workspace = true re_byte_size.workspace = true re_chunk.workspace = true re_chunk_store.workspace = true diff --git a/crates/store/re_query/examples/latest_at.rs b/crates/store/re_query/examples/latest_at.rs index 2cfc8136dbb1..749858f089d5 100644 --- a/crates/store/re_query/examples/latest_at.rs +++ b/crates/store/re_query/examples/latest_at.rs @@ -4,6 +4,7 @@ use anyhow::Context; use arrow2::array::PrimitiveArray as Arrow2PrimitiveArray; use itertools::Itertools; +use re_arrow_util::Arrow2ArrayDowncastRef as _; use re_chunk::{Chunk, RowId}; use re_chunk_store::{ChunkStore, ChunkStoreHandle, LatestAtQuery}; use re_log_types::example_components::{MyColor, MyLabel, MyPoint, MyPoints}; @@ -77,8 +78,7 @@ fn main() -> anyhow::Result<()> { .component_batch_raw_arrow2(&MyColor::name()) .context("invalid")?; let colors = colors - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() .context("invalid")?; let colors = colors .values() diff --git a/crates/store/re_types_core/Cargo.toml b/crates/store/re_types_core/Cargo.toml index 2b83921d9012..f37d8d987a83 100644 --- a/crates/store/re_types_core/Cargo.toml +++ b/crates/store/re_types_core/Cargo.toml @@ -34,6 +34,7 @@ serde = ["dep:serde", "re_string_interner/serde"] [dependencies] # Rerun +re_arrow_util.workspace = true re_byte_size.workspace = true re_case.workspace = true re_error.workspace = true diff --git a/crates/store/re_types_core/src/tuid.rs b/crates/store/re_types_core/src/tuid.rs index 1bcbd9d6e22a..0075f2346e3e 100644 --- a/crates/store/re_types_core/src/tuid.rs +++ b/crates/store/re_types_core/src/tuid.rs @@ -5,6 +5,7 @@ use arrow::{ datatypes::{DataType, Field, Fields}, }; +use re_arrow_util::ArrowArrayDowncastRef as _; use re_tuid::Tuid; use crate::{DeserializationError, Loggable}; @@ -79,7 +80,7 @@ impl Loggable for Tuid { // NOTE: Unwrap is safe everywhere below, datatype is checked above. // NOTE: We don't even look at the validity, our datatype says we don't care. - let array = array.as_any().downcast_ref::().unwrap(); + let array = array.downcast_array_ref::().unwrap(); // TODO(cmc): Can we rely on the fields ordering from the datatype? I would assume not // since we generally cannot rely on anything when it comes to arrow… @@ -99,8 +100,7 @@ impl Loggable for Tuid { let get_buffer = |field_index: usize| { array.columns()[field_index] - .as_any() - .downcast_ref::() + .downcast_array_ref::() .unwrap() .values() }; diff --git a/crates/top/rerun_c/Cargo.toml b/crates/top/rerun_c/Cargo.toml index 978d6cde38c5..d8368f7102f0 100644 --- a/crates/top/rerun_c/Cargo.toml +++ b/crates/top/rerun_c/Cargo.toml @@ -35,6 +35,7 @@ test = false [dependencies] +re_arrow_util.workspace = true re_log = { workspace = true, features = ["setup"] } re_sdk = { workspace = true, features = ["data_loaders"] } re_video.workspace = true diff --git a/crates/top/rerun_c/src/lib.rs b/crates/top/rerun_c/src/lib.rs index 2da8b11d97f4..f5e0bafe322a 100644 --- a/crates/top/rerun_c/src/lib.rs +++ b/crates/top/rerun_c/src/lib.rs @@ -14,11 +14,11 @@ mod video; use std::ffi::{c_char, c_uchar, CString}; -use component_type_registry::COMPONENT_TYPES; -use once_cell::sync::Lazy; - use arrow::array::ArrayRef as ArrowArrayRef; use arrow_utils::arrow_array_from_c_ffi; +use once_cell::sync::Lazy; + +use re_arrow_util::Arrow2ArrayDowncastRef as _; use re_sdk::{ external::nohash_hasher::IntMap, log::{Chunk, ChunkId, PendingRow, TimeColumn}, @@ -26,6 +26,8 @@ use re_sdk::{ ComponentDescriptor, EntityPath, RecordingStream, RecordingStreamBuilder, StoreKind, TimePoint, Timeline, }; + +use component_type_registry::COMPONENT_TYPES; use recording_streams::{recording_stream, RECORDING_STREAMS}; // ---------------------------------------------------------------------------- @@ -997,8 +999,7 @@ fn rr_recording_stream_send_columns_impl( let component_values_untyped = unsafe { arrow_array_from_c_ffi(array, datatype) }?; let component_values = component_values_untyped - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() .ok_or_else(|| { CError::new( CErrorCode::ArrowFfiArrayImportError, diff --git a/crates/utils/re_arrow_util/Cargo.toml b/crates/utils/re_arrow_util/Cargo.toml new file mode 100644 index 000000000000..68a36945c59d --- /dev/null +++ b/crates/utils/re_arrow_util/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "re_arrow_util" +authors.workspace = true +description = "Helpers for working with arrow." +edition.workspace = true +homepage.workspace = true +include.workspace = true +license.workspace = true +publish = true +readme = "README.md" +repository.workspace = true +rust-version.workspace = true +version.workspace = true + +[lints] +workspace = true + +[package.metadata.docs.rs] +all-features = true + + +[features] + + +[dependencies] +re_log.workspace = true +re_tracing.workspace = true + +arrow.workspace = true +arrow2.workspace = true +itertools.workspace = true diff --git a/crates/utils/re_arrow_util/README.md b/crates/utils/re_arrow_util/README.md new file mode 100644 index 000000000000..6508f218a3ad --- /dev/null +++ b/crates/utils/re_arrow_util/README.md @@ -0,0 +1,10 @@ +# re_arrow_util + +Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. + +[![Latest version](https://img.shields.io/crates/v/re_arrow_util.svg)](https://crates.io/crates/re_arrow_util?speculative-link) +[![Documentation](https://docs.rs/re_arrow_util/badge.svg)](https://docs.rs/re_arrow_util?speculative-link) +![MIT](https://img.shields.io/badge/license-MIT-blue.svg) +![Apache](https://img.shields.io/badge/license-Apache-blue.svg) + +Helpers for working with arrow diff --git a/crates/store/re_chunk/src/arrow2_util.rs b/crates/utils/re_arrow_util/src/arrow2_util.rs similarity index 91% rename from crates/store/re_chunk/src/arrow2_util.rs rename to crates/utils/re_arrow_util/src/arrow2_util.rs index cebfa8505e31..dcf5c45c61ea 100644 --- a/crates/store/re_chunk/src/arrow2_util.rs +++ b/crates/utils/re_arrow_util/src/arrow2_util.rs @@ -1,4 +1,3 @@ -use arrow::datatypes::Schema as ArrowSchema; use arrow2::{ array::{ Array as Arrow2Array, BooleanArray as Arrow2BooleanArray, @@ -9,11 +8,38 @@ use arrow2::{ datatypes::DataType as Arrow2Datatype, offset::Offsets as ArrowOffsets, }; -use itertools::Itertools; +use itertools::Itertools as _; -use crate::TransportChunk; +// --------------------------------------------------------------------------------- -// --- +/// Downcast an arrow array to another array, without having to go via `Any`. +/// +/// This is shorter, but also better: it means we don't accidentally downcast +/// an arrow2 array to an arrow1 array, or vice versa. +pub trait Arrow2ArrayDowncastRef { + /// Downcast an arrow array to another array, without having to go via `Any`. + /// + /// This is shorter, but also better: it means we don't accidentally downcast + /// an arrow2 array to an arrow1 array, or vice versa. + fn downcast_array2_ref(&self) -> Option<&T>; +} + +impl Arrow2ArrayDowncastRef for dyn Arrow2Array { + fn downcast_array2_ref(&self) -> Option<&T> { + self.as_any().downcast_ref() + } +} + +impl Arrow2ArrayDowncastRef for A +where + A: Arrow2Array, +{ + fn downcast_array2_ref(&self) -> Option<&T> { + self.as_any().downcast_ref() + } +} + +// --------------------------------------------------------------------------------- /// Returns true if the given `list_array` is semantically empty. /// @@ -436,43 +462,3 @@ pub fn take_array( .unwrap() .clone() } - -// --- - -use arrow2::chunk::Chunk as Arrow2Chunk; - -/// Concatenate multiple [`TransportChunk`]s into one. -/// -/// This is a temporary method that we use while waiting to migrate towards `arrow-rs`. -/// * `arrow2` doesn't have a `RecordBatch` type, therefore we emulate that using our `TransportChunk`s. -/// * `arrow-rs` does have one, and it natively supports concatenation. -pub fn concatenate_record_batches( - schema: impl Into, - batches: &[TransportChunk], -) -> anyhow::Result { - let schema: ArrowSchema = schema.into(); - anyhow::ensure!( - batches - .iter() - .all(|batch| batch.schema_ref().as_ref() == &schema), - "concatenate_record_batches: all batches must have the same schema" - ); - - let mut output_columns = Vec::new(); - - if !batches.is_empty() { - for (i, _field) in schema.fields.iter().enumerate() { - let arrays: Option> = batches.iter().map(|batch| batch.column(i)).collect(); - let arrays = arrays.ok_or_else(|| { - anyhow::anyhow!("concatenate_record_batches: all batches must have the same schema") - })?; - let array = concat_arrays(&arrays)?; - output_columns.push(array); - } - } - - Ok(TransportChunk::new( - schema, - Arrow2Chunk::new(output_columns), - )) -} diff --git a/crates/store/re_chunk/src/arrow_util.rs b/crates/utils/re_arrow_util/src/arrow_util.rs similarity index 91% rename from crates/store/re_chunk/src/arrow_util.rs rename to crates/utils/re_arrow_util/src/arrow_util.rs index c3d80b207b9b..a8a5cd298822 100644 --- a/crates/store/re_chunk/src/arrow_util.rs +++ b/crates/utils/re_arrow_util/src/arrow_util.rs @@ -3,9 +3,35 @@ use arrow::{ buffer::{NullBuffer, OffsetBuffer}, datatypes::{DataType, Field}, }; -use itertools::Itertools; +use itertools::Itertools as _; -// --- +// --------------------------------------------------------------------------------- + +/// Downcast an arrow array to another array, without having to go via `Any`. +/// +/// This is shorter, but also better: it means we don't accidentally downcast +/// an arrow2 array to an arrow1 array, or vice versa. +pub trait ArrowArrayDowncastRef { + /// Downcast an arrow array to another array, without having to go via `Any`. + /// + /// This is shorter, but also better: it means we don't accidentally downcast + /// an arrow2 array to an arrow1 array, or vice versa. + fn downcast_array_ref(&self) -> Option<&T>; +} + +impl ArrowArrayDowncastRef for &dyn Array { + fn downcast_array_ref(&self) -> Option<&T> { + self.as_any().downcast_ref() + } +} + +impl ArrowArrayDowncastRef for ArrayRef { + fn downcast_array_ref(&self) -> Option<&T> { + self.as_any().downcast_ref() + } +} + +// --------------------------------------------------------------------------------- #[inline] pub fn into_arrow_ref(array: impl Array + 'static) -> ArrayRef { diff --git a/crates/utils/re_arrow_util/src/lib.rs b/crates/utils/re_arrow_util/src/lib.rs new file mode 100644 index 000000000000..20e0ffe898ef --- /dev/null +++ b/crates/utils/re_arrow_util/src/lib.rs @@ -0,0 +1,7 @@ +//! Helpers for working with arrow + +pub mod arrow2_util; +pub mod arrow_util; + +pub use arrow2_util::Arrow2ArrayDowncastRef; +pub use arrow_util::ArrowArrayDowncastRef; diff --git a/crates/viewer/re_ui/Cargo.toml b/crates/viewer/re_ui/Cargo.toml index f166efe51cf2..461293cc5246 100644 --- a/crates/viewer/re_ui/Cargo.toml +++ b/crates/viewer/re_ui/Cargo.toml @@ -34,10 +34,11 @@ arrow = ["dep:arrow"] [dependencies] -re_entity_db.workspace = true # syntax-highlighting for InstancePath. TODO(emilk): move InstancePath +re_arrow_util.workspace = true +re_entity_db.workspace = true # syntax-highlighting for InstancePath. TODO(emilk): move InstancePath re_format.workspace = true re_log.workspace = true -re_log_types.workspace = true # syntax-highlighting for EntityPath +re_log_types.workspace = true # syntax-highlighting for EntityPath re_tracing.workspace = true eframe = { workspace = true, default-features = false, features = ["wgpu"] } diff --git a/crates/viewer/re_ui/src/arrow_ui.rs b/crates/viewer/re_ui/src/arrow_ui.rs index 778c91fe64ba..4333279b9730 100644 --- a/crates/viewer/re_ui/src/arrow_ui.rs +++ b/crates/viewer/re_ui/src/arrow_ui.rs @@ -1,6 +1,8 @@ use arrow::util::display::{ArrayFormatter, FormatOptions}; use itertools::Itertools as _; +use re_arrow_util::ArrowArrayDowncastRef as _; + use crate::UiLayout; pub fn arrow_ui(ui: &mut egui::Ui, ui_layout: UiLayout, array: &dyn arrow::array::Array) { @@ -16,14 +18,14 @@ pub fn arrow_ui(ui: &mut egui::Ui, ui_layout: UiLayout, array: &dyn arrow::array // Special-treat text. // Note: we match on the raw data here, so this works for any component containing text. - if let Some(utf8) = array.as_any().downcast_ref::() { + if let Some(utf8) = array.downcast_array_ref::() { if utf8.values().len() == 1 { let string = utf8.value(0); ui_layout.data_label(ui, string); return; } } - if let Some(utf8) = array.as_any().downcast_ref::() { + if let Some(utf8) = array.downcast_array_ref::() { if utf8.values().len() == 1 { let string = utf8.value(0); ui_layout.data_label(ui, string); diff --git a/crates/viewer/re_view_dataframe/Cargo.toml b/crates/viewer/re_view_dataframe/Cargo.toml index ab6613059ce6..129b3c75e566 100644 --- a/crates/viewer/re_view_dataframe/Cargo.toml +++ b/crates/viewer/re_view_dataframe/Cargo.toml @@ -19,6 +19,7 @@ workspace = true all-features = true [dependencies] +re_arrow_util.workspace = true re_chunk_store.workspace = true re_dataframe.workspace = true re_error.workspace = true diff --git a/crates/viewer/re_view_dataframe/src/display_record_batch.rs b/crates/viewer/re_view_dataframe/src/display_record_batch.rs index b774c5f80f90..99d8d65fd735 100644 --- a/crates/viewer/re_view_dataframe/src/display_record_batch.rs +++ b/crates/viewer/re_view_dataframe/src/display_record_batch.rs @@ -11,6 +11,7 @@ use arrow::{ }; use thiserror::Error; +use re_arrow_util::ArrowArrayDowncastRef as _; use re_chunk_store::{ColumnDescriptor, ComponentColumnDescriptor, LatestAtQuery}; use re_dataframe::external::re_chunk::{TimeColumn, TimeColumnError}; use re_log_types::{EntityPath, TimeInt, Timeline}; @@ -52,21 +53,18 @@ impl ComponentData { ArrowDataType::Null => Ok(Self::Null), ArrowDataType::List(_) => Ok(Self::ListArray( column_data - .as_any() - .downcast_ref::() + .downcast_array_ref::() .expect("`data_type` checked, failure is a bug in re_dataframe") .clone(), )), ArrowDataType::Dictionary(_, _) => { let dict = column_data - .as_any() - .downcast_ref::() + .downcast_array_ref::() .expect("`data_type` checked, failure is a bug in re_dataframe") .clone(); let values = dict .values() - .as_any() - .downcast_ref::() + .downcast_array_ref::() .expect("`data_type` checked, failure is a bug in re_dataframe") .clone(); Ok(Self::DictionaryArray { dict, values }) diff --git a/rerun_py/Cargo.toml b/rerun_py/Cargo.toml index 99cdf915700a..0cc66e0e91a2 100644 --- a/rerun_py/Cargo.toml +++ b/rerun_py/Cargo.toml @@ -58,6 +58,7 @@ web_viewer = [ [dependencies] +re_arrow_util.workspace = true re_build_info.workspace = true re_chunk = { workspace = true, features = ["arrow"] } re_chunk_store.workspace = true diff --git a/rerun_py/src/arrow.rs b/rerun_py/src/arrow.rs index 87a6968e5f07..16dc761d3066 100644 --- a/rerun_py/src/arrow.rs +++ b/rerun_py/src/arrow.rs @@ -17,6 +17,7 @@ use pyo3::{ Bound, PyAny, PyResult, }; +use re_arrow_util::Arrow2ArrayDowncastRef as _; use re_chunk::{Chunk, ChunkError, ChunkId, PendingRow, RowId, TimeColumn, TransportChunk}; use re_log_types::TimePoint; use re_sdk::{external::nohash_hasher::IntMap, ComponentDescriptor, EntityPath, Timeline}; @@ -161,7 +162,7 @@ pub fn build_chunk_from_components( .into_iter() .zip(fields) .map(|(value, field)| { - let batch = if let Some(batch) = value.as_any().downcast_ref::>() { + let batch = if let Some(batch) = value.downcast_array2_ref::>() { batch.clone() } else { let offsets = Offsets::try_from_lengths(std::iter::repeat(1).take(value.len())) diff --git a/rerun_py/src/dataframe.rs b/rerun_py/src/dataframe.rs index fd7772b3a4be..79b8ba2f82d2 100644 --- a/rerun_py/src/dataframe.rs +++ b/rerun_py/src/dataframe.rs @@ -8,7 +8,7 @@ use std::{ }; use arrow::{ - array::{make_array, Array, ArrayData, Int64Array, RecordBatchIterator, RecordBatchReader}, + array::{make_array, ArrayData, Int64Array, RecordBatchIterator, RecordBatchReader}, pyarrow::PyArrowType, }; use numpy::PyArrayMethods as _; @@ -18,6 +18,7 @@ use pyo3::{ types::{PyDict, PyTuple}, }; +use re_arrow_util::ArrowArrayDowncastRef as _; use re_chunk_store::{ ChunkStore, ChunkStoreConfig, ChunkStoreHandle, ColumnDescriptor, ColumnSelector, ComponentColumnDescriptor, ComponentColumnSelector, QueryExpression, SparseFillStrategy, @@ -344,7 +345,7 @@ impl IndexValuesLike<'_> { Self::PyArrow(array) => { let array = make_array(array.0.clone()); - let int_array = array.as_any().downcast_ref::().ok_or_else(|| { + let int_array = array.downcast_array_ref::().ok_or_else(|| { PyTypeError::new_err("pyarrow.Array for IndexValuesLike must be of type int64.") })?; @@ -393,7 +394,7 @@ impl IndexValuesLike<'_> { let array = make_array(chunk.0.clone()); let int_array = - array.as_any().downcast_ref::().ok_or_else(|| { + array.downcast_array_ref::().ok_or_else(|| { PyTypeError::new_err( "pyarrow.Array for IndexValuesLike must be of type int64.", ) diff --git a/rerun_py/src/remote.rs b/rerun_py/src/remote.rs index a19d779787b0..61ff89875aa3 100644 --- a/rerun_py/src/remote.rs +++ b/rerun_py/src/remote.rs @@ -15,6 +15,7 @@ use pyo3::{ types::PyDict, Bound, PyResult, }; +use re_arrow_util::Arrow2ArrayDowncastRef as _; use re_chunk::{Chunk, TransportChunk}; use re_chunk_store::ChunkStore; use re_dataframe::{ChunkStoreHandle, QueryExpression, SparseFillStrategy, ViewContentsSelector}; @@ -350,8 +351,7 @@ impl PyStorageNodeClient { .find(|(field, _data)| field.name() == "rerun_recording_id") .map(|(_field, data)| data) .ok_or(PyRuntimeError::new_err("No rerun_recording_id"))? - .as_any() - .downcast_ref::>() + .downcast_array2_ref::>() .ok_or(PyRuntimeError::new_err("Recording Id is not a string"))? .value(0) .to_owned(); diff --git a/rerun_py/src/video.rs b/rerun_py/src/video.rs index 42b3ad08e174..0ada08d02c29 100644 --- a/rerun_py/src/video.rs +++ b/rerun_py/src/video.rs @@ -1,6 +1,8 @@ #![allow(unsafe_op_in_unsafe_fn)] // False positive due to #[pyfunction] macro use pyo3::{exceptions::PyRuntimeError, pyfunction, Bound, PyAny, PyResult}; + +use re_arrow_util::Arrow2ArrayDowncastRef as _; use re_sdk::ComponentDescriptor; use re_video::VideoLoadError; @@ -26,9 +28,8 @@ pub fn asset_video_read_frame_timestamps_ns( let video_bytes_arrow_array = array_to_rust(video_bytes_arrow_array, &component_descr)?.0; let video_bytes_arrow_uint8_array = video_bytes_arrow_array - .as_any() - .downcast_ref::>() - .and_then(|arr| arr.values().as_any().downcast_ref::()) + .downcast_array2_ref::>() + .and_then(|arr| arr.values().downcast_array2_ref::()) .ok_or_else(|| { PyRuntimeError::new_err(format!( "Expected arrow array to be a list with a single uint8 array, instead it has the datatype {:?}", From d747b6c280b5366996816609a1cefce7aec1dabe Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Wed, 15 Jan 2025 10:09:18 +0100 Subject: [PATCH 38/57] Add new `Transform3D` partial updates snippet for all languages (#8690) Adds some much needed snippet for partial updates on `Transform3D`. Much needed because A) `Transform3D` has a long history of custom partial updatability hacks and B) users are very very likely to use that one. * Part of #8580 --- docs/snippets/INDEX.md | 4 ++ .../transform3d_partial_updates.cpp | 57 ++++++++++++++++++ .../archetypes/transform3d_partial_updates.py | 53 ++++++++++++++++ .../archetypes/transform3d_partial_updates.rs | 60 +++++++++++++++++++ docs/snippets/snippets.toml | 4 ++ lychee.toml | 3 + 6 files changed, 181 insertions(+) create mode 100644 docs/snippets/all/archetypes/transform3d_partial_updates.cpp create mode 100644 docs/snippets/all/archetypes/transform3d_partial_updates.py create mode 100644 docs/snippets/all/archetypes/transform3d_partial_updates.rs diff --git a/docs/snippets/INDEX.md b/docs/snippets/INDEX.md index aa559659970c..f77453ae1a2e 100644 --- a/docs/snippets/INDEX.md +++ b/docs/snippets/INDEX.md @@ -67,6 +67,7 @@ _All snippets, organized by the [`Archetype`](https://rerun.io/docs/reference/ty | **[`Boxes3D`](https://rerun.io/docs/reference/types/archetypes/boxes3d)** | `archetypes/boxes3d_batch` | Log a batch of oriented bounding boxes | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/boxes3d_batch.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/boxes3d_batch.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/boxes3d_batch.cpp) | | **[`Boxes3D`](https://rerun.io/docs/reference/types/archetypes/boxes3d)** | `archetypes/instance_poses3d_combined` | Log a simple 3D box with a regular & instance pose transform | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/instance_poses3d_combined.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/instance_poses3d_combined.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/instance_poses3d_combined.cpp) | | **[`Boxes3D`](https://rerun.io/docs/reference/types/archetypes/boxes3d)** | `archetypes/mesh3d_instancing` | Log a simple 3D mesh with several instance pose transforms which instantiate the mesh several times and will not affect its children (known as mesh instancing) | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/mesh3d_instancing.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/mesh3d_instancing.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/mesh3d_instancing.cpp) | +| **[`Boxes3D`](https://rerun.io/docs/reference/types/archetypes/boxes3d)** | `archetypes/transform3d_partial_updates` | Log different transforms with visualized coordinates axes | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.cpp) | | **[`Boxes3D`](https://rerun.io/docs/reference/types/archetypes/boxes3d)** | `views/spatial3d` | Use a blueprint to customize a Spatial3DView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/spatial3d.py) | | | | **[`Capsules3D`](https://rerun.io/docs/reference/types/archetypes/capsules3d)** | `archetypes/capsules3d_batch` | Log a batch of capsules | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/capsules3d_batch.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/capsules3d_batch.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/capsules3d_batch.cpp) | | **[`Clear`](https://rerun.io/docs/reference/types/archetypes/clear)** | `archetypes/clear_simple` | Log and then clear data | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/clear_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/clear_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/clear_simple.cpp) | @@ -176,6 +177,7 @@ _All snippets, organized by the [`Archetype`](https://rerun.io/docs/reference/ty | **[`TextLog`](https://rerun.io/docs/reference/types/archetypes/text_log)** | `concepts/app-model/native-async` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-async.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-async.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-async.cpp) | | **[`TextLog`](https://rerun.io/docs/reference/types/archetypes/text_log)** | `concepts/app-model/native-sync` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-sync.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-sync.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-sync.cpp) | | **[`Transform3D`](https://rerun.io/docs/reference/types/archetypes/transform3d)** | `archetypes/transform3d_simple` | Log different transforms between three arrows | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_simple.cpp) | +| **[`Transform3D`](https://rerun.io/docs/reference/types/archetypes/transform3d)** | `archetypes/transform3d_partial_updates` | Log different transforms with visualized coordinates axes | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.cpp) | | **[`Transform3D`](https://rerun.io/docs/reference/types/archetypes/transform3d)** | `archetypes/transform3d_hierarchy` | Logs a transforms transform hierarchy | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_hierarchy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_hierarchy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_hierarchy.cpp) | | **[`Transform3D`](https://rerun.io/docs/reference/types/archetypes/transform3d)** | `archetypes/transform3d_axes` | Log different transforms with visualized coordinates axes | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_axes.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_axes.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_axes.cpp) | | **[`Transform3D`](https://rerun.io/docs/reference/types/archetypes/transform3d)** | `archetypes/instance_poses3d_combined` | Log a simple 3D box with a regular & instance pose transform | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/instance_poses3d_combined.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/instance_poses3d_combined.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/instance_poses3d_combined.cpp) | @@ -210,6 +212,7 @@ _All snippets, organized by the [`Component`](https://rerun.io/docs/reference/ty | **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `concepts/viscomp-visualizer-override-multiple` | Override a visualizer | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/viscomp-visualizer-override-multiple.py) | | | | **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `descriptors/descr_custom_archetype` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_custom_archetype.cpp) | | **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `views/spatial3d` | Use a blueprint to customize a Spatial3DView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/spatial3d.py) | | | +| **[`FillMode`](https://rerun.io/docs/reference/types/components/fill_mode)** | `archetypes/transform3d_partial_updates` | Log different transforms with visualized coordinates axes | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.cpp) | | **[`GeoLineString`](https://rerun.io/docs/reference/types/components/geo_line_string)** | `archetypes/geo_line_strings_simple` | Log a simple geospatial line string | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_line_strings_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_line_strings_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_line_strings_simple.cpp) | | **[`GraphEdge`](https://rerun.io/docs/reference/types/components/graph_edge)** | `archetypes/graph_directed` | Log a simple directed graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_directed.cpp) | | **[`GraphEdge`](https://rerun.io/docs/reference/types/components/graph_edge)** | `archetypes/graph_undirected` | Log a simple undirected graph | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/graph_undirected.cpp) | @@ -245,6 +248,7 @@ _All snippets, organized by the [`Component`](https://rerun.io/docs/reference/ty | **[`RotationAxisAngle`](https://rerun.io/docs/reference/types/components/rotation_axis_angle)** | `archetypes/mesh3d_instancing` | Log a simple 3D mesh with several instance pose transforms which instantiate the mesh several times and will not affect its children (known as mesh instancing) | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/mesh3d_instancing.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/mesh3d_instancing.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/mesh3d_instancing.cpp) | | **[`RotationAxisAngle`](https://rerun.io/docs/reference/types/components/rotation_axis_angle)** | `archetypes/transform3d_axes` | Log different transforms with visualized coordinates axes | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_axes.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_axes.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_axes.cpp) | | **[`RotationAxisAngle`](https://rerun.io/docs/reference/types/components/rotation_axis_angle)** | `archetypes/transform3d_hierarchy` | Logs a transforms transform hierarchy | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_hierarchy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_hierarchy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_hierarchy.cpp) | +| **[`RotationAxisAngle`](https://rerun.io/docs/reference/types/components/rotation_axis_angle)** | `archetypes/transform3d_partial_updates` | Log different transforms with visualized coordinates axes | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.cpp) | | **[`RotationAxisAngle`](https://rerun.io/docs/reference/types/components/rotation_axis_angle)** | `archetypes/transform3d_simple` | Log different transforms between three arrows | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_simple.cpp) | | **[`Scalar`](https://rerun.io/docs/reference/types/components/scalar)** | `archetypes/scalar_simple` | Log a scalar over time | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/scalar_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/scalar_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/scalar_simple.cpp) | | **[`Scalar`](https://rerun.io/docs/reference/types/components/scalar)** | `archetypes/scalar_send_columns` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/scalar_send_columns.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/scalar_send_columns.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/scalar_send_columns.cpp) | diff --git a/docs/snippets/all/archetypes/transform3d_partial_updates.cpp b/docs/snippets/all/archetypes/transform3d_partial_updates.cpp new file mode 100644 index 000000000000..384723c1cb3c --- /dev/null +++ b/docs/snippets/all/archetypes/transform3d_partial_updates.cpp @@ -0,0 +1,57 @@ +// Log different transforms with visualized coordinates axes. + +#include + +float truncated_radians(int deg) { + auto degf = static_cast(deg); + const auto pi = 3.14159265358979323846; + return static_cast(static_cast(degf * pi / 180.0f * 1000.0f)) / 1000.0f; +} + +int main() { + const auto rec = rerun::RecordingStream("rerun_example_transform3d_partial_updates"); + rec.spawn().exit_on_failure(); + + // Set up a 3D box. + rec.log( + "box", + rerun::Boxes3D::from_half_sizes({{4.f, 2.f, 1.0f}}).with_fill_mode(rerun::FillMode::Solid), + rerun::Transform3D().with_axis_length(10.0) + ); + + // Update only the rotation of the box. + for (int deg = 0; deg <= 45; deg++) { + auto rad = truncated_radians(deg * 4); + // TODO(#8583): update_fields + rec.log( + "box", + rerun::Transform3D().with_rotation_axis_angle( + rerun::RotationAxisAngle({0.0f, 1.0f, 0.0f}, rerun::Angle::radians(rad)) + ) + ); + } + + // Update only the position of the box. + for (int t = 0; t <= 45; t++) { + rec.log( + "box", + rerun::Transform3D().with_translation({0.0f, 0.0f, static_cast(t) / 10.0f}) + ); + } + + // Update only the rotation of the box. + for (int deg = 0; deg <= 45; deg++) { + auto rad = truncated_radians((deg + 45) * 4); + // TODO(#8583): update_fields + rec.log( + "box", + rerun::Transform3D().with_rotation_axis_angle( + rerun::RotationAxisAngle({0.0f, 1.0f, 0.0f}, rerun::Angle::radians(rad)) + ) + ); + } + + // Clear all of the box's attributes, and reset its axis length. + // TODO(#8583): clear_fields + rec.log("box", rerun::Transform3D().with_axis_length(15.0)); +} diff --git a/docs/snippets/all/archetypes/transform3d_partial_updates.py b/docs/snippets/all/archetypes/transform3d_partial_updates.py new file mode 100644 index 000000000000..1b05dd5db502 --- /dev/null +++ b/docs/snippets/all/archetypes/transform3d_partial_updates.py @@ -0,0 +1,53 @@ +"""Log different transforms with visualized coordinates axes.""" + +import math + +import rerun as rr + + +def truncated_radians(deg: float) -> float: + return float(int(math.radians(deg) * 1000.0)) / 1000.0 + + +rr.init("rerun_example_transform3d_partial_updates", spawn=True) + +rr.log( + "box", + rr.Boxes3D(half_sizes=[4.0, 2.0, 1.0], fill_mode=rr.components.FillMode.Solid), + rr.Transform3D(axis_length=10), +) + +for deg in range(46): + rad = truncated_radians(deg * 4) + # TODO(#8582): update_fields + rr.log( + "box", + rr.Transform3D( + # TODO(cmc): we should have access to all the fields of the extended constructor too. + rotation_axis_angle=rr.RotationAxisAngle(axis=[0.0, 1.0, 0.0], radians=rad), + ), + ) + +for t in range(51): + # TODO(#8582): update_fields + rr.log( + "box", + rr.Transform3D(translation=[0, 0, t / 10.0]), + ) + +for deg in range(46): + rad = truncated_radians((deg + 45) * 4) + # TODO(#8582): update_fields + rr.log( + "box", + rr.Transform3D( + # TODO(cmc): we should have access to all the fields of the extended constructor too. + rotation_axis_angle=rr.RotationAxisAngle(axis=[0.0, 1.0, 0.0], radians=rad), + ), + ) + +# TODO(#8582): update_fields(clear=True) +rr.log( + "box", + rr.Transform3D(axis_length=15), +) diff --git a/docs/snippets/all/archetypes/transform3d_partial_updates.rs b/docs/snippets/all/archetypes/transform3d_partial_updates.rs new file mode 100644 index 000000000000..ad3f75f6daaa --- /dev/null +++ b/docs/snippets/all/archetypes/transform3d_partial_updates.rs @@ -0,0 +1,60 @@ +//! Log different transforms with visualized coordinates axes. + +fn main() -> Result<(), Box> { + let rec = + rerun::RecordingStreamBuilder::new("rerun_example_transform3d_partial_updates").spawn()?; + + // Set up a 3D box. + rec.log( + "box", + &[ + &rerun::Boxes3D::from_half_sizes([(4.0, 2.0, 1.0)]) + .with_fill_mode(rerun::FillMode::Solid) as &dyn rerun::AsComponents, + &rerun::Transform3D::default().with_axis_length(10.0), + ], + )?; + + // Update only the rotation of the box. + for deg in 0..=45 { + let rad = truncated_radians((deg * 4) as f32); + rec.log( + "box", + &rerun::Transform3D::update_fields().with_rotation(rerun::RotationAxisAngle::new( + [0.0, 1.0, 0.0], + rerun::Angle::from_radians(rad), + )), + )?; + } + + // Update only the position of the box. + for t in 0..=50 { + rec.log( + "box", + &rerun::Transform3D::update_fields().with_translation([0.0, 0.0, t as f32 / 10.0]), + )?; + } + + // Update only the rotation of the box. + for deg in 0..=45 { + let rad = truncated_radians(((deg + 45) * 4) as f32); + rec.log( + "box", + &rerun::Transform3D::update_fields().with_rotation(rerun::RotationAxisAngle::new( + [0.0, 1.0, 0.0], + rerun::Angle::from_radians(rad), + )), + )?; + } + + // Clear all of the box's attributes, and reset its axis length. + rec.log( + "box", + &rerun::Transform3D::clear_fields().with_axis_length(15.0), + )?; + + Ok(()) +} + +fn truncated_radians(deg: f32) -> f32 { + ((deg.to_radians() * 1000.0) as i32) as f32 / 1000.0 +} diff --git a/docs/snippets/snippets.toml b/docs/snippets/snippets.toml index d911b5f21f6c..6b66945e367c 100644 --- a/docs/snippets/snippets.toml +++ b/docs/snippets/snippets.toml @@ -271,6 +271,10 @@ quick_start = [ # These examples don't have exactly the same implementation. "archetypes/transform3d_hierarchy" = [ # Uses a lot of trigonometry which is surprisingly easy to get the same on Rust & C++, but not on Python/Numpy "py", ] +"archetypes/transform3d_partial_updates" = [ + "cpp", # TODO(#8583): remove once C++ partial updates APIs have shipped + "py", # TODO(#8582): remove once Python partial updates APIs have shipped +] "archetypes/instance_poses3d_combined" = [ # TODO(#3235): Slight floating point differences in point grid. "cpp", "py", diff --git a/lychee.toml b/lychee.toml index 7342caee577e..dbe1ae32f097 100644 --- a/lychee.toml +++ b/lychee.toml @@ -160,4 +160,7 @@ exclude = [ 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp', 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs', 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs', + 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.py', + 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.cpp', + 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.rs', ] From 77d4f58e4cd9c2292a38e8ab7399df0b487352e9 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 15 Jan 2025 16:06:58 +0100 Subject: [PATCH 39/57] Improve transform performance (by caching affine transforms resulting from transform components) (#8691) --- crates/store/re_query/src/latest_at.rs | 4 +- .../re_types/src/archetypes/pinhole_ext.rs | 10 +- crates/viewer/re_view/src/query.rs | 26 +- .../re_view_spatial/src/contexts/mod.rs | 6 +- ...m_context.rs => transform_tree_context.rs} | 589 ++++----- crates/viewer/re_view_spatial/src/lib.rs | 3 +- .../re_view_spatial/src/transform_cache.rs | 1093 +++++++++++++++++ .../src/transform_component_tracker.rs | 139 --- crates/viewer/re_view_spatial/src/ui_2d.rs | 3 +- crates/viewer/re_view_spatial/src/view_2d.rs | 2 +- crates/viewer/re_view_spatial/src/view_3d.rs | 2 +- .../src/visualizers/cameras.rs | 19 +- .../src/visualizers/depth_images.rs | 3 +- .../re_view_spatial/src/visualizers/mod.rs | 6 +- .../src/visualizers/transform3d_arrows.rs | 6 +- .../visualizers/utilities/entity_iterator.rs | 7 +- 16 files changed, 1365 insertions(+), 553 deletions(-) rename crates/viewer/re_view_spatial/src/contexts/{transform_context.rs => transform_tree_context.rs} (50%) create mode 100644 crates/viewer/re_view_spatial/src/transform_cache.rs delete mode 100644 crates/viewer/re_view_spatial/src/transform_component_tracker.rs diff --git a/crates/store/re_query/src/latest_at.rs b/crates/store/re_query/src/latest_at.rs index eb0afd78425d..922cd3a648b1 100644 --- a/crates/store/re_query/src/latest_at.rs +++ b/crates/store/re_query/src/latest_at.rs @@ -508,7 +508,7 @@ impl LatestAtResults { /// Returns the deserialized data for the specified component, assuming a mono-batch. /// - /// Returns an error if the data cannot be deserialized, or if the underlying batch is not of unit length. + /// Logs an error if the data cannot be deserialized, or if the underlying batch is not of unit length. #[inline] pub fn component_mono(&self) -> Option { self.component_mono_with_log_level(re_log::Level::Error) @@ -516,7 +516,7 @@ impl LatestAtResults { /// Returns the deserialized data for the specified component, assuming a mono-batch. /// - /// Returns an error if the data cannot be deserialized, or if the underlying batch is not of unit length. + /// Returns none if the data cannot be deserialized, or if the underlying batch is not of unit length. #[inline] pub fn component_mono_quiet(&self) -> Option { self.components diff --git a/crates/store/re_types/src/archetypes/pinhole_ext.rs b/crates/store/re_types/src/archetypes/pinhole_ext.rs index 787e2b932837..dba2076ef46b 100644 --- a/crates/store/re_types/src/archetypes/pinhole_ext.rs +++ b/crates/store/re_types/src/archetypes/pinhole_ext.rs @@ -1,8 +1,16 @@ -use crate::datatypes::Vec2D; +use crate::{components::ViewCoordinates, datatypes::Vec2D}; use super::Pinhole; impl Pinhole { + /// Camera orientation used when there's no camera orientation explicitly logged. + /// + /// - x pointing right + /// - y pointing down + /// - z pointing into the image plane + /// (this is convenient for reading out a depth image which has typically positive z values) + pub const DEFAULT_CAMERA_XYZ: ViewCoordinates = ViewCoordinates::RDF; + /// Creates a pinhole from the camera focal length and resolution, both specified in pixels. /// /// The focal length is the diagonal of the projection matrix. diff --git a/crates/viewer/re_view/src/query.rs b/crates/viewer/re_view/src/query.rs index 7365c2324cc8..d997c2a94e35 100644 --- a/crates/viewer/re_view/src/query.rs +++ b/crates/viewer/re_view/src/query.rs @@ -215,6 +215,12 @@ pub trait DataResultQuery { latest_at_query: &'a LatestAtQuery, ) -> HybridLatestAtResults<'a>; + fn latest_at_with_blueprint_resolved_data_for_component<'a, C: re_types_core::Component>( + &'a self, + ctx: &'a ViewContext<'a>, + latest_at_query: &'a LatestAtQuery, + ) -> HybridLatestAtResults<'a>; + fn query_archetype_with_history<'a, A: re_types_core::Archetype>( &'a self, ctx: &'a ViewContext<'a>, @@ -235,14 +241,30 @@ impl DataResultQuery for DataResult { ctx: &'a ViewContext<'a>, latest_at_query: &'a LatestAtQuery, ) -> HybridLatestAtResults<'a> { - let query_shadowed_defaults = false; + let query_shadowed_components = false; latest_at_with_blueprint_resolved_data( ctx, None, latest_at_query, self, A::all_components().iter().map(|descr| descr.component_name), - query_shadowed_defaults, + query_shadowed_components, + ) + } + + fn latest_at_with_blueprint_resolved_data_for_component<'a, C: re_types_core::Component>( + &'a self, + ctx: &'a ViewContext<'a>, + latest_at_query: &'a LatestAtQuery, + ) -> HybridLatestAtResults<'a> { + let query_shadowed_components = false; + latest_at_with_blueprint_resolved_data( + ctx, + None, + latest_at_query, + self, + std::iter::once(C::name()), + query_shadowed_components, ) } diff --git a/crates/viewer/re_view_spatial/src/contexts/mod.rs b/crates/viewer/re_view_spatial/src/contexts/mod.rs index 7bab048b990c..2bb6a7ac3877 100644 --- a/crates/viewer/re_view_spatial/src/contexts/mod.rs +++ b/crates/viewer/re_view_spatial/src/contexts/mod.rs @@ -1,10 +1,10 @@ mod depth_offsets; -mod transform_context; +mod transform_tree_context; pub use depth_offsets::EntityDepthOffsets; use re_types::ViewClassIdentifier; use re_view::AnnotationSceneContext; -pub use transform_context::{TransformContext, TransformInfo, TwoDInThreeDTransformInfo}; +pub use transform_tree_context::{TransformInfo, TransformTreeContext, TwoDInThreeDTransformInfo}; // ----------------------------------------------------------------------------- @@ -24,7 +24,7 @@ pub struct SpatialSceneEntityContext<'a> { pub fn register_spatial_contexts( system_registry: &mut re_viewer_context::ViewSystemRegistrator<'_>, ) -> Result<(), ViewClassRegistryError> { - system_registry.register_context_system::()?; + system_registry.register_context_system::()?; system_registry.register_context_system::()?; system_registry.register_context_system::()?; Ok(()) diff --git a/crates/viewer/re_view_spatial/src/contexts/transform_context.rs b/crates/viewer/re_view_spatial/src/contexts/transform_tree_context.rs similarity index 50% rename from crates/viewer/re_view_spatial/src/contexts/transform_context.rs rename to crates/viewer/re_view_spatial/src/contexts/transform_tree_context.rs index 4e7cbc27eb5c..6d474bd6b525 100644 --- a/crates/viewer/re_view_spatial/src/contexts/transform_context.rs +++ b/crates/viewer/re_view_spatial/src/contexts/transform_tree_context.rs @@ -1,23 +1,23 @@ -use itertools::Either; use nohash_hasher::IntMap; use re_chunk_store::LatestAtQuery; -use re_entity_db::{EntityDb, EntityPath, EntityTree}; +use re_entity_db::{EntityPath, EntityTree}; +use re_log_types::EntityPathHash; use re_types::{ - archetypes::{InstancePoses3D, Pinhole, Transform3D}, - components::{ - ImagePlaneDistance, PinholeProjection, PoseRotationAxisAngle, PoseRotationQuat, - PoseScale3D, PoseTransformMat3x3, PoseTranslation3D, RotationAxisAngle, RotationQuat, - Scale3D, TransformMat3x3, TransformRelation, Translation3D, ViewCoordinates, - }, + archetypes::{InstancePoses3D, Transform3D}, + components::{ImagePlaneDistance, PinholeProjection}, Archetype, Component as _, ComponentNameSet, }; use re_view::DataResultQuery as _; -use re_viewer_context::{IdentifiedViewSystem, ViewContext, ViewContextSystem}; +use re_viewer_context::{ + DataResultNode, DataResultTree, IdentifiedViewSystem, ViewContext, ViewContextSystem, +}; use vec1::smallvec_v1::SmallVec1; use crate::{ - transform_component_tracker::TransformComponentTrackerStoreSubscriber, + transform_cache::{ + CachedTransformsPerTimeline, ResolvedPinholeProjection, TransformCacheStoreSubscriber, + }, visualizers::image_view_coordinates, }; @@ -107,54 +107,50 @@ impl TransformInfo { } } -#[derive(Clone, Copy)] -enum UnreachableTransformReason { - /// More than one pinhole camera between this and the reference space. - NestedPinholeCameras, -} - /// Provides transforms from an entity to a chosen reference space for all elements in the scene /// for the currently selected time & timeline. /// +/// The resulting transforms are dependent on: +/// * tree, pose, pinhole and view-coordinates transforms components as logged to the data store +/// * TODO(#6743): blueprint overrides aren't respected yet +/// * the view' spatial origin +/// * the query time +/// * TODO(#723): ranges aren't taken into account yet +/// * TODO(andreas): the queried entities. Right now we determine transforms for ALL entities in the scene. +/// since 3D views tend to display almost everything that's mostly fine, but it's very wasteful when they don't. +/// /// The renderer then uses this reference space as its world space, /// making world and reference space equivalent for a given view. /// -/// Should be recomputed every frame. -/// -/// TODO(#7025): Alternative proposal to not have to deal with tree upwards walking & per-origin tree walking. +/// TODO(#7025): Right now we also do full tree traversal in here to resolve transforms to the root. +/// However, for views that share the same query, we can easily make all entities relative to the respective origin in a linear pass over all matrices. +/// (Note that right now the query IS always the same across all views for a given frame since it's just latest-at controlled by the timeline, +/// but once we support range queries it may be not or only partially the case) #[derive(Clone)] -pub struct TransformContext { +pub struct TransformTreeContext { /// All transforms provided are relative to this reference path. space_origin: EntityPath, /// All reachable entities. - transform_per_entity: IntMap, - - /// All unreachable descendant paths of `reference_path`. - unreachable_descendants: Vec<(EntityPath, UnreachableTransformReason)>, - - /// The first parent of `reference_path` that is no longer reachable. - first_unreachable_parent: Option<(EntityPath, UnreachableTransformReason)>, + transform_per_entity: IntMap, } -impl IdentifiedViewSystem for TransformContext { +impl IdentifiedViewSystem for TransformTreeContext { fn identifier() -> re_viewer_context::ViewSystemIdentifier { "TransformContext".into() } } -impl Default for TransformContext { +impl Default for TransformTreeContext { fn default() -> Self { Self { space_origin: EntityPath::root(), transform_per_entity: Default::default(), - unreachable_descendants: Default::default(), - first_unreachable_parent: None, } } } -impl ViewContextSystem for TransformContext { +impl ViewContextSystem for TransformTreeContext { fn compatible_component_sets(&self) -> Vec { vec![ Transform3D::all_components() @@ -180,10 +176,19 @@ impl ViewContextSystem for TransformContext { query: &re_viewer_context::ViewQuery<'_>, ) { re_tracing::profile_function!(); - debug_assert_transform_field_order(ctx.viewer_ctx.reflection); + // Make sure transform cache is up to date. + // TODO(andreas): This is a rather annoying sync point between different views. + // We could alleviate this by introducing a per view class (not instance) method that is called + // before system execution. + TransformCacheStoreSubscriber::access_mut(&ctx.recording().store_id(), |cache| { + cache.apply_all_updates(ctx.recording()); + }); + let entity_tree = ctx.recording().tree(); + let query_result = ctx.viewer_ctx.lookup_query_result(query.view_id); + let data_result_tree = &query_result.tree; self.space_origin = query.space_origin.clone(); @@ -197,19 +202,44 @@ impl ViewContextSystem for TransformContext { let time_query = ctx.current_query(); - // Child transforms of this space - self.gather_descendants_transforms( - ctx, - query, - current_tree, - ctx.recording(), - &time_query, - // Ignore potential pinhole camera at the root of the view, since it regarded as being "above" this root. - TransformInfo::default(), - ); + TransformCacheStoreSubscriber::access(&ctx.recording().store_id(), |cache| { + let Some(transforms_per_timeline) = cache.transforms_per_timeline(query.timeline) + else { + // No transforms on this timeline at all. In other words, everything is identity! + query_result.tree.visit(&mut |node: &DataResultNode| { + self.transform_per_entity.insert( + node.data_result.entity_path.hash(), + TransformInfo::default(), + ); + true + }); + return; + }; + + // Child transforms of this space + { + re_tracing::profile_scope!("gather_descendants_transforms"); + + self.gather_descendants_transforms( + ctx, + data_result_tree, + current_tree, + &time_query, + // Ignore potential pinhole camera at the root of the view, since it is regarded as being "above" this root. + TransformInfo::default(), + transforms_per_timeline, + ); + } - // Walk up from the reference to the highest reachable parent. - self.gather_parent_transforms(ctx, query, current_tree, &time_query); + // Walk up from the reference to the highest reachable parent. + self.gather_parent_transforms( + ctx, + data_result_tree, + current_tree, + &time_query, + transforms_per_timeline, + ); + }); // Note that this can return None if no event has happened for this timeline yet. } fn as_any(&self) -> &dyn std::any::Any { @@ -217,64 +247,56 @@ impl ViewContextSystem for TransformContext { } } -impl TransformContext { +impl TransformTreeContext { /// Gather transforms for everything _above_ the root. fn gather_parent_transforms<'a>( &mut self, ctx: &'a ViewContext<'a>, - query: &re_viewer_context::ViewQuery<'_>, + data_result_tree: &DataResultTree, mut current_tree: &'a EntityTree, time_query: &LatestAtQuery, + transforms_per_timeline: &CachedTransformsPerTimeline, ) { re_tracing::profile_function!(); let entity_tree = ctx.recording().tree(); - let mut encountered_pinhole = None; let mut reference_from_ancestor = glam::Affine3A::IDENTITY; while let Some(parent_path) = current_tree.path.parent() { let Some(parent_tree) = entity_tree.subtree(&parent_path) else { // Unlike not having the space path in the hierarchy, this should be impossible. re_log::error_once!( - "Path {} is not part of the global entity tree whereas its child {} is", - parent_path, - query.space_origin + "Path {parent_path} is not part of the global entity tree whereas its child is" ); return; }; // Note that the transform at the reference is the first that needs to be inverted to "break out" of its hierarchy. // Generally, the transform _at_ a node isn't relevant to it's children, but only to get to its parent in turn! - let new_transform = match transforms_at( + let transforms_at_entity = transforms_at( ¤t_tree.path, - ctx.recording(), time_query, // TODO(#1025): See comment in transform_at. This is a workaround for precision issues // and the fact that there is no meaningful image plane distance for 3D->2D views. |_| 500.0, - &mut encountered_pinhole, - ) { - Err(unreachable_reason) => { - self.first_unreachable_parent = - Some((parent_tree.path.clone(), unreachable_reason)); - break; - } - Ok(transforms_at_entity) => transform_info_for_upward_propagation( - reference_from_ancestor, - transforms_at_entity, - ), - }; + &mut None, // Don't care about pinhole encounters. + transforms_per_timeline, + ); + let new_transform = transform_info_for_upward_propagation( + reference_from_ancestor, + &transforms_at_entity, + ); reference_from_ancestor = new_transform.reference_from_entity; // (this skips over everything at and under `current_tree` automatically) self.gather_descendants_transforms( ctx, - query, + data_result_tree, parent_tree, - ctx.recording(), time_query, new_transform, + transforms_per_timeline, ); current_tree = parent_tree; @@ -285,15 +307,15 @@ impl TransformContext { fn gather_descendants_transforms( &mut self, ctx: &ViewContext<'_>, - view_query: &re_viewer_context::ViewQuery<'_>, + data_result_tree: &DataResultTree, subtree: &EntityTree, - entity_db: &EntityDb, query: &LatestAtQuery, transform: TransformInfo, + transforms_per_timeline: &CachedTransformsPerTimeline, ) { let twod_in_threed_info = transform.twod_in_threed_info.clone(); let reference_from_parent = transform.reference_from_entity; - match self.transform_per_entity.entry(subtree.path.clone()) { + match self.transform_per_entity.entry(subtree.path.hash()) { std::collections::hash_map::Entry::Occupied(_) => { return; } @@ -305,54 +327,34 @@ impl TransformContext { for child_tree in subtree.children.values() { let child_path = &child_tree.path; - let lookup_image_plane = |p: &_| { - let query_result = ctx.viewer_ctx.lookup_query_result(view_query.view_id); - - query_result - .tree - .lookup_result_by_path(p) - .cloned() - .map(|data_result| { - let results = data_result - .latest_at_with_blueprint_resolved_data::(ctx, query); - - results.get_mono_with_fallback::() - }) - .unwrap_or_default() - .into() - }; + let lookup_image_plane = + |p: &_| lookup_image_plane_distance(ctx, data_result_tree, p, query); let mut encountered_pinhole = twod_in_threed_info .as_ref() .map(|info| info.parent_pinhole.clone()); - let new_transform = match transforms_at( + + let transforms_at_entity = transforms_at( child_path, - entity_db, query, lookup_image_plane, &mut encountered_pinhole, - ) { - Err(unreachable_reason) => { - self.unreachable_descendants - .push((child_path.clone(), unreachable_reason)); - continue; - } - - Ok(transforms_at_entity) => transform_info_for_downward_propagation( - child_path, - reference_from_parent, - twod_in_threed_info.clone(), - transforms_at_entity, - ), - }; + transforms_per_timeline, + ); + let new_transform = transform_info_for_downward_propagation( + child_path, + reference_from_parent, + twod_in_threed_info.clone(), + &transforms_at_entity, + ); self.gather_descendants_transforms( ctx, - view_query, + data_result_tree, child_tree, - entity_db, query, new_transform, + transforms_per_timeline, ); } } @@ -364,15 +366,35 @@ impl TransformContext { /// Retrieves transform information for a given entity. /// /// Returns `None` if it's not reachable from the view's origin. - pub fn transform_info_for_entity(&self, ent_path: &EntityPath) -> Option<&TransformInfo> { - self.transform_per_entity.get(ent_path) + pub fn transform_info_for_entity(&self, ent_path: EntityPathHash) -> Option<&TransformInfo> { + self.transform_per_entity.get(&ent_path) } } +fn lookup_image_plane_distance( + ctx: &ViewContext<'_>, + data_result_tree: &DataResultTree, + entity_path: &EntityPath, + query: &LatestAtQuery, +) -> f32 { + data_result_tree + .lookup_result_by_path(entity_path) + .cloned() + .map(|data_result| { + data_result + .latest_at_with_blueprint_resolved_data_for_component::( + ctx, query, + ) + .get_mono_with_fallback::() + }) + .unwrap_or_default() + .into() +} + /// Compute transform info for when we walk up the tree from the reference. fn transform_info_for_upward_propagation( reference_from_ancestor: glam::Affine3A, - transforms_at_entity: TransformsAtEntity, + transforms_at_entity: &TransformsAtEntity<'_>, ) -> TransformInfo { let mut reference_from_entity = reference_from_ancestor; @@ -390,7 +412,7 @@ fn transform_info_for_upward_propagation( // Collect & compute poses. let (mut reference_from_instances, has_instance_transforms) = - if let Ok(mut entity_from_instances) = SmallVec1::<[glam::Affine3A; 1]>::try_from_vec( + if let Ok(mut entity_from_instances) = SmallVec1::<[glam::Affine3A; 1]>::try_from_slice( transforms_at_entity.entity_from_instance_poses, ) { for entity_from_instance in &mut entity_from_instances { @@ -402,18 +424,16 @@ fn transform_info_for_upward_propagation( (SmallVec1::new(reference_from_entity), false) }; - // Apply tree transform if any. - if let Some(parent_from_entity_tree_transform) = - transforms_at_entity.parent_from_entity_tree_transform - { - reference_from_entity *= parent_from_entity_tree_transform.inverse(); - if has_instance_transforms { - for reference_from_instance in &mut reference_from_instances { - *reference_from_instance = reference_from_entity * (*reference_from_instance); - } - } else { - *reference_from_instances.first_mut() = reference_from_entity; + // Apply tree transform. + reference_from_entity *= transforms_at_entity + .parent_from_entity_tree_transform + .inverse(); + if has_instance_transforms { + for reference_from_instance in &mut reference_from_instances { + *reference_from_instance = reference_from_entity * (*reference_from_instance); } + } else { + *reference_from_instances.first_mut() = reference_from_entity; } TransformInfo { @@ -431,21 +451,18 @@ fn transform_info_for_downward_propagation( current_path: &EntityPath, reference_from_parent: glam::Affine3A, mut twod_in_threed_info: Option, - transforms_at_entity: TransformsAtEntity, + transforms_at_entity: &TransformsAtEntity<'_>, ) -> TransformInfo { let mut reference_from_entity = reference_from_parent; // Apply tree transform. - if let Some(parent_from_entity_tree_transform) = - transforms_at_entity.parent_from_entity_tree_transform - { - reference_from_entity *= parent_from_entity_tree_transform; - } + + reference_from_entity *= transforms_at_entity.parent_from_entity_tree_transform; // Collect & compute poses. let (mut reference_from_instances, has_instance_transforms) = if let Ok(mut entity_from_instances) = - SmallVec1::try_from_vec(transforms_at_entity.entity_from_instance_poses) + SmallVec1::try_from_slice(transforms_at_entity.entity_from_instance_poses) { for entity_from_instance in &mut entity_from_instances { *entity_from_instance = reference_from_entity * (*entity_from_instance); @@ -491,15 +508,16 @@ fn transform_info_for_downward_propagation( #[cfg(debug_assertions)] fn debug_assert_transform_field_order(reflection: &re_types::reflection::Reflection) { + use re_types::{components, Archetype as _}; + let expected_order = vec![ - Translation3D::name(), - RotationAxisAngle::name(), - RotationQuat::name(), - Scale3D::name(), - TransformMat3x3::name(), + components::Translation3D::name(), + components::RotationAxisAngle::name(), + components::RotationQuat::name(), + components::Scale3D::name(), + components::TransformMat3x3::name(), ]; - use re_types::Archetype as _; let transform3d_reflection = reflection .archetypes .get(&re_types::archetypes::Transform3D::name()) @@ -528,276 +546,87 @@ But they are instead ordered like this:\n{actual_order:?}" #[cfg(not(debug_assertions))] fn debug_assert_transform_field_order(_: &re_types::reflection::Reflection) {} -fn query_and_resolve_tree_transform_at_entity( +fn transform_from_pinhole_with_image_plane( entity_path: &EntityPath, - entity_db: &EntityDb, - query: &LatestAtQuery, - transform3d_components: impl Iterator, -) -> Option { - // TODO(#6743): Doesn't take into account overrides. - let result = entity_db.latest_at(query, entity_path, transform3d_components); - if result.components.is_empty() { - return None; - } - - let mut transform = glam::Affine3A::IDENTITY; - - // Order see `debug_assert_transform_field_order` - if let Some(translation) = result.component_instance::(0) { - transform = glam::Affine3A::from(translation); - } - if let Some(axis_angle) = result.component_instance::(0) { - if let Ok(axis_angle) = glam::Affine3A::try_from(axis_angle) { - transform *= axis_angle; - } else { - // Invalid transform. - return None; - } - } - if let Some(quaternion) = result.component_instance::(0) { - if let Ok(quaternion) = glam::Affine3A::try_from(quaternion) { - transform *= quaternion; - } else { - // Invalid transform. - return None; - } - } - if let Some(scale) = result.component_instance::(0) { - if scale.x() == 0.0 && scale.y() == 0.0 && scale.z() == 0.0 { - // Invalid scale. - return None; - } - transform *= glam::Affine3A::from(scale); - } - if let Some(mat3x3) = result.component_instance::(0) { - let affine_transform = glam::Affine3A::from(mat3x3); - if affine_transform.matrix3.determinant() == 0.0 { - // Invalid transform. - return None; - } - transform *= affine_transform; - } - - if result.component_instance::(0) == Some(TransformRelation::ChildFromParent) - // TODO(andreas): Should we warn? This might be intentionally caused by zero scale. - && transform.matrix3.determinant() != 0.0 - { - transform = transform.inverse(); - } - - Some(transform) -} - -fn query_and_resolve_instance_poses_at_entity( - entity_path: &EntityPath, - entity_db: &EntityDb, - query: &LatestAtQuery, - pose3d_components: impl Iterator, -) -> Vec { - // TODO(#6743): Doesn't take into account overrides. - let result = entity_db.latest_at(query, entity_path, pose3d_components); - - let max_count = result - .components - .iter() - .map(|(name, row)| row.num_instances(name)) - .max() - .unwrap_or(0) as usize; - - if max_count == 0 { - return Vec::new(); - } - - #[inline] - pub fn clamped_or_nothing( - values: Vec, - clamped_len: usize, - ) -> impl Iterator { - let Some(last) = values.last() else { - return Either::Left(std::iter::empty()); - }; - let last = last.clone(); - Either::Right( - values - .into_iter() - .chain(std::iter::repeat(last)) - .take(clamped_len), - ) - } - - let mut iter_translation = clamped_or_nothing( - result - .component_batch::() - .unwrap_or_default(), - max_count, - ); - let mut iter_rotation_quat = clamped_or_nothing( - result - .component_batch::() - .unwrap_or_default(), - max_count, - ); - let mut iter_rotation_axis_angle = clamped_or_nothing( - result - .component_batch::() - .unwrap_or_default(), - max_count, - ); - let mut iter_scale = clamped_or_nothing( - result.component_batch::().unwrap_or_default(), - max_count, - ); - let mut iter_mat3x3 = clamped_or_nothing( - result - .component_batch::() - .unwrap_or_default(), - max_count, - ); - - let mut transforms = Vec::with_capacity(max_count); - for _ in 0..max_count { - // Order see `debug_assert_transform_field_order` - let mut transform = glam::Affine3A::IDENTITY; - if let Some(translation) = iter_translation.next() { - transform = glam::Affine3A::from(translation); - } - if let Some(rotation_quat) = iter_rotation_quat.next() { - if let Ok(rotation_quat) = glam::Affine3A::try_from(rotation_quat) { - transform *= rotation_quat; - } else { - transform = glam::Affine3A::ZERO; - } - } - if let Some(rotation_axis_angle) = iter_rotation_axis_angle.next() { - if let Ok(axis_angle) = glam::Affine3A::try_from(rotation_axis_angle) { - transform *= axis_angle; - } else { - transform = glam::Affine3A::ZERO; - } - } - if let Some(scale) = iter_scale.next() { - transform *= glam::Affine3A::from(scale); - } - if let Some(mat3x3) = iter_mat3x3.next() { - transform *= glam::Affine3A::from(mat3x3); - } - - transforms.push(transform); - } - - transforms -} - -fn query_and_resolve_obj_from_pinhole_image_plane( - entity_path: &EntityPath, - entity_db: &EntityDb, - query: &LatestAtQuery, + resolved_pinhole_projection: &ResolvedPinholeProjection, pinhole_image_plane_distance: impl Fn(&EntityPath) -> f32, -) -> Option { - entity_db - .latest_at_component::(entity_path, query) - .map(|(_index, image_from_camera)| { - ( - image_from_camera, - entity_db - .latest_at_component::(entity_path, query) - .map_or(ViewCoordinates::RDF, |(_index, res)| res), - ) - }) - .map(|(image_from_camera, view_coordinates)| { - // Everything under a pinhole camera is a 2D projection, thus doesn't actually have a proper 3D representation. - // Our visualization interprets this as looking at a 2D image plane from a single point (the pinhole). - - // Center the image plane and move it along z, scaling the further the image plane is. - let distance = pinhole_image_plane_distance(entity_path); - let focal_length = image_from_camera.focal_length_in_pixels(); - let focal_length = glam::vec2(focal_length.x(), focal_length.y()); - let scale = distance / focal_length; - let translation = (-image_from_camera.principal_point() * scale).extend(distance); - - let image_plane3d_from_2d_content = glam::Affine3A::from_translation(translation) +) -> glam::Affine3A { + let ResolvedPinholeProjection { + image_from_camera, + view_coordinates, + } = resolved_pinhole_projection; + + // Everything under a pinhole camera is a 2D projection, thus doesn't actually have a proper 3D representation. + // Our visualization interprets this as looking at a 2D image plane from a single point (the pinhole). + + // Center the image plane and move it along z, scaling the further the image plane is. + let distance = pinhole_image_plane_distance(entity_path); + let focal_length = image_from_camera.focal_length_in_pixels(); + let focal_length = glam::vec2(focal_length.x(), focal_length.y()); + let scale = distance / focal_length; + let translation = (-image_from_camera.principal_point() * scale).extend(distance); + + let image_plane3d_from_2d_content = glam::Affine3A::from_translation(translation) // We want to preserve any depth that might be on the pinhole image. // Use harmonic mean of x/y scale for those. * glam::Affine3A::from_scale( scale.extend(2.0 / (1.0 / scale.x + 1.0 / scale.y)), ); - // Our interpretation of the pinhole camera implies that the axis semantics, i.e. ViewCoordinates, - // determine how the image plane is oriented. - // (see also `CamerasPart` where the frustum lines are set up) - let obj_from_image_plane3d = view_coordinates.from_other(&image_view_coordinates()); + // Our interpretation of the pinhole camera implies that the axis semantics, i.e. ViewCoordinates, + // determine how the image plane is oriented. + // (see also `CamerasPart` where the frustum lines are set up) + let obj_from_image_plane3d = view_coordinates.from_other(&image_view_coordinates()); - glam::Affine3A::from_mat3(obj_from_image_plane3d) * image_plane3d_from_2d_content + glam::Affine3A::from_mat3(obj_from_image_plane3d) * image_plane3d_from_2d_content - // Above calculation is nice for a certain kind of visualizing a projected image plane, - // but the image plane distance is arbitrary and there might be other, better visualizations! + // Above calculation is nice for a certain kind of visualizing a projected image plane, + // but the image plane distance is arbitrary and there might be other, better visualizations! - // TODO(#1025): - // As such we don't ever want to invert this matrix! - // However, currently our 2D views require do to exactly that since we're forced to - // build a relationship between the 2D plane and the 3D world, when actually the 2D plane - // should have infinite depth! - // The inverse of this matrix *is* working for this, but quickly runs into precision issues. - // See also `ui_2d.rs#setup_target_config` - }) + // TODO(#1025): + // As such we don't ever want to invert this matrix! + // However, currently our 2D views require do to exactly that since we're forced to + // build a relationship between the 2D plane and the 3D world, when actually the 2D plane + // should have infinite depth! + // The inverse of this matrix *is* working for this, but quickly runs into precision issues. + // See also `ui_2d.rs#setup_target_config` } /// Resolved transforms at an entity. #[derive(Default)] -struct TransformsAtEntity { - parent_from_entity_tree_transform: Option, - entity_from_instance_poses: Vec, +struct TransformsAtEntity<'a> { + parent_from_entity_tree_transform: glam::Affine3A, + entity_from_instance_poses: &'a [glam::Affine3A], instance_from_pinhole_image_plane: Option, } -fn transforms_at( +fn transforms_at<'a>( entity_path: &EntityPath, - entity_db: &EntityDb, query: &LatestAtQuery, pinhole_image_plane_distance: impl Fn(&EntityPath) -> f32, encountered_pinhole: &mut Option, -) -> Result { + transforms_per_timeline: &'a CachedTransformsPerTimeline, +) -> TransformsAtEntity<'a> { // This is called very frequently, don't put a profile scope here. - let potential_transform_components = - TransformComponentTrackerStoreSubscriber::access(&entity_db.store_id(), |tracker| { - tracker.potential_transform_components(entity_path).cloned() - }) - .flatten() - .unwrap_or_default(); - - let parent_from_entity_tree_transform = if potential_transform_components.transform3d.is_empty() - { - None - } else { - query_and_resolve_tree_transform_at_entity( - entity_path, - entity_db, - query, - potential_transform_components.transform3d.iter().copied(), - ) - }; - let entity_from_instance_poses = if potential_transform_components.pose3d.is_empty() { - Vec::new() - } else { - query_and_resolve_instance_poses_at_entity( - entity_path, - entity_db, - query, - potential_transform_components.pose3d.iter().copied(), - ) - }; - let instance_from_pinhole_image_plane = if potential_transform_components.pinhole { - query_and_resolve_obj_from_pinhole_image_plane( - entity_path, - entity_db, - query, - pinhole_image_plane_distance, - ) - } else { - None + let Some(entity_transforms) = transforms_per_timeline.entity_transforms(entity_path.hash()) + else { + return TransformsAtEntity::default(); }; + let parent_from_entity_tree_transform = entity_transforms.latest_at_tree_transform(query); + let entity_from_instance_poses = entity_transforms.latest_at_instance_poses(query); + let instance_from_pinhole_image_plane = + entity_transforms + .latest_at_pinhole(query) + .map(|resolved_pinhole_projection| { + transform_from_pinhole_with_image_plane( + entity_path, + resolved_pinhole_projection, + pinhole_image_plane_distance, + ) + }); + let transforms_at_entity = TransformsAtEntity { parent_from_entity_tree_transform, entity_from_instance_poses, @@ -809,12 +638,8 @@ fn transforms_at( .instance_from_pinhole_image_plane .is_some() { - if encountered_pinhole.is_some() { - return Err(UnreachableTransformReason::NestedPinholeCameras); - } else { - *encountered_pinhole = Some(entity_path.clone()); - } + *encountered_pinhole = Some(entity_path.clone()); } - Ok(transforms_at_entity) + transforms_at_entity } diff --git a/crates/viewer/re_view_spatial/src/lib.rs b/crates/viewer/re_view_spatial/src/lib.rs index 62cf77783d4f..1ce80145f306 100644 --- a/crates/viewer/re_view_spatial/src/lib.rs +++ b/crates/viewer/re_view_spatial/src/lib.rs @@ -19,7 +19,6 @@ mod proc_mesh; mod scene_bounding_boxes; mod space_camera_3d; mod spatial_topology; -mod transform_component_tracker; mod ui; mod ui_2d; mod ui_3d; @@ -29,6 +28,8 @@ mod view_3d; mod view_3d_properties; mod visualizers; +mod transform_cache; + pub use view_2d::SpatialView2D; pub use view_3d::SpatialView3D; diff --git a/crates/viewer/re_view_spatial/src/transform_cache.rs b/crates/viewer/re_view_spatial/src/transform_cache.rs new file mode 100644 index 000000000000..87922ecb7eef --- /dev/null +++ b/crates/viewer/re_view_spatial/src/transform_cache.rs @@ -0,0 +1,1093 @@ +use std::collections::BTreeMap; + +use ahash::{HashMap, HashSet}; +use glam::Affine3A; +use itertools::Either; +use nohash_hasher::{IntMap, IntSet}; + +use once_cell::sync::OnceCell; +use re_chunk_store::{ + ChunkStore, ChunkStoreSubscriberHandle, LatestAtQuery, PerStoreChunkSubscriber, +}; +use re_entity_db::EntityDb; +use re_log_types::{EntityPath, EntityPathHash, StoreId, TimeInt, Timeline}; +use re_types::{ + archetypes::{self}, + components::{self}, + Archetype as _, Component, ComponentName, +}; + +/// Store subscriber that resolves all transform components at a given entity to an affine transform. +/// +/// It only handles resulting transforms individually to each entity, not how these transforms propagate in the tree. +/// For transform tree propagation see [`crate::contexts::TransformTreeContext`]. +/// +/// There are different kinds of transforms handled here: +/// * [`archetypes::Transform3D`] +/// Tree transforms that should propagate in the tree (via [`crate::contexts::TransformTreeContext`]). +/// * [`archetypes::InstancePoses3D`] +/// Instance poses that should be applied to the tree transforms (via [`crate::contexts::TransformTreeContext`]) but not propagate. +/// * [`components::PinholeProjection`] and [`components::ViewCoordinates`] +/// Pinhole projections & associated view coordinates used for visualizing cameras in 3D and embedding 2D in 3D +pub struct TransformCacheStoreSubscriber { + /// All components of [`archetypes::Transform3D`] + transform_components: IntSet, + + /// All components of [`archetypes::InstancePoses3D`] + pose_components: IntSet, + + /// All components related to pinholes (i.e. [`components::PinholeProjection`] and [`components::ViewCoordinates`]). + pinhole_components: IntSet, + + per_timeline: HashMap, +} + +impl Default for TransformCacheStoreSubscriber { + #[inline] + fn default() -> Self { + use re_types::Archetype as _; + + Self { + transform_components: archetypes::Transform3D::all_components() + .iter() + .map(|descr| descr.component_name) + .collect(), + pose_components: archetypes::InstancePoses3D::all_components() + .iter() + .map(|descr| descr.component_name) + .collect(), + pinhole_components: [ + components::PinholeProjection::name(), + components::ViewCoordinates::name(), + ] + .into_iter() + .collect(), + + per_timeline: Default::default(), + } + } +} + +bitflags::bitflags! { + /// Flags for the different kinds of independent transforms that the transform cache handles. + #[derive(Debug, Clone, Copy)] + pub struct TransformAspect: u8 { + /// The entity has a tree transform, i.e. any non-style component of [`archetypes::Transform3D`]. + const Tree = 1 << 0; + + /// The entity has instance poses, i.e. any non-style component of [`archetypes::InstancePoses3D`]. + const Pose = 1 << 1; + + /// The entity has a pinhole projection or view coordinates, i.e. either [`components::PinholeProjection`] or [`components::ViewCoordinates`]. + const PinholeOrViewCoordinates = 1 << 2; + } +} + +/// Points in time that have changed for a given entity, +/// i.e. the cache is invalid for these times. +#[derive(Debug)] +struct InvalidatedTransforms { + entity_path: EntityPath, + times: Vec, + aspects: TransformAspect, +} + +#[derive(Default)] +pub struct CachedTransformsPerTimeline { + /// Updates that should be applied to the cache. + /// I.e. times & entities at which the cache is invalid right now. + invalidated_transforms: Vec, + + per_entity: IntMap, +} + +type PoseTransformMap = BTreeMap>; + +/// Maps from time to pinhole projection. +/// +/// Unlike with tree & pose transforms, there's identity value that we can insert upon clears. +/// (clears here meaning that the user first logs a pinhole and then later either logs a clear or an empty pinhole array) +/// Therefore, we instead store those events as `None` values to ensure that everything after a clear +/// is properly marked as having no pinhole projection. +type PinholeProjectionMap = BTreeMap>; + +pub struct PerTimelinePerEntityTransforms { + timeline: Timeline, + + tree_transforms: BTreeMap, + + // Pose transforms and pinhole projections are typically more rare, which is why we store them as optional boxes. + pose_transforms: Option>, + pinhole_projections: Option>, +} + +#[derive(Clone, Debug, PartialEq)] +pub struct ResolvedPinholeProjection { + pub image_from_camera: components::PinholeProjection, + + /// View coordinates at this pinhole camera. + /// + /// This is needed to orient 2D in 3D and 3D in 2D the right way around + /// (answering questions like which axis is distance to viewer increasing). + /// If no view coordinates were logged, this is set to [`archetypes::Pinhole::DEFAULT_CAMERA_XYZ`]. + pub view_coordinates: components::ViewCoordinates, +} + +impl CachedTransformsPerTimeline { + #[inline] + pub fn entity_transforms( + &self, + entity_path: EntityPathHash, + ) -> Option<&PerTimelinePerEntityTransforms> { + self.per_entity.get(&entity_path) + } +} + +impl PerTimelinePerEntityTransforms { + #[inline] + pub fn latest_at_tree_transform(&self, query: &LatestAtQuery) -> Affine3A { + debug_assert_eq!(query.timeline(), self.timeline); + self.tree_transforms + .range(..query.at().inc()) + .next_back() + .map(|(_time, transform)| *transform) + .unwrap_or(Affine3A::IDENTITY) + } + + #[inline] + pub fn latest_at_instance_poses(&self, query: &LatestAtQuery) -> &[Affine3A] { + debug_assert_eq!(query.timeline(), self.timeline); + self.pose_transforms + .as_ref() + .and_then(|pose_transforms| pose_transforms.range(..query.at().inc()).next_back()) + .map(|(_time, pose_transforms)| pose_transforms.as_slice()) + .unwrap_or(&[]) + } + + #[inline] + pub fn latest_at_pinhole(&self, query: &LatestAtQuery) -> Option<&ResolvedPinholeProjection> { + debug_assert_eq!(query.timeline(), self.timeline); + self.pinhole_projections + .as_ref() + .and_then(|pinhole_projections| { + pinhole_projections.range(..query.at().inc()).next_back() + }) + .and_then(|(_time, projection)| projection.as_ref()) + } +} + +impl TransformCacheStoreSubscriber { + /// Accesses the global store subscriber. + /// + /// Lazily registers the subscriber if it hasn't been registered yet. + pub fn subscription_handle() -> ChunkStoreSubscriberHandle { + static SUBSCRIPTION: OnceCell = OnceCell::new(); + *SUBSCRIPTION.get_or_init(ChunkStore::register_per_store_subscriber::) + } + + /// Accesses the transform component tracking data for a given store. + #[inline] + pub fn access(store_id: &StoreId, f: impl FnMut(&Self) -> T) -> Option { + ChunkStore::with_per_store_subscriber(Self::subscription_handle(), store_id, f) + } + + /// Accesses the transform component tracking data for a given store exclusively. + #[inline] + pub fn access_mut(store_id: &StoreId, f: impl FnMut(&mut Self) -> T) -> Option { + ChunkStore::with_per_store_subscriber_mut(Self::subscription_handle(), store_id, f) + } + + /// Accesses the transform component tracking data for a given timeline. + /// + /// Returns `None` if the timeline doesn't have any transforms at all. + #[inline] + pub fn transforms_per_timeline( + &self, + timeline: Timeline, + ) -> Option<&CachedTransformsPerTimeline> { + self.per_timeline.get(&timeline) + } + + /// Makes sure the transform cache is up to date with the latest data. + /// + /// This needs to be called once per frame prior to any transform propagation. + /// (which is done by [`crate::contexts::TransformTreeContext`]) + pub fn apply_all_updates(&mut self, entity_db: &EntityDb) { + re_tracing::profile_function!(); + + for (timeline, per_timeline) in &mut self.per_timeline { + for invalidated_transform in per_timeline.invalidated_transforms.drain(..) { + let entity_path = &invalidated_transform.entity_path; + let entity_entry = per_timeline + .per_entity + .entry(entity_path.hash()) + .or_insert_with(|| PerTimelinePerEntityTransforms { + timeline: *timeline, + tree_transforms: Default::default(), + pose_transforms: Default::default(), + pinhole_projections: Default::default(), + }); + + for time in invalidated_transform.times { + let query = LatestAtQuery::new(*timeline, time); + + if invalidated_transform + .aspects + .contains(TransformAspect::Tree) + { + let transform = query_and_resolve_tree_transform_at_entity( + entity_path, + entity_db, + &query, + ) + .unwrap_or(Affine3A::IDENTITY); + // If there's *no* transform, we have to put identity in, otherwise we'd miss clears! + entity_entry.tree_transforms.insert(time, transform); + } + if invalidated_transform + .aspects + .contains(TransformAspect::Pose) + { + let poses = query_and_resolve_instance_poses_at_entity( + entity_path, + entity_db, + &query, + ); + // *do* also insert empty ones, otherwise it's not possible to clear previous state. + entity_entry + .pose_transforms + .get_or_insert_with(Box::default) + .insert(time, poses); + } + if invalidated_transform + .aspects + .contains(TransformAspect::PinholeOrViewCoordinates) + { + let pinhole_projection = query_and_resolve_pinhole_projection_at_entity( + entity_path, + entity_db, + &query, + ); + // `None` values need to be inserted as well to clear out previous state. + // See also doc string on `PinholeProjectionMap`. + entity_entry + .pinhole_projections + .get_or_insert_with(Box::default) + .insert(time, pinhole_projection); + } + } + } + } + } + + fn add_chunk(&mut self, event: &re_chunk_store::ChunkStoreEvent, aspects: TransformAspect) { + let entity_path = event.chunk.entity_path(); + + for (timeline, time_column) in event.diff.chunk.timelines() { + let per_timeline = self.per_timeline.entry(*timeline).or_default(); + + // All of these require complex latest-at queries that would require a lot more context, + // are fairly expensive, and may depend on other components that may come in at the same time. + // (we could inject that here, but it's not entirely straight forward). + // So instead, we note down that the caches is invalidated for the given entity & times. + + // This invalidates any time _after_ the first event in this chunk. + // (e.g. if a rotation is added prior to translations later on, + // then the resulting transforms at those translations changes as well for latest-at queries) + let mut invalidated_times = Vec::new(); + let Some(min_time) = time_column.times().min() else { + continue; + }; + if let Some(entity_entry) = per_timeline.per_entity.get_mut(&entity_path.hash()) { + if aspects.contains(TransformAspect::Tree) { + let invalidated_tree_transforms = + entity_entry.tree_transforms.split_off(&min_time); + invalidated_times.extend(invalidated_tree_transforms.into_keys()); + } + if aspects.contains(TransformAspect::Pose) { + if let Some(pose_transforms) = &mut entity_entry.pose_transforms { + let invalidated_pose_transforms = pose_transforms.split_off(&min_time); + invalidated_times.extend(invalidated_pose_transforms.into_keys()); + } + } + if aspects.contains(TransformAspect::PinholeOrViewCoordinates) { + if let Some(pinhole_projections) = &mut entity_entry.pinhole_projections { + let invalidated_pinhole_projections = + pinhole_projections.split_off(&min_time); + invalidated_times.extend(invalidated_pinhole_projections.into_keys()); + } + } + } + + per_timeline + .invalidated_transforms + .push(InvalidatedTransforms { + entity_path: entity_path.clone(), + times: time_column + .times() + .chain(invalidated_times.into_iter()) + .collect(), + aspects, + }); + } + } + + fn remove_chunk(&mut self, event: &re_chunk_store::ChunkStoreEvent, aspects: TransformAspect) { + let entity_path = event.chunk.entity_path(); + + for (timeline, time_column) in event.diff.chunk.timelines() { + let Some(per_timeline) = self.per_timeline.get_mut(timeline) else { + continue; + }; + + // Remove incoming data. + for invalidated_transform in per_timeline + .invalidated_transforms + .iter_mut() + .filter(|invalidated_transform| &invalidated_transform.entity_path == entity_path) + { + let times = time_column.times().collect::>(); + invalidated_transform + .times + .retain(|time| !times.contains(time)); + } + per_timeline + .invalidated_transforms + .retain(|invalidated_transform| !invalidated_transform.times.is_empty()); + + // Remove existing data. + if let Some(per_entity) = per_timeline.per_entity.get_mut(&entity_path.hash()) { + for time in time_column.times() { + if aspects.contains(TransformAspect::Tree) { + per_entity.tree_transforms.remove(&time); + } + if aspects.contains(TransformAspect::Pose) { + if let Some(pose_transforms) = &mut per_entity.pose_transforms { + pose_transforms.remove(&time); + } + } + if aspects.contains(TransformAspect::PinholeOrViewCoordinates) { + if let Some(pinhole_projections) = &mut per_entity.pinhole_projections { + pinhole_projections.remove(&time); + } + } + } + + if per_entity.tree_transforms.is_empty() + && per_entity + .pose_transforms + .as_ref() + .map_or(true, |pose_transforms| pose_transforms.is_empty()) + && per_entity + .pinhole_projections + .as_ref() + .map_or(true, |pinhole_projections| pinhole_projections.is_empty()) + { + per_timeline.per_entity.remove(&entity_path.hash()); + } + } + + if per_timeline.per_entity.is_empty() && per_timeline.invalidated_transforms.is_empty() + { + self.per_timeline.remove(timeline); + } + } + } +} + +impl PerStoreChunkSubscriber for TransformCacheStoreSubscriber { + fn name() -> String { + "rerun.TransformCacheStoreSubscriber".to_owned() + } + + fn on_events<'a>(&mut self, events: impl Iterator) { + re_tracing::profile_function!(); + + for event in events { + // The components we are interested in may only show up on some of the timelines + // within this chunk, so strictly speaking the affected "aspects" we compute here are conservative. + // But that's fairly rare, so a few false positive entries here are fine. + let mut aspects = TransformAspect::empty(); + for component_name in event.chunk.component_names() { + if self.transform_components.contains(&component_name) { + aspects |= TransformAspect::Tree; + } + if self.pose_components.contains(&component_name) { + aspects |= TransformAspect::Pose; + } + if self.pinhole_components.contains(&component_name) { + aspects |= TransformAspect::PinholeOrViewCoordinates; + } + } + if aspects.is_empty() { + continue; + } + + if event.kind == re_chunk_store::ChunkStoreDiffKind::Deletion { + self.remove_chunk(event, aspects); + } else { + self.add_chunk(event, aspects); + } + } + } +} + +/// Queries all components that are part of pose transforms, returning the transform from child to parent. +/// +/// If any of the components yields an invalid transform, returns a `glam::Affine3A::ZERO`. +/// (this effectively disconnects a subtree from the transform hierarchy!) +// TODO(#3849): There's no way to discover invalid transforms right now (they can be intentional but often aren't). +fn query_and_resolve_tree_transform_at_entity( + entity_path: &EntityPath, + entity_db: &EntityDb, + query: &LatestAtQuery, +) -> Option { + // TODO(andreas): Filter out styling components. + let components = archetypes::Transform3D::all_components(); + let component_names = components.iter().map(|descr| descr.component_name); + let results = entity_db.latest_at(query, entity_path, component_names); + if results.components.is_empty() { + return None; + } + + let mut transform = Affine3A::IDENTITY; + + // It's an error if there's more than one component. Warn in that case. + let mono_log_level = re_log::Level::Warn; + + // The order of the components here is important, and checked by `debug_assert_transform_field_order` + if let Some(translation) = + results.component_mono_with_log_level::(mono_log_level) + { + transform = Affine3A::from(translation); + } + if let Some(axis_angle) = + results.component_mono_with_log_level::(mono_log_level) + { + if let Ok(axis_angle) = Affine3A::try_from(axis_angle) { + transform *= axis_angle; + } else { + return Some(Affine3A::ZERO); + } + } + if let Some(quaternion) = + results.component_mono_with_log_level::(mono_log_level) + { + if let Ok(quaternion) = Affine3A::try_from(quaternion) { + transform *= quaternion; + } else { + return Some(Affine3A::ZERO); + } + } + if let Some(scale) = + results.component_mono_with_log_level::(mono_log_level) + { + if scale.x() == 0.0 && scale.y() == 0.0 && scale.z() == 0.0 { + return Some(Affine3A::ZERO); + } + transform *= Affine3A::from(scale); + } + if let Some(mat3x3) = + results.component_mono_with_log_level::(mono_log_level) + { + let affine_transform = Affine3A::from(mat3x3); + if affine_transform.matrix3.determinant() == 0.0 { + return Some(Affine3A::ZERO); + } + transform *= affine_transform; + } + + if results.component_mono_with_log_level::(mono_log_level) + == Some(components::TransformRelation::ChildFromParent) + { + let determinant = transform.matrix3.determinant(); + if determinant != 0.0 && determinant.is_finite() { + transform = transform.inverse(); + } else { + // All "regular invalid" transforms should have been caught. + // So ending up here means something else went wrong? + re_log::warn_once!( + "Failed to express child-from-parent transform at {} since it wasn't invertible", + entity_path, + ); + } + } + + Some(transform) +} + +/// Queries all components that are part of pose transforms, returning the transform from child to parent. +/// +/// If any of the components yields an invalid transform, returns a `glam::Affine3A::ZERO` for that instance. +/// (this effectively ignores the instance for most visualizations!) +// TODO(#3849): There's no way to discover invalid transforms right now (they can be intentional but often aren't). +fn query_and_resolve_instance_poses_at_entity( + entity_path: &EntityPath, + entity_db: &EntityDb, + query: &LatestAtQuery, +) -> Vec { + // TODO(andreas): Filter out styling components. + let components = archetypes::InstancePoses3D::all_components(); + let component_names = components.iter().map(|descr| descr.component_name); + let result = entity_db.latest_at(query, entity_path, component_names); + + let max_num_instances = result + .components + .iter() + .map(|(name, row)| row.num_instances(name)) + .max() + .unwrap_or(0) as usize; + + if max_num_instances == 0 { + return Vec::new(); + } + + #[inline] + pub fn clamped_or_nothing( + values: Vec, + clamped_len: usize, + ) -> impl Iterator { + let Some(last) = values.last() else { + return Either::Left(std::iter::empty()); + }; + let last = last.clone(); + Either::Right( + values + .into_iter() + .chain(std::iter::repeat(last)) + .take(clamped_len), + ) + } + + let batch_translation = result + .component_batch::() + .unwrap_or_default(); + let batch_rotation_quat = result + .component_batch::() + .unwrap_or_default(); + let batch_rotation_axis_angle = result + .component_batch::() + .unwrap_or_default(); + let batch_scale = result + .component_batch::() + .unwrap_or_default(); + let batch_mat3x3 = result + .component_batch::() + .unwrap_or_default(); + + if batch_translation.is_empty() + && batch_rotation_quat.is_empty() + && batch_rotation_axis_angle.is_empty() + && batch_scale.is_empty() + && batch_mat3x3.is_empty() + { + return Vec::new(); + } + let mut iter_translation = clamped_or_nothing(batch_translation, max_num_instances); + let mut iter_rotation_quat = clamped_or_nothing(batch_rotation_quat, max_num_instances); + let mut iter_rotation_axis_angle = + clamped_or_nothing(batch_rotation_axis_angle, max_num_instances); + let mut iter_scale = clamped_or_nothing(batch_scale, max_num_instances); + let mut iter_mat3x3 = clamped_or_nothing(batch_mat3x3, max_num_instances); + + (0..max_num_instances) + .map(|_| { + // We apply these in a specific order - see `debug_assert_transform_field_order` + let mut transform = Affine3A::IDENTITY; + if let Some(translation) = iter_translation.next() { + transform = Affine3A::from(translation); + } + if let Some(rotation_quat) = iter_rotation_quat.next() { + if let Ok(rotation_quat) = Affine3A::try_from(rotation_quat) { + transform *= rotation_quat; + } else { + transform = Affine3A::ZERO; + } + } + if let Some(rotation_axis_angle) = iter_rotation_axis_angle.next() { + if let Ok(axis_angle) = Affine3A::try_from(rotation_axis_angle) { + transform *= axis_angle; + } else { + transform = Affine3A::ZERO; + } + } + if let Some(scale) = iter_scale.next() { + transform *= Affine3A::from(scale); + } + if let Some(mat3x3) = iter_mat3x3.next() { + transform *= Affine3A::from(mat3x3); + } + transform + }) + .collect() +} + +fn query_and_resolve_pinhole_projection_at_entity( + entity_path: &EntityPath, + entity_db: &EntityDb, + query: &LatestAtQuery, +) -> Option { + entity_db + .latest_at_component::(entity_path, query) + .map(|(_index, image_from_camera)| ResolvedPinholeProjection { + image_from_camera, + view_coordinates: entity_db + .latest_at_component::(entity_path, query) + .map_or(archetypes::Pinhole::DEFAULT_CAMERA_XYZ, |(_index, res)| res), + }) +} + +#[cfg(test)] +mod tests { + use std::sync::Arc; + + use re_chunk_store::{ + external::re_chunk::ChunkBuilder, ChunkId, GarbageCollectionOptions, RowId, + }; + use re_types::{archetypes, Loggable, SerializedComponentBatch}; + + use super::*; + + fn ensure_subscriber_registered(entity_db: &EntityDb) { + TransformCacheStoreSubscriber::access(&entity_db.store_id(), |_| { + // Make sure the subscriber is registered. + }); + } + + #[test] + fn test_transforms_per_timeline_access() { + let mut entity_db = EntityDb::new(StoreId::random(re_log_types::StoreKind::Recording)); + ensure_subscriber_registered(&entity_db); + + // Log a few tree transforms at different times. + let timeline = Timeline::new_sequence("t"); + let chunk0 = ChunkBuilder::new(ChunkId::new(), EntityPath::from("with_transform")) + .with_archetype( + RowId::new(), + [(timeline, 1)], + &archetypes::Transform3D::from_translation([1.0, 2.0, 3.0]), + ) + .build() + .unwrap(); + let chunk1 = ChunkBuilder::new(ChunkId::new(), EntityPath::from("without_transform")) + .with_archetype( + RowId::new(), + [(timeline, 1)], + // Anything that doesn't have components the transform cache is interested in. + &archetypes::Points3D::new([[1.0, 2.0, 3.0]]), + ) + .build() + .unwrap(); + entity_db.add_chunk(&Arc::new(chunk0)).unwrap(); + entity_db.add_chunk(&Arc::new(chunk1)).unwrap(); + + TransformCacheStoreSubscriber::access_mut(&entity_db.store_id(), |cache| { + cache.apply_all_updates(&entity_db); + let transforms_per_timeline = cache.transforms_per_timeline(timeline).unwrap(); + assert!(transforms_per_timeline + .entity_transforms(EntityPath::from("without_transform").hash()) + .is_none()); + assert!(transforms_per_timeline + .entity_transforms(EntityPath::from("rando").hash()) + .is_none()); + let transforms = transforms_per_timeline + .entity_transforms(EntityPath::from("with_transform").hash()) + .unwrap(); + assert_eq!(transforms.timeline, timeline); + assert_eq!(transforms.tree_transforms.len(), 1); + assert_eq!(transforms.pose_transforms, None); + assert_eq!(transforms.pinhole_projections, None); + }); + } + + #[test] + fn test_tree_transforms() { + let mut entity_db = EntityDb::new(StoreId::random(re_log_types::StoreKind::Recording)); + ensure_subscriber_registered(&entity_db); + + // Log a few tree transforms at different times. + let timeline = Timeline::new_sequence("t"); + let chunk = ChunkBuilder::new(ChunkId::new(), EntityPath::from("my_entity")) + .with_archetype( + RowId::new(), + [(timeline, 1)], + &archetypes::Transform3D::from_translation([1.0, 2.0, 3.0]), + ) + .with_archetype( + RowId::new(), + [(timeline, 3)], + &archetypes::Transform3D::update_fields().with_scale([1.0, 2.0, 3.0]), + ) + .with_archetype( + RowId::new(), + [(timeline, 4)], + &archetypes::Transform3D::from_rotation(glam::Quat::from_rotation_x(1.0)), + ) + .with_archetype( + RowId::new(), + [(timeline, 5)], + &archetypes::Transform3D::clear_fields(), + ) + .build() + .unwrap(); + entity_db.add_chunk(&Arc::new(chunk)).unwrap(); + + // Check that the transform cache has the expected transforms. + TransformCacheStoreSubscriber::access_mut(&entity_db.store_id(), |cache| { + cache.apply_all_updates(&entity_db); + let transforms_per_timeline = cache.transforms_per_timeline(timeline).unwrap(); + let transforms = transforms_per_timeline + .entity_transforms(EntityPath::from("my_entity").hash()) + .unwrap(); + + assert_eq!( + transforms.latest_at_tree_transform(&LatestAtQuery::new(timeline, 0)), + glam::Affine3A::IDENTITY + ); + assert_eq!( + transforms.latest_at_tree_transform(&LatestAtQuery::new(timeline, 1)), + glam::Affine3A::from_translation(glam::Vec3::new(1.0, 2.0, 3.0)) + ); + assert_eq!( + transforms.latest_at_tree_transform(&LatestAtQuery::new(timeline, 2)), + glam::Affine3A::from_translation(glam::Vec3::new(1.0, 2.0, 3.0)) + ); + assert_eq!( + transforms.latest_at_tree_transform(&LatestAtQuery::new(timeline, 3)), + glam::Affine3A::from_scale_rotation_translation( + glam::Vec3::new(1.0, 2.0, 3.0), + glam::Quat::IDENTITY, + glam::Vec3::new(1.0, 2.0, 3.0), + ) + ); + assert_eq!( + transforms.latest_at_tree_transform(&LatestAtQuery::new(timeline, 4)), + glam::Affine3A::from_quat(glam::Quat::from_rotation_x(1.0)) + ); + assert_eq!( + transforms.latest_at_tree_transform(&LatestAtQuery::new(timeline, 5)), + glam::Affine3A::IDENTITY + ); + assert_eq!( + transforms.latest_at_tree_transform(&LatestAtQuery::new(timeline, 123)), + glam::Affine3A::IDENTITY + ); + }); + } + + #[test] + fn test_pose_transforms() { + let mut entity_db = EntityDb::new(StoreId::random(re_log_types::StoreKind::Recording)); + ensure_subscriber_registered(&entity_db); + + // Log a few tree transforms at different times. + let timeline = Timeline::new_sequence("t"); + let chunk = ChunkBuilder::new(ChunkId::new(), EntityPath::from("my_entity")) + .with_archetype( + RowId::new(), + [(timeline, 1)], + &archetypes::InstancePoses3D::new().with_translations([ + [1.0, 2.0, 3.0], + [4.0, 5.0, 6.0], + [7.0, 8.0, 9.0], + ]), + ) + .with_archetype( + RowId::new(), + [(timeline, 3)], + // Less instances, and a splatted scale. + &archetypes::InstancePoses3D::new() + .with_translations([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) + .with_scales([[2.0, 3.0, 4.0]]), + ) + .with_serialized_batches( + RowId::new(), + [(timeline, 4)], + [ + SerializedComponentBatch::new( + arrow::array::new_empty_array(&components::Translation3D::arrow_datatype()), + archetypes::InstancePoses3D::descriptor_translations(), + ), + SerializedComponentBatch::new( + arrow::array::new_empty_array(&components::Scale3D::arrow_datatype()), + archetypes::InstancePoses3D::descriptor_scales(), + ), + ], + ) + // TODO(#7245): Use this instead of the above + // .with_archetype( + // RowId::new(), + // [(timeline, 4)], + // &archetypes::InstancePoses3D::clear_fields(), + // ) + .build() + .unwrap(); + entity_db.add_chunk(&Arc::new(chunk)).unwrap(); + + // Check that the transform cache has the expected transforms. + TransformCacheStoreSubscriber::access_mut(&entity_db.store_id(), |cache| { + cache.apply_all_updates(&entity_db); + let transforms_per_timeline = cache.transforms_per_timeline(timeline).unwrap(); + let transforms = transforms_per_timeline + .entity_transforms(EntityPath::from("my_entity").hash()) + .unwrap(); + + assert_eq!( + transforms.latest_at_instance_poses(&LatestAtQuery::new(timeline, 0)), + &[] + ); + assert_eq!( + transforms.latest_at_instance_poses(&LatestAtQuery::new(timeline, 1)), + &[ + glam::Affine3A::from_translation(glam::Vec3::new(1.0, 2.0, 3.0)), + glam::Affine3A::from_translation(glam::Vec3::new(4.0, 5.0, 6.0)), + glam::Affine3A::from_translation(glam::Vec3::new(7.0, 8.0, 9.0)), + ] + ); + assert_eq!( + transforms.latest_at_instance_poses(&LatestAtQuery::new(timeline, 2)), + &[ + glam::Affine3A::from_translation(glam::Vec3::new(1.0, 2.0, 3.0)), + glam::Affine3A::from_translation(glam::Vec3::new(4.0, 5.0, 6.0)), + glam::Affine3A::from_translation(glam::Vec3::new(7.0, 8.0, 9.0)), + ] + ); + assert_eq!( + transforms.latest_at_instance_poses(&LatestAtQuery::new(timeline, 3)), + &[ + glam::Affine3A::from_scale_rotation_translation( + glam::Vec3::new(2.0, 3.0, 4.0), + glam::Quat::IDENTITY, + glam::Vec3::new(1.0, 2.0, 3.0), + ), + glam::Affine3A::from_scale_rotation_translation( + glam::Vec3::new(2.0, 3.0, 4.0), + glam::Quat::IDENTITY, + glam::Vec3::new(4.0, 5.0, 6.0), + ), + ] + ); + assert_eq!( + transforms.latest_at_instance_poses(&LatestAtQuery::new(timeline, 4)), + &[] + ); + assert_eq!( + transforms.latest_at_instance_poses(&LatestAtQuery::new(timeline, 123)), + &[] + ); + }); + } + + #[test] + fn test_pinhole_projections() { + let mut entity_db = EntityDb::new(StoreId::random(re_log_types::StoreKind::Recording)); + ensure_subscriber_registered(&entity_db); + + let image_from_camera = + components::PinholeProjection::from_focal_length_and_principal_point( + [1.0, 2.0], + [1.0, 2.0], + ); + + // Log a few tree transforms at different times. + let timeline = Timeline::new_sequence("t"); + let chunk = ChunkBuilder::new(ChunkId::new(), EntityPath::from("my_entity")) + .with_archetype( + RowId::new(), + [(timeline, 1)], + &archetypes::Pinhole::new(image_from_camera), + ) + .with_archetype( + RowId::new(), + [(timeline, 3)], + &archetypes::ViewCoordinates::BLU, + ) + // Clear out the pinhole projection (this should yield nothing then for the remaining view coordinates.) + .with_serialized_batch( + RowId::new(), + [(timeline, 4)], + SerializedComponentBatch::new( + arrow::array::new_empty_array(&components::PinholeProjection::arrow_datatype()), + archetypes::Pinhole::descriptor_image_from_camera(), + ), + ) + // TODO(#7245): Use this instead + // .with_archetype( + // RowId::new(), + // [(timeline, 4)], + // &archetypes::Pinhole::clear_fields(), + // ) + .build() + .unwrap(); + entity_db.add_chunk(&Arc::new(chunk)).unwrap(); + + // Check that the transform cache has the expected transforms. + TransformCacheStoreSubscriber::access_mut(&entity_db.store_id(), |cache| { + cache.apply_all_updates(&entity_db); + let transforms_per_timeline = cache.transforms_per_timeline(timeline).unwrap(); + let transforms = transforms_per_timeline + .entity_transforms(EntityPath::from("my_entity").hash()) + .unwrap(); + + assert_eq!( + transforms.latest_at_pinhole(&LatestAtQuery::new(timeline, 0)), + None + ); + assert_eq!( + transforms.latest_at_pinhole(&LatestAtQuery::new(timeline, 1)), + Some(&ResolvedPinholeProjection { + image_from_camera, + view_coordinates: archetypes::Pinhole::DEFAULT_CAMERA_XYZ, + }) + ); + assert_eq!( + transforms.latest_at_pinhole(&LatestAtQuery::new(timeline, 2)), + Some(&ResolvedPinholeProjection { + image_from_camera, + view_coordinates: archetypes::Pinhole::DEFAULT_CAMERA_XYZ, + }) + ); + assert_eq!( + transforms.latest_at_pinhole(&LatestAtQuery::new(timeline, 3)), + Some(&ResolvedPinholeProjection { + image_from_camera, + view_coordinates: components::ViewCoordinates::BLU, + }) + ); + assert_eq!( + transforms.latest_at_pinhole(&LatestAtQuery::new(timeline, 4)), + None // View coordinates alone doesn't give us a pinhole projection from the transform cache. + ); + assert_eq!( + transforms.latest_at_pinhole(&LatestAtQuery::new(timeline, 123)), + None + ); + }); + } + + #[test] + fn test_out_of_order_updates() { + let mut entity_db = EntityDb::new(StoreId::random(re_log_types::StoreKind::Recording)); + ensure_subscriber_registered(&entity_db); + + // Log a few tree transforms at different times. + let timeline = Timeline::new_sequence("t"); + let chunk = ChunkBuilder::new(ChunkId::new(), EntityPath::from("my_entity")) + .with_archetype( + RowId::new(), + [(timeline, 1)], + &archetypes::Transform3D::from_translation([1.0, 2.0, 3.0]), + ) + .with_archetype( + RowId::new(), + [(timeline, 3)], + // Note that this doesn't clear anything that could be inserted at time 2. + &archetypes::Transform3D::update_fields().with_translation([2.0, 3.0, 4.0]), + ) + .build() + .unwrap(); + entity_db.add_chunk(&Arc::new(chunk)).unwrap(); + + // Check that the transform cache has the expected transforms. + TransformCacheStoreSubscriber::access_mut(&entity_db.store_id(), |cache| { + cache.apply_all_updates(&entity_db); + let transforms_per_timeline = cache.transforms_per_timeline(timeline).unwrap(); + let transforms = transforms_per_timeline + .entity_transforms(EntityPath::from("my_entity").hash()) + .unwrap(); + + // Check that the transform cache has the expected transforms. + assert_eq!( + transforms.latest_at_tree_transform(&LatestAtQuery::new(timeline, 1)), + glam::Affine3A::from_translation(glam::Vec3::new(1.0, 2.0, 3.0)) + ); + assert_eq!( + transforms.latest_at_tree_transform(&LatestAtQuery::new(timeline, 3)), + glam::Affine3A::from_translation(glam::Vec3::new(2.0, 3.0, 4.0)) + ); + }); + + // Add a transform between the two that invalidates the one at time stamp 3. + let timeline = Timeline::new_sequence("t"); + let chunk = ChunkBuilder::new(ChunkId::new(), EntityPath::from("my_entity")) + .with_archetype( + RowId::new(), + [(timeline, 2)], + &archetypes::Transform3D::update_fields().with_scale([-1.0, -2.0, -3.0]), + ) + .build() + .unwrap(); + entity_db.add_chunk(&Arc::new(chunk)).unwrap(); + + // Check that the transform cache has the expected changed transforms. + TransformCacheStoreSubscriber::access_mut(&entity_db.store_id(), |cache| { + cache.apply_all_updates(&entity_db); + let transforms_per_timeline = cache.transforms_per_timeline(timeline).unwrap(); + let transforms = transforms_per_timeline + .entity_transforms(EntityPath::from("my_entity").hash()) + .unwrap(); + + // Check that the transform cache has the expected transforms. + assert_eq!( + transforms.latest_at_tree_transform(&LatestAtQuery::new(timeline, 1)), + glam::Affine3A::from_translation(glam::Vec3::new(1.0, 2.0, 3.0)) + ); + assert_eq!( + transforms.latest_at_tree_transform(&LatestAtQuery::new(timeline, 2)), + glam::Affine3A::from_scale_rotation_translation( + glam::Vec3::new(-1.0, -2.0, -3.0), + glam::Quat::IDENTITY, + glam::Vec3::new(1.0, 2.0, 3.0), + ) + ); + assert_eq!( + transforms.latest_at_tree_transform(&LatestAtQuery::new(timeline, 3)), + glam::Affine3A::from_scale_rotation_translation( + glam::Vec3::new(-1.0, -2.0, -3.0), + glam::Quat::IDENTITY, + glam::Vec3::new(2.0, 3.0, 4.0), + ) + ); + }); + } + + #[test] + fn test_gc() { + let mut entity_db = EntityDb::new(StoreId::random(re_log_types::StoreKind::Recording)); + ensure_subscriber_registered(&entity_db); + + let timeline = Timeline::new_sequence("t"); + let chunk = ChunkBuilder::new(ChunkId::new(), EntityPath::from("my_entity0")) + .with_archetype( + RowId::new(), + [(timeline, 1)], + &archetypes::Transform3D::from_translation([1.0, 2.0, 3.0]), + ) + .build() + .unwrap(); + entity_db.add_chunk(&Arc::new(chunk)).unwrap(); + + // Apply some updates to the transform before GC pass. + TransformCacheStoreSubscriber::access_mut(&entity_db.store_id(), |cache| { + cache.apply_all_updates(&entity_db); + }); + + let chunk = ChunkBuilder::new(ChunkId::new(), EntityPath::from("my_entity1")) + .with_archetype( + RowId::new(), + [(timeline, 2)], + &archetypes::Transform3D::from_translation([4.0, 5.0, 6.0]), + ) + .build() + .unwrap(); + entity_db.add_chunk(&Arc::new(chunk)).unwrap(); + + // Don't apply updates for this chunk. + + entity_db.gc(&GarbageCollectionOptions::gc_everything()); + + TransformCacheStoreSubscriber::access_mut(&entity_db.store_id(), |cache| { + assert!(cache.transforms_per_timeline(timeline).is_none()); + }); + } +} diff --git a/crates/viewer/re_view_spatial/src/transform_component_tracker.rs b/crates/viewer/re_view_spatial/src/transform_component_tracker.rs deleted file mode 100644 index 7f6b564f10f6..000000000000 --- a/crates/viewer/re_view_spatial/src/transform_component_tracker.rs +++ /dev/null @@ -1,139 +0,0 @@ -use once_cell::sync::OnceCell; - -use nohash_hasher::{IntMap, IntSet}; -use re_chunk_store::{ - ChunkStore, ChunkStoreDiffKind, ChunkStoreEvent, ChunkStoreSubscriberHandle, - PerStoreChunkSubscriber, -}; -use re_log_types::{EntityPath, EntityPathHash, StoreId}; -use re_types::{Component as _, ComponentName}; - -// --- - -/// Set of components that an entity ever had over its known lifetime. -#[derive(Default, Clone)] -pub struct PotentialTransformComponentSet { - /// All transform components ever present. - pub transform3d: IntSet, - - /// All pose transform components ever present. - pub pose3d: IntSet, - - /// Whether the entity ever had a pinhole camera. - pub pinhole: bool, -} - -/// Keeps track of which entities have had any `Transform3D`-related data on any timeline at any -/// point in time. -/// -/// This is used to optimize queries in the `TransformContext`, so that we don't unnecessarily pay -/// for the fixed overhead of all the query layers when we know for a fact that there won't be any -/// data there. -/// This is a huge performance improvement in practice, especially in recordings with many entities. -pub struct TransformComponentTrackerStoreSubscriber { - /// The components of interest. - transform_components: IntSet, - pose_components: IntSet, - - components_per_entity: IntMap, -} - -impl Default for TransformComponentTrackerStoreSubscriber { - #[inline] - fn default() -> Self { - use re_types::Archetype as _; - Self { - transform_components: re_types::archetypes::Transform3D::all_components() - .iter() - .map(|descr| descr.component_name) - .collect(), - pose_components: re_types::archetypes::InstancePoses3D::all_components() - .iter() - .map(|descr| descr.component_name) - .collect(), - components_per_entity: Default::default(), - } - } -} - -impl TransformComponentTrackerStoreSubscriber { - /// Accesses the global store subscriber. - /// - /// Lazily registers the subscriber if it hasn't been registered yet. - pub fn subscription_handle() -> ChunkStoreSubscriberHandle { - static SUBSCRIPTION: OnceCell = OnceCell::new(); - *SUBSCRIPTION.get_or_init(ChunkStore::register_per_store_subscriber::) - } - - /// Accesses the transform component tracking data for a given store. - #[inline] - pub fn access(store_id: &StoreId, f: impl FnOnce(&Self) -> T) -> Option { - ChunkStore::with_per_store_subscriber_once(Self::subscription_handle(), store_id, f) - } - - pub fn potential_transform_components( - &self, - entity_path: &EntityPath, - ) -> Option<&PotentialTransformComponentSet> { - self.components_per_entity.get(&entity_path.hash()) - } -} - -impl PerStoreChunkSubscriber for TransformComponentTrackerStoreSubscriber { - #[inline] - fn name() -> String { - "rerun.store_subscriber.TransformComponentTracker".into() - } - - fn on_events<'a>(&mut self, events: impl Iterator) { - re_tracing::profile_function!(); - - for event in events - // This is only additive, don't care about removals. - .filter(|e| e.kind == ChunkStoreDiffKind::Addition) - { - let entity_path_hash = event.chunk.entity_path().hash(); - - let contains_non_zero_component_array = |component_name| { - event - .chunk - .components() - .get(&component_name) - .is_some_and(|per_desc| { - per_desc - .values() - .any(|list_array| list_array.offsets().lengths().any(|len| len > 0)) - }) - }; - - for component_name in event.chunk.component_names() { - if self.transform_components.contains(&component_name) - && contains_non_zero_component_array(component_name) - { - self.components_per_entity - .entry(entity_path_hash) - .or_default() - .transform3d - .insert(component_name); - } - if self.pose_components.contains(&component_name) - && contains_non_zero_component_array(component_name) - { - self.components_per_entity - .entry(entity_path_hash) - .or_default() - .pose3d - .insert(component_name); - } - if component_name == re_types::components::PinholeProjection::name() - && contains_non_zero_component_array(component_name) - { - self.components_per_entity - .entry(entity_path_hash) - .or_default() - .pinhole = true; - } - } - } - } -} diff --git a/crates/viewer/re_view_spatial/src/ui_2d.rs b/crates/viewer/re_view_spatial/src/ui_2d.rs index 3104e685c88b..a77dc8c6df91 100644 --- a/crates/viewer/re_view_spatial/src/ui_2d.rs +++ b/crates/viewer/re_view_spatial/src/ui_2d.rs @@ -10,7 +10,6 @@ use re_types::{ archetypes::{Background, NearClipPlane, VisualBounds2D}, components as blueprint_components, }, - components::ViewCoordinates, }; use re_ui::{ContextExt as _, ModifiersMarkdown, MouseButtonMarkdown}; use re_view::controls::{DRAG_PAN2D_BUTTON, ZOOM_SCROLL_MODIFIER}; @@ -353,7 +352,7 @@ fn setup_target_config( ) .into(), resolution: Some([resolution.x, resolution.y].into()), - camera_xyz: Some(ViewCoordinates::RDF), + camera_xyz: Some(Pinhole::DEFAULT_CAMERA_XYZ), image_plane_distance: None, }; } diff --git a/crates/viewer/re_view_spatial/src/view_2d.rs b/crates/viewer/re_view_spatial/src/view_2d.rs index 1ed42c0201d7..1949cfa043cb 100644 --- a/crates/viewer/re_view_spatial/src/view_2d.rs +++ b/crates/viewer/re_view_spatial/src/view_2d.rs @@ -68,7 +68,7 @@ impl ViewClass for SpatialView2D { ) -> Result<(), ViewClassRegistryError> { // Ensure spatial topology & max image dimension is registered. crate::spatial_topology::SpatialTopologyStoreSubscriber::subscription_handle(); - crate::transform_component_tracker::TransformComponentTrackerStoreSubscriber::subscription_handle(); + crate::transform_cache::TransformCacheStoreSubscriber::subscription_handle(); crate::max_image_dimension_subscriber::MaxImageDimensionsStoreSubscriber::subscription_handle(); register_spatial_contexts(system_registry)?; diff --git a/crates/viewer/re_view_spatial/src/view_3d.rs b/crates/viewer/re_view_spatial/src/view_3d.rs index 2af66bb20404..c83faf828c5a 100644 --- a/crates/viewer/re_view_spatial/src/view_3d.rs +++ b/crates/viewer/re_view_spatial/src/view_3d.rs @@ -74,7 +74,7 @@ impl ViewClass for SpatialView3D { ) -> Result<(), ViewClassRegistryError> { // Ensure spatial topology is registered. crate::spatial_topology::SpatialTopologyStoreSubscriber::subscription_handle(); - crate::transform_component_tracker::TransformComponentTrackerStoreSubscriber::subscription_handle(); + crate::transform_cache::TransformCacheStoreSubscriber::subscription_handle(); register_spatial_contexts(system_registry)?; register_3d_spatial_visualizers(system_registry)?; diff --git a/crates/viewer/re_view_spatial/src/visualizers/cameras.rs b/crates/viewer/re_view_spatial/src/visualizers/cameras.rs index 709ccae686c4..834d90f90daf 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/cameras.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/cameras.rs @@ -14,7 +14,8 @@ use re_viewer_context::{ use super::{filter_visualizable_3d_entities, SpatialViewVisualizerData}; use crate::{ - contexts::TransformContext, query_pinhole, space_camera_3d::SpaceCamera3D, ui::SpatialViewState, + contexts::TransformTreeContext, query_pinhole, space_camera_3d::SpaceCamera3D, + ui::SpatialViewState, }; const CAMERA_COLOR: re_renderer::Color32 = re_renderer::Color32::from_rgb(150, 150, 150); @@ -46,7 +47,7 @@ impl CamerasVisualizer { fn visit_instance( &mut self, line_builder: &mut re_renderer::LineDrawableBuilder<'_>, - transforms: &TransformContext, + transforms: &TransformTreeContext, data_result: &DataResult, pinhole: &Pinhole, pinhole_view_coordinates: ViewCoordinates, @@ -71,7 +72,7 @@ impl CamerasVisualizer { } // The camera transform does not include the pinhole transform. - let Some(transform_info) = transforms.transform_info_for_entity(ent_path) else { + let Some(transform_info) = transforms.transform_info_for_entity(ent_path.hash()) else { return; }; let Some(twod_in_threed_info) = &transform_info.twod_in_threed_info else { @@ -214,7 +215,7 @@ impl VisualizerSystem for CamerasVisualizer { query: &ViewQuery<'_>, context_systems: &ViewContextCollection, ) -> Result, ViewSystemExecutionError> { - let transforms = context_systems.get::()?; + let transforms = context_systems.get::()?; // Counting all cameras ahead of time is a bit wasteful, but we also don't expect a huge amount, // so let re_renderer's allocator internally decide what buffer sizes to pick & grow them as we go. @@ -236,7 +237,7 @@ impl VisualizerSystem for CamerasVisualizer { transforms, data_result, &pinhole, - pinhole.camera_xyz.unwrap_or(ViewCoordinates::RDF), // TODO(#2641): This should come from archetype + pinhole.camera_xyz.unwrap_or(Pinhole::DEFAULT_CAMERA_XYZ), entity_highlight, ); } @@ -279,4 +280,10 @@ impl TypedComponentFallbackProvider for CamerasVisualizer { } } -re_viewer_context::impl_component_fallback_provider!(CamerasVisualizer => [ImagePlaneDistance]); +impl TypedComponentFallbackProvider for CamerasVisualizer { + fn fallback_for(&self, _ctx: &QueryContext<'_>) -> ViewCoordinates { + Pinhole::DEFAULT_CAMERA_XYZ + } +} + +re_viewer_context::impl_component_fallback_provider!(CamerasVisualizer => [ImagePlaneDistance, ViewCoordinates]); diff --git a/crates/viewer/re_view_spatial/src/visualizers/depth_images.rs b/crates/viewer/re_view_spatial/src/visualizers/depth_images.rs index 652eafbdb38f..3b946caefd14 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/depth_images.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/depth_images.rs @@ -7,7 +7,6 @@ use re_types::{ archetypes::DepthImage, components::{ self, Colormap, DepthMeter, DrawOrder, FillRatio, ImageBuffer, ImageFormat, ValueRange, - ViewCoordinates, }, image::ImageKind, Component as _, @@ -190,7 +189,7 @@ impl DepthImageVisualizer { * glam::Affine3A::from_mat3( intrinsics .camera_xyz - .unwrap_or(ViewCoordinates::RDF) // TODO(#2641): This should come from archetype + .unwrap_or(re_types::archetypes::Pinhole::DEFAULT_CAMERA_XYZ) .from_rdf(), ); diff --git a/crates/viewer/re_view_spatial/src/visualizers/mod.rs b/crates/viewer/re_view_spatial/src/visualizers/mod.rs index b1b5ea34d38f..0bf2cb4b8297 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/mod.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/mod.rs @@ -267,11 +267,7 @@ pub fn load_keypoint_connections( /// /// TODO(#1387): Image coordinate space should be configurable. pub fn image_view_coordinates() -> re_types::components::ViewCoordinates { - // Typical image spaces have - // - x pointing right - // - y pointing down - // - z pointing into the image plane (this is convenient for reading out a depth image which has typically positive z values) - re_types::components::ViewCoordinates::RDF + re_types::archetypes::Pinhole::DEFAULT_CAMERA_XYZ } fn filter_visualizable_2d_entities( diff --git a/crates/viewer/re_view_spatial/src/visualizers/transform3d_arrows.rs b/crates/viewer/re_view_spatial/src/visualizers/transform3d_arrows.rs index a2340f88fd85..1ecb0dc73177 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/transform3d_arrows.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/transform3d_arrows.rs @@ -13,7 +13,7 @@ use re_viewer_context::{ VisualizableEntities, VisualizableFilterContext, VisualizerQueryInfo, VisualizerSystem, }; -use crate::{contexts::TransformContext, ui::SpatialViewState, view_kind::SpatialViewKind}; +use crate::{contexts::TransformTreeContext, ui::SpatialViewState, view_kind::SpatialViewKind}; use super::{filter_visualizable_3d_entities, CamerasVisualizer, SpatialViewVisualizerData}; @@ -81,7 +81,7 @@ impl VisualizerSystem for Transform3DArrowsVisualizer { query: &ViewQuery<'_>, context_systems: &ViewContextCollection, ) -> Result, ViewSystemExecutionError> { - let transforms = context_systems.get::()?; + let transforms = context_systems.get::()?; let latest_at_query = re_chunk_store::LatestAtQuery::new(query.timeline, query.latest_at); @@ -95,7 +95,7 @@ impl VisualizerSystem for Transform3DArrowsVisualizer { for data_result in query.iter_visible_data_results(ctx, Self::identifier()) { // Use transform without potential pinhole, since we don't want to visualize image-space coordinates. let Some(transform_info) = - transforms.transform_info_for_entity(&data_result.entity_path) + transforms.transform_info_for_entity(data_result.entity_path.hash()) else { continue; }; diff --git a/crates/viewer/re_view_spatial/src/visualizers/utilities/entity_iterator.rs b/crates/viewer/re_view_spatial/src/visualizers/utilities/entity_iterator.rs index 2b5718a26e92..2ca627bf1430 100644 --- a/crates/viewer/re_view_spatial/src/visualizers/utilities/entity_iterator.rs +++ b/crates/viewer/re_view_spatial/src/visualizers/utilities/entity_iterator.rs @@ -6,7 +6,7 @@ use re_viewer_context::{ ViewSystemExecutionError, }; -use crate::contexts::{EntityDepthOffsets, SpatialSceneEntityContext, TransformContext}; +use crate::contexts::{EntityDepthOffsets, SpatialSceneEntityContext, TransformTreeContext}; // --- @@ -84,7 +84,7 @@ where &HybridResults<'_>, ) -> Result<(), ViewSystemExecutionError>, { - let transforms = view_ctx.get::()?; + let transforms = view_ctx.get::()?; let depth_offsets = view_ctx.get::()?; let annotations = view_ctx.get::()?; @@ -93,7 +93,8 @@ where let system_identifier = System::identifier(); for data_result in query.iter_visible_data_results(ctx, system_identifier) { - let Some(transform_info) = transforms.transform_info_for_entity(&data_result.entity_path) + let Some(transform_info) = + transforms.transform_info_for_entity(data_result.entity_path.hash()) else { continue; }; From ec07b14fdb2ed9a21f09323e85cb65e27500102a Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 15 Jan 2025 16:24:25 +0100 Subject: [PATCH 40/57] Use insta for dataframe snapshot tests (#8696) * Part of #3741 This will make it easier to switch out TransportChunk for RecordBatch --- Cargo.lock | 1 + crates/store/re_chunk/src/arrow.rs | 8 +- crates/store/re_chunk/src/transport.rs | 14 +- crates/store/re_dataframe/Cargo.toml | 1 + crates/store/re_dataframe/src/query.rs | 310 ++---------------- ..._query__tests__async_barebones_static.snap | 13 + ...uery__tests__async_barebones_temporal.snap | 13 + ..._dataframe__query__tests__barebones-2.snap | 13 + ...re_dataframe__query__tests__barebones.snap | 13 + .../re_dataframe__query__tests__clears-2.snap | 13 + .../re_dataframe__query__tests__clears.snap | 13 + ...e__query__tests__filtered_index_range.snap | 13 + ...__query__tests__filtered_index_values.snap | 13 + ..._query__tests__filtered_is_not_null-2.snap | 7 + ..._query__tests__filtered_is_not_null-3.snap | 13 + ..._query__tests__filtered_is_not_null-4.snap | 13 + ...e__query__tests__filtered_is_not_null.snap | 7 + ..._dataframe__query__tests__selection-2.snap | 11 + ..._dataframe__query__tests__selection-3.snap | 12 + ..._dataframe__query__tests__selection-4.snap | 19 ++ ...re_dataframe__query__tests__selection.snap | 7 + ...__sparse_fill_strategy_latestatglobal.snap | 13 + ...e__query__tests__using_index_values-2.snap | 13 + ...ame__query__tests__using_index_values.snap | 13 + ...aframe__query__tests__view_contents-2.snap | 12 + ...ataframe__query__tests__view_contents.snap | 7 + ...y__tests__view_contents_and_selection.snap | 14 + rerun_py/src/remote.rs | 2 +- 28 files changed, 310 insertions(+), 291 deletions(-) create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__async_barebones_static.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__async_barebones_temporal.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__barebones-2.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__barebones.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__clears-2.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__clears.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_index_range.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_index_values.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-2.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-3.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-4.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-2.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-3.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-4.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__sparse_fill_strategy_latestatglobal.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__using_index_values-2.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__using_index_values.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents-2.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents.snap create mode 100644 crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents_and_selection.snap diff --git a/Cargo.lock b/Cargo.lock index 950cec6514a2..75faee5fd61a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5913,6 +5913,7 @@ version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", "arrow", + "insta", "itertools 0.13.0", "nohash-hasher", "rayon", diff --git a/crates/store/re_chunk/src/arrow.rs b/crates/store/re_chunk/src/arrow.rs index 32642e298555..4802c2170484 100644 --- a/crates/store/re_chunk/src/arrow.rs +++ b/crates/store/re_chunk/src/arrow.rs @@ -13,11 +13,9 @@ impl TransportChunk { /// related rust structures that refer to those data buffers. pub fn try_to_arrow_record_batch(&self) -> Result { let columns: Vec<_> = self - .all_columns() - .map(|(_field, arr2_array)| { - let data = arrow2::array::to_data(arr2_array.as_ref()); - make_array(data) - }) + .columns() + .iter() + .map(|arr2_array| make_array(arrow2::array::to_data(*arr2_array))) .collect(); RecordBatch::try_new(self.schema(), columns) diff --git a/crates/store/re_chunk/src/transport.rs b/crates/store/re_chunk/src/transport.rs index 5f0a9c17e162..0b5a4fe7d3e8 100644 --- a/crates/store/re_chunk/src/transport.rs +++ b/crates/store/re_chunk/src/transport.rs @@ -380,7 +380,7 @@ impl TransportChunk { /// * [`Self::FIELD_METADATA_VALUE_KIND_CONTROL`] /// * [`Self::FIELD_METADATA_VALUE_KIND_DATA`] #[inline] - pub fn columns<'a>( + fn columns_of_kind<'a>( &'a self, kind: &'a str, ) -> impl Iterator)> + 'a { @@ -402,7 +402,9 @@ impl TransportChunk { } #[inline] - pub fn all_columns(&self) -> impl Iterator)> + '_ { + pub fn fields_and_columns( + &self, + ) -> impl Iterator)> + '_ { self.schema .fields .iter() @@ -416,26 +418,26 @@ impl TransportChunk { } #[inline] - pub fn all_columns_collected(&self) -> Vec<&dyn Arrow2Array> { + pub fn columns(&self) -> Vec<&dyn Arrow2Array> { self.data.iter().map(|c| c.as_ref()).collect() } /// Iterates all control columns present in this chunk. #[inline] pub fn controls(&self) -> impl Iterator)> { - self.columns(Self::FIELD_METADATA_VALUE_KIND_CONTROL) + self.columns_of_kind(Self::FIELD_METADATA_VALUE_KIND_CONTROL) } /// Iterates all data columns present in this chunk. #[inline] pub fn components(&self) -> impl Iterator)> { - self.columns(Self::FIELD_METADATA_VALUE_KIND_DATA) + self.columns_of_kind(Self::FIELD_METADATA_VALUE_KIND_DATA) } /// Iterates all timeline columns present in this chunk. #[inline] pub fn timelines(&self) -> impl Iterator)> { - self.columns(Self::FIELD_METADATA_VALUE_KIND_TIME) + self.columns_of_kind(Self::FIELD_METADATA_VALUE_KIND_TIME) } /// How many columns in total? Includes control, time, and component columns. diff --git a/crates/store/re_dataframe/Cargo.toml b/crates/store/re_dataframe/Cargo.toml index af5cce5c268a..cd62b928e2b0 100644 --- a/crates/store/re_dataframe/Cargo.toml +++ b/crates/store/re_dataframe/Cargo.toml @@ -40,6 +40,7 @@ re_types_core.workspace = true anyhow.workspace = true arrow.workspace = true arrow2.workspace = true +insta.workspace = true itertools.workspace = true nohash-hasher.workspace = true rayon.workspace = true diff --git a/crates/store/re_dataframe/src/query.rs b/crates/store/re_dataframe/src/query.rs index 4834b631dff4..1a5c6358ba50 100644 --- a/crates/store/re_dataframe/src/query.rs +++ b/crates/store/re_dataframe/src/query.rs @@ -1323,6 +1323,7 @@ impl QueryHandle { mod tests { use std::sync::Arc; + use insta::assert_debug_snapshot; use re_chunk::{ concat_record_batches::concatenate_record_batches, Chunk, ChunkId, RowId, TimePoint, TransportChunk, @@ -1398,20 +1399,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[None], - Timestamp(Nanosecond, None)[None], - ListArray[None], - ListArray[[c]], - ListArray[None], - ]\ - ", - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } // temporal @@ -1433,20 +1421,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[10, 20, 30, 40, 50, 60, 70], - Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, None, 1970-01-01 00:00:00.000000070], - ListArray[None, None, [2], [3], [4], None, [6]], - ListArray[[c], [c], [c], [c], [c], [c], [c]], - ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 5, y: 5}], [{x: 8, y: 8}]], - ]\ - " - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } Ok(()) @@ -1480,20 +1455,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[10, 20, 30, 40, 50, 60, 70], - Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, None, 1970-01-01 00:00:00.000000070], - ListArray[None, None, [2], [3], [4], [4], [6]], - ListArray[[c], [c], [c], [c], [c], [c], [c]], - ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 5, y: 5}], [{x: 8, y: 8}]], - ]\ - " - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); Ok(()) } @@ -1526,20 +1488,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[30, 40, 50, 60], - Timestamp(Nanosecond, None)[None, None, 1970-01-01 00:00:00.000000050, None], - ListArray[[2], [3], [4], None], - ListArray[[c], [c], [c], [c]], - ListArray[[{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 5, y: 5}]], - ]\ - ", - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); Ok(()) } @@ -1578,20 +1527,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[30, 60], - Timestamp(Nanosecond, None)[None, None], - ListArray[[2], None], - ListArray[[c], [c]], - ListArray[[{x: 2, y: 2}], [{x: 5, y: 5}]], - ]\ - ", - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); Ok(()) } @@ -1633,20 +1569,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[0, 15, 30, 45, 60, 75, 90], - Timestamp(Nanosecond, None)[None, None, None, None, None, None, None], - ListArray[None, None, [2], None, None, None, None], - ListArray[[c], [c], [c], [c], [c], [c], [c]], - ListArray[None, None, [{x: 2, y: 2}], None, [{x: 5, y: 5}], None, None], - ]\ - ", - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } // sparse-filled @@ -1676,20 +1599,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[0, 15, 30, 45, 60, 75, 90], - Timestamp(Nanosecond, None)[None, 1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000070, 1970-01-01 00:00:00.000000070], - ListArray[None, None, [2], [3], [4], [6], [6]], - ListArray[[c], [c], [c], [c], [c], [c], [c]], - ListArray[None, [{x: 0, y: 0}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 5, y: 5}], [{x: 8, y: 8}], [{x: 8, y: 8}]], - ]\ - ", - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } Ok(()) @@ -1730,10 +1640,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = "[]"; - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } // non-existing component @@ -1759,10 +1666,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = "[]"; - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } // MyPoint @@ -1788,20 +1692,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[10, 20, 30, 40, 50, 60, 70], - Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, None, 1970-01-01 00:00:00.000000070], - ListArray[None, None, [2], [3], [4], None, [6]], - ListArray[[c], [c], [c], [c], [c], [c], [c]], - ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 5, y: 5}], [{x: 8, y: 8}]], - ]\ - " - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } // MyColor @@ -1827,20 +1718,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[30, 40, 50, 70], - Timestamp(Nanosecond, None)[None, None, 1970-01-01 00:00:00.000000050, 1970-01-01 00:00:00.000000070], - ListArray[[2], [3], [4], [6]], - ListArray[[c], [c], [c], [c]], - ListArray[[{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 8, y: 8}]], - ]\ - ", - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } Ok(()) @@ -1882,10 +1760,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = "[]"; - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } { @@ -1922,19 +1797,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[30, 40, 50, 70], - Timestamp(Nanosecond, None)[None, None, None, None], - ListArray[[2], [3], [4], [6]], - ListArray[[c], [c], [c], [c]], - ]\ - ", - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } Ok(()) @@ -1972,10 +1835,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = "[]"; - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } // only indices (+ duplication) @@ -2008,18 +1868,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - NullArray(7), - ]\ - ", - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } // only components (+ duplication) @@ -2059,19 +1908,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - ListArray[None, None, [2], [3], [4], None, [6]], - ListArray[None, None, [2], [3], [4], None, [6]], - NullArray(7), - NullArray(7), - ]\ - ", - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } // static @@ -2132,26 +1969,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - ListArray[[c], [c], [c], [c], [c], [c], [c]], - ]\ - ", - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } Ok(()) @@ -2220,21 +2038,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[30, 40, 50, 70], - Timestamp(Nanosecond, None)[None, None, None, None], - NullArray(4), - NullArray(4), - ListArray[[2], [3], [4], [6]], - ListArray[[c], [c], [c], [c]], - ]\ - ", - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } Ok(()) @@ -2274,20 +2078,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[10, 20, 30, 40, 50, 60, 65, 70], - Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, 1970-01-01 00:00:00.000000060, 1970-01-01 00:00:00.000000065, 1970-01-01 00:00:00.000000070], - ListArray[None, None, [2], [3], [4], [], [], [6]], - ListArray[[c], [c], [c], [c], [c], [c], [c], [c]], - ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [], [], [{x: 8, y: 8}]], - ]\ - " - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } // sparse-filled @@ -2315,20 +2106,7 @@ mod tests { // static clear semantics in general are pretty unhinged right now, especially when // ranges are involved. // It's extremely niche, our time is better spent somewhere else right now. - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[10, 20, 30, 40, 50, 60, 65, 70], - Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, 1970-01-01 00:00:00.000000060, 1970-01-01 00:00:00.000000065, 1970-01-01 00:00:00.000000070], - ListArray[None, None, [2], [3], [4], [], [], [6]], - ListArray[[c], [c], [c], [c], [c], [c], [c], [c]], - ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [], [], [{x: 8, y: 8}]], - ]\ - " - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!(dataframe.columns()); } Ok(()) @@ -2375,8 +2153,8 @@ mod tests { &query_handle.batch_iter().take(3).collect_vec(), )?; - let expected = format!("{:#?}", expected.all_columns_collected()); - let got = format!("{:#?}", got.all_columns_collected()); + let expected = format!("{:#?}", expected.columns()); + let got = format!("{:#?}", got.columns()); similar_asserts::assert_eq!(expected, got); } @@ -2416,8 +2194,8 @@ mod tests { &query_handle.batch_iter().take(3).collect_vec(), )?; - let expected = format!("{:#?}", expected.all_columns_collected()); - let got = format!("{:#?}", got.all_columns_collected()); + let expected = format!("{:#?}", expected.columns()); + let got = format!("{:#?}", got.columns()); similar_asserts::assert_eq!(expected, got); } @@ -2460,8 +2238,8 @@ mod tests { &query_handle.batch_iter().take(3).collect_vec(), )?; - let expected = format!("{:#?}", expected.all_columns_collected()); - let got = format!("{:#?}", got.all_columns_collected()); + let expected = format!("{:#?}", expected.columns()); + let got = format!("{:#?}", got.columns()); similar_asserts::assert_eq!(expected, got); } @@ -2498,8 +2276,8 @@ mod tests { &query_handle.batch_iter().take(3).collect_vec(), )?; - let expected = format!("{:#?}", expected.all_columns_collected()); - let got = format!("{:#?}", got.all_columns_collected()); + let expected = format!("{:#?}", expected.columns()); + let got = format!("{:#?}", got.columns()); similar_asserts::assert_eq!(expected, got); } @@ -2566,20 +2344,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[None], - Timestamp(Nanosecond, None)[None], - ListArray[None], - ListArray[[c]], - ListArray[None], - ]\ - ", - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!("async_barebones_static", dataframe.columns()); Ok::<_, anyhow::Error>(()) } @@ -2610,20 +2375,7 @@ mod tests { )?; eprintln!("{dataframe}"); - let got = format!("{:#?}", dataframe.all_columns_collected()); - let expected = unindent::unindent( - "\ - [ - Int64[10, 20, 30, 40, 50, 60, 70], - Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, None, 1970-01-01 00:00:00.000000070], - ListArray[None, None, [2], [3], [4], None, [6]], - ListArray[[c], [c], [c], [c], [c], [c], [c]], - ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 5, y: 5}], [{x: 8, y: 8}]], - ]\ - " - ); - - similar_asserts::assert_eq!(expected, got); + assert_debug_snapshot!("async_barebones_temporal", dataframe.columns()); Ok::<_, anyhow::Error>(()) } diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__async_barebones_static.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__async_barebones_static.snap new file mode 100644 index 000000000000..ec3f6001de19 --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__async_barebones_static.snap @@ -0,0 +1,13 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 2347 +expression: dataframe.columns() +snapshot_kind: text +--- +[ + Int64[None], + Timestamp(Nanosecond, None)[None], + ListArray[None], + ListArray[[c]], + ListArray[None], +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__async_barebones_temporal.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__async_barebones_temporal.snap new file mode 100644 index 000000000000..a037d330cd2c --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__async_barebones_temporal.snap @@ -0,0 +1,13 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 2378 +expression: dataframe.columns() +snapshot_kind: text +--- +[ + Int64[10, 20, 30, 40, 50, 60, 70], + Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, None, 1970-01-01 00:00:00.000000070], + ListArray[None, None, [2], [3], [4], None, [6]], + ListArray[[c], [c], [c], [c], [c], [c], [c]], + ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 5, y: 5}], [{x: 8, y: 8}]], +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__barebones-2.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__barebones-2.snap new file mode 100644 index 000000000000..f143af9dbdba --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__barebones-2.snap @@ -0,0 +1,13 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1424 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[ + Int64[10, 20, 30, 40, 50, 60, 70], + Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, None, 1970-01-01 00:00:00.000000070], + ListArray[None, None, [2], [3], [4], None, [6]], + ListArray[[c], [c], [c], [c], [c], [c], [c]], + ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 5, y: 5}], [{x: 8, y: 8}]], +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__barebones.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__barebones.snap new file mode 100644 index 000000000000..f3b4325d5236 --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__barebones.snap @@ -0,0 +1,13 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1402 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[ + Int64[None], + Timestamp(Nanosecond, None)[None], + ListArray[None], + ListArray[[c]], + ListArray[None], +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__clears-2.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__clears-2.snap new file mode 100644 index 000000000000..afc62129c581 --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__clears-2.snap @@ -0,0 +1,13 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 2109 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[ + Int64[10, 20, 30, 40, 50, 60, 65, 70], + Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, 1970-01-01 00:00:00.000000060, 1970-01-01 00:00:00.000000065, 1970-01-01 00:00:00.000000070], + ListArray[None, None, [2], [3], [4], [], [], [6]], + ListArray[[c], [c], [c], [c], [c], [c], [c], [c]], + ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [], [], [{x: 8, y: 8}]], +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__clears.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__clears.snap new file mode 100644 index 000000000000..bffc10269340 --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__clears.snap @@ -0,0 +1,13 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 2081 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[ + Int64[10, 20, 30, 40, 50, 60, 65, 70], + Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, 1970-01-01 00:00:00.000000060, 1970-01-01 00:00:00.000000065, 1970-01-01 00:00:00.000000070], + ListArray[None, None, [2], [3], [4], [], [], [6]], + ListArray[[c], [c], [c], [c], [c], [c], [c], [c]], + ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [], [], [{x: 8, y: 8}]], +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_index_range.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_index_range.snap new file mode 100644 index 000000000000..08ebd00df026 --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_index_range.snap @@ -0,0 +1,13 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1491 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[ + Int64[30, 40, 50, 60], + Timestamp(Nanosecond, None)[None, None, 1970-01-01 00:00:00.000000050, None], + ListArray[[2], [3], [4], None], + ListArray[[c], [c], [c], [c]], + ListArray[[{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 5, y: 5}]], +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_index_values.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_index_values.snap new file mode 100644 index 000000000000..e537db4b0d30 --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_index_values.snap @@ -0,0 +1,13 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1530 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[ + Int64[30, 60], + Timestamp(Nanosecond, None)[None, None], + ListArray[[2], None], + ListArray[[c], [c]], + ListArray[[{x: 2, y: 2}], [{x: 5, y: 5}]], +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-2.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-2.snap new file mode 100644 index 000000000000..7ddef2114658 --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-2.snap @@ -0,0 +1,7 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1669 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-3.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-3.snap new file mode 100644 index 000000000000..672f02d24438 --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-3.snap @@ -0,0 +1,13 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1695 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[ + Int64[10, 20, 30, 40, 50, 60, 70], + Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, None, 1970-01-01 00:00:00.000000070], + ListArray[None, None, [2], [3], [4], None, [6]], + ListArray[[c], [c], [c], [c], [c], [c], [c]], + ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 5, y: 5}], [{x: 8, y: 8}]], +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-4.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-4.snap new file mode 100644 index 000000000000..e913daa93261 --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-4.snap @@ -0,0 +1,13 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1721 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[ + Int64[30, 40, 50, 70], + Timestamp(Nanosecond, None)[None, None, 1970-01-01 00:00:00.000000050, 1970-01-01 00:00:00.000000070], + ListArray[[2], [3], [4], [6]], + ListArray[[c], [c], [c], [c]], + ListArray[[{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 8, y: 8}]], +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null.snap new file mode 100644 index 000000000000..f18b0ee5e796 --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null.snap @@ -0,0 +1,7 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1643 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-2.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-2.snap new file mode 100644 index 000000000000..821038ac14e8 --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-2.snap @@ -0,0 +1,11 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1871 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[ + Int64[10, 20, 30, 40, 50, 60, 70], + Int64[10, 20, 30, 40, 50, 60, 70], + NullArray(7), +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-3.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-3.snap new file mode 100644 index 000000000000..d78191b475bf --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-3.snap @@ -0,0 +1,12 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1911 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[ + ListArray[None, None, [2], [3], [4], None, [6]], + ListArray[None, None, [2], [3], [4], None, [6]], + NullArray(7), + NullArray(7), +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-4.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-4.snap new file mode 100644 index 000000000000..ab708132a72b --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-4.snap @@ -0,0 +1,19 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1972 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[ + Int64[10, 20, 30, 40, 50, 60, 70], + Int64[10, 20, 30, 40, 50, 60, 70], + Int64[10, 20, 30, 40, 50, 60, 70], + Int64[10, 20, 30, 40, 50, 60, 70], + Int64[10, 20, 30, 40, 50, 60, 70], + Int64[10, 20, 30, 40, 50, 60, 70], + Int64[10, 20, 30, 40, 50, 60, 70], + Int64[10, 20, 30, 40, 50, 60, 70], + Int64[10, 20, 30, 40, 50, 60, 70], + Int64[10, 20, 30, 40, 50, 60, 70], + ListArray[[c], [c], [c], [c], [c], [c], [c]], +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection.snap new file mode 100644 index 000000000000..af25dece2e43 --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection.snap @@ -0,0 +1,7 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1838 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__sparse_fill_strategy_latestatglobal.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__sparse_fill_strategy_latestatglobal.snap new file mode 100644 index 000000000000..a2063e9472af --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__sparse_fill_strategy_latestatglobal.snap @@ -0,0 +1,13 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1458 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[ + Int64[10, 20, 30, 40, 50, 60, 70], + Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, None, 1970-01-01 00:00:00.000000070], + ListArray[None, None, [2], [3], [4], [4], [6]], + ListArray[[c], [c], [c], [c], [c], [c], [c]], + ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 5, y: 5}], [{x: 8, y: 8}]], +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__using_index_values-2.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__using_index_values-2.snap new file mode 100644 index 000000000000..7329e2113b69 --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__using_index_values-2.snap @@ -0,0 +1,13 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1602 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[ + Int64[0, 15, 30, 45, 60, 75, 90], + Timestamp(Nanosecond, None)[None, 1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000070, 1970-01-01 00:00:00.000000070], + ListArray[None, None, [2], [3], [4], [6], [6]], + ListArray[[c], [c], [c], [c], [c], [c], [c]], + ListArray[None, [{x: 0, y: 0}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 5, y: 5}], [{x: 8, y: 8}], [{x: 8, y: 8}]], +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__using_index_values.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__using_index_values.snap new file mode 100644 index 000000000000..357656d2c29c --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__using_index_values.snap @@ -0,0 +1,13 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1572 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[ + Int64[0, 15, 30, 45, 60, 75, 90], + Timestamp(Nanosecond, None)[None, None, None, None, None, None, None], + ListArray[None, None, [2], None, None, None, None], + ListArray[[c], [c], [c], [c], [c], [c], [c]], + ListArray[None, None, [{x: 2, y: 2}], None, [{x: 5, y: 5}], None, None], +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents-2.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents-2.snap new file mode 100644 index 000000000000..340c56ae733b --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents-2.snap @@ -0,0 +1,12 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1800 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[ + Int64[30, 40, 50, 70], + Timestamp(Nanosecond, None)[None, None, None, None], + ListArray[[2], [3], [4], [6]], + ListArray[[c], [c], [c], [c]], +] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents.snap new file mode 100644 index 000000000000..c43c3d2929cc --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents.snap @@ -0,0 +1,7 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 1763 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[] diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents_and_selection.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents_and_selection.snap new file mode 100644 index 000000000000..5b5a196fff87 --- /dev/null +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents_and_selection.snap @@ -0,0 +1,14 @@ +--- +source: crates/store/re_dataframe/src/query.rs +assertion_line: 2041 +expression: dataframe.all_columns_collected() +snapshot_kind: text +--- +[ + Int64[30, 40, 50, 70], + Timestamp(Nanosecond, None)[None, None, None, None], + NullArray(4), + NullArray(4), + ListArray[[2], [3], [4], [6]], + ListArray[[c], [c], [c], [c]], +] diff --git a/rerun_py/src/remote.rs b/rerun_py/src/remote.rs index 61ff89875aa3..bc408ba72570 100644 --- a/rerun_py/src/remote.rs +++ b/rerun_py/src/remote.rs @@ -347,7 +347,7 @@ impl PyStorageNodeClient { .map_err(|err| PyRuntimeError::new_err(err.to_string()))?; let recording_id = metadata - .all_columns() + .fields_and_columns() .find(|(field, _data)| field.name() == "rerun_recording_id") .map(|(_field, data)| data) .ok_or(PyRuntimeError::new_err("No rerun_recording_id"))? From 3ffdb3751c7999853291699c733a8486b581858e Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 15 Jan 2025 16:47:30 +0100 Subject: [PATCH 41/57] Respect max width of formatter when formatting ChunkStore/Chunk (#8698) Makes the test predictable, regardless of terminal width --- crates/store/re_chunk/src/transport.rs | 1 + crates/store/re_chunk_store/src/store.rs | 7 ++++++- crates/store/re_chunk_store/tests/formatting.rs | 2 +- .../formatting__format_chunk_store.snap | 2 +- crates/store/re_format_arrow/src/lib.rs | 17 ++++++++++++++++- 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/crates/store/re_chunk/src/transport.rs b/crates/store/re_chunk/src/transport.rs index 0b5a4fe7d3e8..d157c8b52f98 100644 --- a/crates/store/re_chunk/src/transport.rs +++ b/crates/store/re_chunk/src/transport.rs @@ -63,6 +63,7 @@ impl std::fmt::Display for TransportChunk { .iter() .map(|list_array| ArrowArrayRef::from(list_array.clone())) .collect_vec(), + f.width(), ) .fmt(f) } diff --git a/crates/store/re_chunk_store/src/store.rs b/crates/store/re_chunk_store/src/store.rs index bb2facfdafec..a5afbfa9f7a9 100644 --- a/crates/store/re_chunk_store/src/store.rs +++ b/crates/store/re_chunk_store/src/store.rs @@ -530,7 +530,12 @@ impl std::fmt::Display for ChunkStore { f.write_str(&indent::indent_all_by(4, "chunks: [\n"))?; for chunk_id in chunk_id_per_min_row_id.values().flatten() { if let Some(chunk) = chunks_per_chunk_id.get(chunk_id) { - f.write_str(&indent::indent_all_by(8, format!("{chunk}\n")))?; + if let Some(width) = f.width() { + let chunk_width = width.saturating_sub(8); + f.write_str(&indent::indent_all_by(8, format!("{chunk:chunk_width$}\n")))?; + } else { + f.write_str(&indent::indent_all_by(8, format!("{chunk}\n")))?; + } } else { f.write_str(&indent::indent_all_by(8, "\n"))?; } diff --git a/crates/store/re_chunk_store/tests/formatting.rs b/crates/store/re_chunk_store/tests/formatting.rs index e71fbffdbd1c..dc61ff3fae16 100644 --- a/crates/store/re_chunk_store/tests/formatting.rs +++ b/crates/store/re_chunk_store/tests/formatting.rs @@ -42,7 +42,7 @@ fn format_chunk_store() -> anyhow::Result<()> { .build()?, ))?; - insta::assert_snapshot!("format_chunk_store", store.to_string()); + insta::assert_snapshot!("format_chunk_store", format!("{:200}", store)); Ok(()) } diff --git a/crates/store/re_chunk_store/tests/snapshots/formatting__format_chunk_store.snap b/crates/store/re_chunk_store/tests/snapshots/formatting__format_chunk_store.snap index af14c5c661cc..90d7aabfa44b 100644 --- a/crates/store/re_chunk_store/tests/snapshots/formatting__format_chunk_store.snap +++ b/crates/store/re_chunk_store/tests/snapshots/formatting__format_chunk_store.snap @@ -1,7 +1,7 @@ --- source: crates/store/re_chunk_store/tests/formatting.rs assertion_line: 45 -expression: store.to_string() +expression: "format!(\"{:200}\", store)" snapshot_kind: text --- ChunkStore { diff --git a/crates/store/re_format_arrow/src/lib.rs b/crates/store/re_format_arrow/src/lib.rs index 28af79ae8be5..a796f6d91e5a 100644 --- a/crates/store/re_format_arrow/src/lib.rs +++ b/crates/store/re_format_arrow/src/lib.rs @@ -212,7 +212,12 @@ fn trim_name(name: &str) -> &str { .trim_start_matches("rerun.") } -pub fn format_dataframe(metadata: &Metadata, fields: &Fields, columns: &[ArrayRef]) -> Table { +pub fn format_dataframe( + metadata: &Metadata, + fields: &Fields, + columns: &[ArrayRef], + width: Option, +) -> Table { const MAXIMUM_CELL_CONTENT_WIDTH: u16 = 100; let mut outer_table = Table::new(); @@ -221,6 +226,16 @@ pub fn format_dataframe(metadata: &Metadata, fields: &Fields, columns: &[ArrayRe let mut table = Table::new(); table.load_preset(presets::UTF8_FULL); + if let Some(width) = width { + outer_table.set_width(width as _); + outer_table.set_content_arrangement(comfy_table::ContentArrangement::Disabled); + table.set_width(width as _); + table.set_content_arrangement(comfy_table::ContentArrangement::Disabled); + } else { + outer_table.set_content_arrangement(comfy_table::ContentArrangement::Dynamic); + table.set_content_arrangement(comfy_table::ContentArrangement::Dynamic); + } + outer_table.add_row({ let mut row = Row::new(); row.add_cell(Cell::new(format!( From d0a7d1fdf96c022c7d1f02735a86b046d96cf2f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= Date: Wed, 15 Jan 2025 16:49:44 +0100 Subject: [PATCH 42/57] Add JS timeline control and callback APIs (#8673) --- .vscode/settings.json | 6 +- crates/viewer/re_viewer/src/app.rs | 63 +++- crates/viewer/re_viewer/src/app_state.rs | 17 +- crates/viewer/re_viewer/src/web.rs | 287 ++++++++++++++++++ crates/viewer/re_viewer/src/web_tools.rs | 14 +- crates/viewer/re_viewer_context/src/lib.rs | 2 +- .../re_viewer_context/src/time_control.rs | 181 ++++++++--- rerun_js/package.json | 3 +- rerun_js/web-viewer/index.ts | 182 ++++++++++- 9 files changed, 701 insertions(+), 54 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index f92aa692cba5..65fbf4caa119 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -46,11 +46,7 @@ // Uncomment the following options and restart rust-analyzer to get it to check code behind `cfg(target_arch=wasm32)`. // Don't forget to put it in a comment again before committing. // "rust-analyzer.cargo.target": "wasm32-unknown-unknown", - // "rust-analyzer.cargo.cfgs": { - // "web": null, - // "webgl": null, - // "webgpu": null, - // }, + // "rust-analyzer.cargo.cfgs": ["web","webgl","webgpu"], "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", // Use cmake-tools to grab configs. "C_Cpp.autoAddFileAssociations": false, diff --git a/crates/viewer/re_viewer/src/app.rs b/crates/viewer/re_viewer/src/app.rs index 678a21100709..17d0546e1624 100644 --- a/crates/viewer/re_viewer/src/app.rs +++ b/crates/viewer/re_viewer/src/app.rs @@ -82,6 +82,13 @@ pub struct StartupOptions { /// This also can be changed in the viewer's option menu. pub video_decoder_hw_acceleration: Option, + /// Interaction between JS and timeline. + /// + /// This field isn't used directly, but is propagated to all recording configs + /// when they are created. + #[cfg(target_arch = "wasm32")] + pub timeline_options: Option, + /// Fullscreen is handled by JS on web. /// /// This holds some callbacks which we use to communicate @@ -131,6 +138,9 @@ impl Default for StartupOptions { force_wgpu_backend: None, video_decoder_hw_acceleration: None, + #[cfg(target_arch = "wasm32")] + timeline_options: Default::default(), + #[cfg(target_arch = "wasm32")] fullscreen_options: Default::default(), @@ -220,6 +230,12 @@ pub struct App { pub(crate) panel_state_overrides: PanelStateOverrides, reflection: re_types_core::reflection::Reflection, + + /// Interaction between JS and timeline. + /// + /// This field isn't used directly, but is propagated to all recording configs + /// when they are created. + pub timeline_callbacks: Option, } impl App { @@ -325,6 +341,46 @@ impl App { Default::default() }); + #[cfg(target_arch = "wasm32")] + let timeline_callbacks = { + use crate::web_tools::string_from_js_value; + use std::rc::Rc; + use wasm_bindgen::JsValue; + + startup_options.timeline_options.clone().map(|opts| { + re_viewer_context::TimelineCallbacks { + on_timelinechange: Rc::new(move |timeline, time| { + if let Err(err) = opts.on_timelinechange.call2( + &JsValue::from_str(timeline.name().as_str()), + &JsValue::from_f64(time.as_f64()), + ) { + re_log::error!("{}", string_from_js_value(err)); + }; + }), + on_timeupdate: Rc::new(move |time| { + if let Err(err) = + opts.on_timeupdate.call1(&JsValue::from_f64(time.as_f64())) + { + re_log::error!("{}", string_from_js_value(err)); + } + }), + on_play: Rc::new(move || { + if let Err(err) = opts.on_play.call0() { + re_log::error!("{}", string_from_js_value(err)); + } + }), + on_pause: Rc::new(move || { + if let Err(err) = opts.on_pause.call0() { + re_log::error!("{}", string_from_js_value(err)); + } + }), + } + }) + }; + + #[cfg(not(target_arch = "wasm32"))] + let timeline_callbacks = None; + Self { main_thread_token, build_info, @@ -374,6 +430,8 @@ impl App { panel_state_overrides, reflection, + + timeline_callbacks, } } @@ -1126,6 +1184,7 @@ impl App { opacity: self.welcome_screen_opacity(egui_ctx), }, is_history_enabled, + self.timeline_callbacks.as_ref(), ); render_ctx.before_submit(); } @@ -1573,7 +1632,7 @@ impl App { { if let Some(options) = &self.startup_options.fullscreen_options { // Tell JS to toggle fullscreen. - if let Err(err) = options.on_toggle.call() { + if let Err(err) = options.on_toggle.call0() { re_log::error!("{}", crate::web_tools::string_from_js_value(err)); }; } @@ -1589,7 +1648,7 @@ impl App { pub(crate) fn is_fullscreen_mode(&self) -> bool { if let Some(options) = &self.startup_options.fullscreen_options { // Ask JS if fullscreen is on or not. - match options.get_state.call() { + match options.get_state.call0() { Ok(v) => return v.is_truthy(), Err(err) => re_log::error_once!("{}", crate::web_tools::string_from_js_value(err)), } diff --git a/crates/viewer/re_viewer/src/app_state.rs b/crates/viewer/re_viewer/src/app_state.rs index a29e202065d2..b2dcbb77dd60 100644 --- a/crates/viewer/re_viewer/src/app_state.rs +++ b/crates/viewer/re_viewer/src/app_state.rs @@ -151,6 +151,7 @@ impl AppState { command_sender: &CommandSender, welcome_screen_state: &WelcomeScreenState, is_history_enabled: bool, + timeline_callbacks: Option<&re_viewer_context::TimelineCallbacks>, ) { re_tracing::profile_function!(); @@ -291,7 +292,7 @@ impl AppState { // We move the time at the very start of the frame, // so that we always show the latest data when we're in "follow" mode. - move_time(&ctx, recording, rx); + move_time(&ctx, recording, rx, timeline_callbacks); // Update the viewport. May spawn new views and handle queued requests (like screenshots). viewport_ui.on_frame_start(&ctx); @@ -546,6 +547,11 @@ impl AppState { *focused_item = None; } + #[cfg(target_arch = "wasm32")] // Only used in Wasm + pub fn recording_config(&self, rec_id: &StoreId) -> Option<&RecordingConfig> { + self.recording_configs.get(rec_id) + } + pub fn recording_config_mut(&mut self, rec_id: &StoreId) -> Option<&mut RecordingConfig> { self.recording_configs.get_mut(rec_id) } @@ -584,7 +590,12 @@ impl AppState { } } -fn move_time(ctx: &ViewerContext<'_>, recording: &EntityDb, rx: &ReceiveSet) { +fn move_time( + ctx: &ViewerContext<'_>, + recording: &EntityDb, + rx: &ReceiveSet, + timeline_callbacks: Option<&re_viewer_context::TimelineCallbacks>, +) { let dt = ctx.egui_ctx.input(|i| i.stable_dt); // Are we still connected to the data source for the current store? @@ -598,6 +609,7 @@ fn move_time(ctx: &ViewerContext<'_>, recording: &EntityDb, rx: &ReceiveSet, recording: &EntityDb, rx: &ReceiveSet Option { + let app = self.runner.app_mut::()?; + let hub = app.store_hub.as_ref()?; + let recording = hub.active_recording()?; + + Some(recording.store_id().to_string()) + } + + #[wasm_bindgen] + pub fn set_active_recording_id(&self, store_id: &str) { + let Some(mut app) = self.runner.app_mut::() else { + return; + }; + + let Some(hub) = app.store_hub.as_mut() else { + return; + }; + let store_id = re_log_types::StoreId::from_string( + re_log_types::StoreKind::Recording, + store_id.to_owned(), + ); + if !hub.store_bundle().contains(&store_id) { + return; + }; + + hub.set_activate_recording(store_id); + + app.egui_ctx.request_repaint(); + } + + #[wasm_bindgen] + pub fn get_active_timeline(&self, store_id: &str) -> Option { + let mut app = self.runner.app_mut::()?; + let crate::App { + store_hub: Some(ref hub), + state, + .. + } = &mut *app + else { + return None; + }; + + let store_id = re_log_types::StoreId::from_string( + re_log_types::StoreKind::Recording, + store_id.to_owned(), + ); + if !hub.store_bundle().contains(&store_id) { + return None; + }; + + let rec_cfg = state.recording_config_mut(&store_id)?; + let time_ctrl = rec_cfg.time_ctrl.read(); + Some(time_ctrl.timeline().name().as_str().to_owned()) + } + + /// Set the active timeline. + /// + /// This does nothing if the timeline can't be found. + #[wasm_bindgen] + pub fn set_active_timeline(&self, store_id: &str, timeline: &str) { + let Some(mut app) = self.runner.app_mut::() else { + return; + }; + let crate::App { + store_hub: Some(ref hub), + state, + egui_ctx, + .. + } = &mut *app + else { + return; + }; + + let store_id = re_log_types::StoreId::from_string( + re_log_types::StoreKind::Recording, + store_id.to_owned(), + ); + let Some(recording) = hub.store_bundle().get(&store_id) else { + return; + }; + let Some(rec_cfg) = state.recording_config_mut(&store_id) else { + return; + }; + let Some(timeline) = recording + .timelines() + .find(|t| t.name().as_str() == timeline) + else { + return; + }; + + rec_cfg.time_ctrl.write().set_timeline(*timeline); + + egui_ctx.request_repaint(); + } + + #[wasm_bindgen] + pub fn get_time_for_timeline(&self, store_id: &str, timeline: &str) -> Option { + let app = self.runner.app_mut::()?; + let crate::App { + store_hub: Some(ref hub), + state, + .. + } = &*app + else { + return None; + }; + + let store_id = re_log_types::StoreId::from_string( + re_log_types::StoreKind::Recording, + store_id.to_owned(), + ); + let recording = hub.store_bundle().get(&store_id)?; + let rec_cfg = state.recording_config(&store_id)?; + let timeline = recording + .timelines() + .find(|t| t.name().as_str() == timeline)?; + + let time_ctrl = rec_cfg.time_ctrl.read(); + time_ctrl.time_for_timeline(*timeline).map(|v| v.as_f64()) + } + + #[wasm_bindgen] + pub fn set_time_for_timeline(&self, store_id: &str, timeline: &str, time: f64) { + let Some(mut app) = self.runner.app_mut::() else { + return; + }; + let crate::App { + store_hub: Some(ref hub), + state, + egui_ctx, + .. + } = &mut *app + else { + return; + }; + + let store_id = re_log_types::StoreId::from_string( + re_log_types::StoreKind::Recording, + store_id.to_owned(), + ); + let Some(recording) = hub.store_bundle().get(&store_id) else { + return; + }; + let Some(rec_cfg) = state.recording_config_mut(&store_id) else { + return; + }; + let Some(timeline) = recording + .timelines() + .find(|t| t.name().as_str() == timeline) + else { + return; + }; + + rec_cfg + .time_ctrl + .write() + .set_timeline_and_time(*timeline, time); + egui_ctx.request_repaint(); + } + + #[wasm_bindgen] + pub fn get_timeline_time_range(&self, store_id: &str, timeline: &str) -> JsValue { + let Some(app) = self.runner.app_mut::() else { + return JsValue::null(); + }; + let crate::App { + store_hub: Some(ref hub), + .. + } = &*app + else { + return JsValue::null(); + }; + + let store_id = re_log_types::StoreId::from_string( + re_log_types::StoreKind::Recording, + store_id.to_owned(), + ); + let Some(recording) = hub.store_bundle().get(&store_id) else { + return JsValue::null(); + }; + let Some(timeline) = recording + .timelines() + .find(|t| t.name().as_str() == timeline) + else { + return JsValue::null(); + }; + + let Some(time_range) = recording.time_range_for(timeline) else { + return JsValue::null(); + }; + + let min = time_range.min().as_f64(); + let max = time_range.max().as_f64(); + + let obj = js_sys::Object::new(); + js_sys::Reflect::set(&obj, &"min".into(), &min.into()).ok_or_log_js_error(); + js_sys::Reflect::set(&obj, &"max".into(), &max.into()).ok_or_log_js_error(); + + JsValue::from(obj) + } + + #[wasm_bindgen] + pub fn get_playing(&self, store_id: &str) -> Option { + let app = self.runner.app_mut::()?; + let crate::App { + store_hub: Some(ref hub), + state, + .. + } = &*app + else { + return None; + }; + + let store_id = re_log_types::StoreId::from_string( + re_log_types::StoreKind::Recording, + store_id.to_owned(), + ); + if !hub.store_bundle().contains(&store_id) { + return None; + }; + let rec_cfg = state.recording_config(&store_id)?; + + let time_ctrl = rec_cfg.time_ctrl.read(); + Some(time_ctrl.play_state() == re_viewer_context::PlayState::Playing) + } + + #[wasm_bindgen] + pub fn set_playing(&self, store_id: &str, value: bool) { + let Some(mut app) = self.runner.app_mut::() else { + return; + }; + let crate::App { + store_hub, + state, + egui_ctx, + .. + } = &mut *app; + + let Some(hub) = store_hub.as_ref() else { + return; + }; + let store_id = re_log_types::StoreId::from_string( + re_log_types::StoreKind::Recording, + store_id.to_owned(), + ); + let Some(recording) = hub.store_bundle().get(&store_id) else { + return; + }; + let Some(rec_cfg) = state.recording_config_mut(&store_id) else { + return; + }; + + let play_state = if value { + re_viewer_context::PlayState::Playing + } else { + re_viewer_context::PlayState::Paused + }; + + rec_cfg + .time_ctrl + .write() + .set_play_state(recording.times_per_timeline(), play_state); + egui_ctx.request_repaint(); + } } // TODO(jprochazk): figure out a way to auto-generate these types on JS side @@ -321,6 +587,7 @@ pub struct AppOptions { video_decoder: Option, hide_welcome_screen: Option, panel_state_overrides: Option, + timeline: Option, fullscreen: Option, enable_history: Option, @@ -328,6 +595,24 @@ pub struct AppOptions { persist: Option, } +// Keep in sync with the `TimelineOptions` interface in `rerun_js/web-viewer/index.ts` +#[derive(Clone, Deserialize)] +pub struct TimelineOptions { + /// Fired when the a different timeline is selected. + pub on_timelinechange: Callback, + + /// Fired when the timepoint changes. + /// + /// Does not fire when `on_seek` is called. + pub on_timeupdate: Callback, + + /// Fired when the timeline is paused. + pub on_pause: Callback, + + /// Fired when the timeline is played. + pub on_play: Callback, +} + // Keep in sync with the `FullscreenOptions` interface in `rerun_js/web-viewer/index.ts` #[derive(Clone, Deserialize)] pub struct FullscreenOptions { @@ -374,6 +659,7 @@ fn create_app( video_decoder, hide_welcome_screen, panel_state_overrides, + timeline, fullscreen, enable_history, @@ -403,6 +689,7 @@ fn create_app( force_wgpu_backend: render_backend.clone(), video_decoder_hw_acceleration, hide_welcome_screen: hide_welcome_screen.unwrap_or(false), + timeline_options: timeline.clone(), fullscreen_options: fullscreen.clone(), panel_state_overrides: panel_state_overrides.unwrap_or_default().into(), diff --git a/crates/viewer/re_viewer/src/web_tools.rs b/crates/viewer/re_viewer/src/web_tools.rs index 202615ed3d67..d56ce482077f 100644 --- a/crates/viewer/re_viewer/src/web_tools.rs +++ b/crates/viewer/re_viewer/src/web_tools.rs @@ -191,10 +191,22 @@ pub struct Callback(#[serde(with = "serde_wasm_bindgen::preserve")] js_sys::Func impl Callback { #[inline] - pub fn call(&self) -> Result { + pub fn call0(&self) -> Result { let window: JsValue = window()?.into(); self.0.call0(&window) } + + #[inline] + pub fn call1(&self, arg0: &JsValue) -> Result { + let window: JsValue = window()?.into(); + self.0.call1(&window, arg0) + } + + #[inline] + pub fn call2(&self, arg0: &JsValue, arg1: &JsValue) -> Result { + let window: JsValue = window()?.into(); + self.0.call2(&window, arg0, arg1) + } } // Deserializes from JS string or array of strings. diff --git a/crates/viewer/re_viewer_context/src/lib.rs b/crates/viewer/re_viewer_context/src/lib.rs index df0a25b94492..faaa5d6983d2 100644 --- a/crates/viewer/re_viewer_context/src/lib.rs +++ b/crates/viewer/re_viewer_context/src/lib.rs @@ -71,7 +71,7 @@ pub use self::{ store_context::StoreContext, store_hub::StoreHub, tensor::{ImageStats, TensorStats}, - time_control::{Looping, PlayState, TimeControl, TimeView}, + time_control::{Looping, PlayState, TimeControl, TimeView, TimelineCallbacks}, time_drag_value::TimeDragValue, typed_entity_collections::{ ApplicableEntities, IndicatedEntities, PerVisualizer, VisualizableEntities, diff --git a/crates/viewer/re_viewer_context/src/time_control.rs b/crates/viewer/re_viewer_context/src/time_control.rs index be5596ff3b3a..330b95dc8db7 100644 --- a/crates/viewer/re_viewer_context/src/time_control.rs +++ b/crates/viewer/re_viewer_context/src/time_control.rs @@ -1,4 +1,5 @@ use std::collections::BTreeMap; +use std::rc::Rc; use re_entity_db::{TimeCounts, TimesPerTimeline}; use re_log_types::{ @@ -107,14 +108,65 @@ impl std::ops::Deref for ActiveTimeline { } } +#[derive(Clone, PartialEq, serde::Deserialize, serde::Serialize)] +struct TimeStateEntry { + prev: TimeState, + current: TimeState, +} + +impl TimeStateEntry { + fn new(time: impl Into) -> Self { + let state = TimeState::new(time); + Self { + prev: state, + current: state, + } + } +} + +#[derive(serde::Deserialize, serde::Serialize, Clone, PartialEq)] +struct LastFrame { + timeline: Option, + playing: bool, +} + +impl Default for LastFrame { + fn default() -> Self { + Self { + timeline: None, + playing: true, + } + } +} + +// Keep in sync with the `TimelineOptions` interface in `rerun_js/web-viewer/index.ts` +#[derive(Clone)] +pub struct TimelineCallbacks { + /// Fired when the a different timeline is selected. + pub on_timelinechange: Rc, + + /// Fired when the timepoint changes. + /// + /// Does not fire when `on_seek` is called. + pub on_timeupdate: Rc, + + /// Fired when the timeline is paused. + pub on_pause: Rc, + + /// Fired when the timeline is played. + pub on_play: Rc, +} + /// Controls the global view and progress of the time. #[derive(serde::Deserialize, serde::Serialize, Clone, PartialEq)] #[serde(default)] pub struct TimeControl { + last_frame: LastFrame, + /// Name of the timeline (e.g. `log_time`). timeline: ActiveTimeline, - states: BTreeMap, + states: BTreeMap, /// If true, we are either in [`PlayState::Playing`] or [`PlayState::Following`]. playing: bool, @@ -137,6 +189,7 @@ pub struct TimeControl { impl Default for TimeControl { fn default() -> Self { Self { + last_frame: Default::default(), timeline: ActiveTimeline::Auto(default_timeline([])), states: Default::default(), playing: true, @@ -156,6 +209,7 @@ impl TimeControl { times_per_timeline: &TimesPerTimeline, stable_dt: f32, more_data_is_coming: bool, + callbacks: Option<&TimelineCallbacks>, ) -> NeedsRepaint { self.select_a_valid_timeline(times_per_timeline); @@ -163,14 +217,14 @@ impl TimeControl { return NeedsRepaint::No; // we have no data on this timeline yet, so bail }; - match self.play_state() { + let needs_repaint = match self.play_state() { PlayState::Paused => { // It's possible that the playback is paused because e.g. it reached its end, but // then the user decides to switch timelines. // When they do so, it might be the case that they switch to a timeline they've // never interacted with before, in which case we don't even have a time state yet. self.states.entry(*self.timeline).or_insert_with(|| { - TimeState::new(if self.following { + TimeStateEntry::new(if self.following { full_range.max() } else { full_range.min() @@ -184,11 +238,11 @@ impl TimeControl { let state = self .states .entry(*self.timeline) - .or_insert_with(|| TimeState::new(full_range.min())); + .or_insert_with(|| TimeStateEntry::new(full_range.min())); - if self.looping == Looping::Off && full_range.max() <= state.time { + if self.looping == Looping::Off && full_range.max() <= state.current.time { // We've reached the end of the data - state.time = full_range.max().into(); + state.current.time = full_range.max().into(); if more_data_is_coming { // then let's wait for it without pausing! @@ -201,24 +255,24 @@ impl TimeControl { let loop_range = match self.looping { Looping::Off => None, - Looping::Selection => state.loop_selection, + Looping::Selection => state.current.loop_selection, Looping::All => Some(full_range.into()), }; if let Some(loop_range) = loop_range { - state.time = state.time.max(loop_range.min); + state.current.time = state.current.time.max(loop_range.min); } match self.timeline.typ() { TimeType::Sequence => { - state.time += TimeReal::from(state.fps * dt); + state.current.time += TimeReal::from(state.current.fps * dt); } - TimeType::Time => state.time += TimeReal::from(Duration::from_secs(dt)), + TimeType::Time => state.current.time += TimeReal::from(Duration::from_secs(dt)), } if let Some(loop_range) = loop_range { - if loop_range.max < state.time { - state.time = loop_range.min; // loop! + if loop_range.max < state.current.time { + state.current.time = loop_range.min; // loop! } } @@ -228,14 +282,52 @@ impl TimeControl { // Set the time to the max: match self.states.entry(*self.timeline) { std::collections::btree_map::Entry::Vacant(entry) => { - entry.insert(TimeState::new(full_range.max())); + entry.insert(TimeStateEntry::new(full_range.max())); } std::collections::btree_map::Entry::Occupied(mut entry) => { - entry.get_mut().time = full_range.max().into(); + entry.get_mut().current.time = full_range.max().into(); } } NeedsRepaint::No // no need for request_repaint - we already repaint when new data arrives } + }; + + if let Some(callbacks) = callbacks { + self.handle_callbacks(callbacks); + } + + needs_repaint + } + + /// Handle updating last frame state and trigger callbacks on changes. + pub fn handle_callbacks(&mut self, callbacks: &TimelineCallbacks) { + if self.last_frame.playing != self.playing { + self.last_frame.playing = self.playing; + + if self.playing { + (callbacks.on_play)(); + } else { + (callbacks.on_pause)(); + } + } + + if self.last_frame.timeline != Some(*self.timeline) { + self.last_frame.timeline = Some(*self.timeline); + + let time = self + .time_for_timeline(*self.timeline) + .unwrap_or(TimeReal::MIN); + + (callbacks.on_timelinechange)(*self.timeline, time); + } + + if let Some(state) = self.states.get_mut(&self.timeline) { + // TODO(jan): throttle? + if state.prev.time != state.current.time { + state.prev.time = state.current.time; + + (callbacks.on_timeupdate)(state.current.time); + } } } @@ -279,12 +371,12 @@ impl TimeControl { // Start from beginning if we are at the end: if let Some(time_points) = times_per_timeline.get(&self.timeline) { if let Some(state) = self.states.get_mut(&self.timeline) { - if max(time_points) <= state.time { - state.time = min(time_points).into(); + if max(time_points) <= state.current.time { + state.current.time = min(time_points).into(); } } else { self.states - .insert(*self.timeline, TimeState::new(min(time_points))); + .insert(*self.timeline, TimeStateEntry::new(min(time_points))); } } } @@ -296,10 +388,10 @@ impl TimeControl { // Set the time to the max: match self.states.entry(*self.timeline) { std::collections::btree_map::Entry::Vacant(entry) => { - entry.insert(TimeState::new(max(time_points))); + entry.insert(TimeStateEntry::new(max(time_points))); } std::collections::btree_map::Entry::Occupied(mut entry) => { - entry.get_mut().time = max(time_points).into(); + entry.get_mut().current.time = max(time_points).into(); } } } @@ -350,7 +442,7 @@ impl TimeControl { pub fn restart(&mut self, times_per_timeline: &TimesPerTimeline) { if let Some(time_points) = times_per_timeline.get(&self.timeline) { if let Some(state) = self.states.get_mut(&self.timeline) { - state.time = min(time_points).into(); + state.current.time = min(time_points).into(); self.following = false; } } @@ -386,8 +478,8 @@ impl TimeControl { // Start from beginning if we are at the end: if let Some(time_points) = times_per_timeline.get(&self.timeline) { if let Some(state) = self.states.get_mut(&self.timeline) { - if max(time_points) <= state.time { - state.time = min(time_points).into(); + if max(time_points) <= state.current.time { + state.current.time = min(time_points).into(); self.playing = true; self.following = false; return; @@ -415,13 +507,15 @@ impl TimeControl { /// playback fps pub fn fps(&self) -> Option { - self.states.get(self.timeline()).map(|state| state.fps) + self.states + .get(self.timeline()) + .map(|state| state.current.fps) } /// playback fps pub fn set_fps(&mut self, fps: f32) { if let Some(state) = self.states.get_mut(&self.timeline) { - state.fps = fps; + state.current.fps = fps; } } @@ -461,7 +555,9 @@ impl TimeControl { /// The current time. pub fn time(&self) -> Option { - self.states.get(self.timeline()).map(|state| state.time) + self.states + .get(self.timeline()) + .map(|state| state.current.time) } /// The current time. @@ -485,7 +581,7 @@ impl TimeControl { /// The current loop range, iff selection looping is turned on. pub fn active_loop_selection(&self) -> Option { if self.looping == Looping::Selection { - self.states.get(self.timeline())?.loop_selection + self.states.get(self.timeline())?.current.loop_selection } else { None } @@ -500,21 +596,22 @@ impl TimeControl { /// /// This can still return `Some` even if looping is currently off. pub fn loop_selection(&self) -> Option { - self.states.get(self.timeline())?.loop_selection + self.states.get(self.timeline())?.current.loop_selection } /// Set the current loop selection without enabling looping. pub fn set_loop_selection(&mut self, selection: ResolvedTimeRangeF) { self.states .entry(*self.timeline) - .or_insert_with(|| TimeState::new(selection.min)) + .or_insert_with(|| TimeStateEntry::new(selection.min)) + .current .loop_selection = Some(selection); } /// Remove the current loop selection. pub fn remove_loop_selection(&mut self) { if let Some(state) = self.states.get_mut(&self.timeline) { - state.loop_selection = None; + state.current.loop_selection = None; } if self.looping() == Looping::Selection { self.set_looping(Looping::Off); @@ -528,7 +625,7 @@ impl TimeControl { } if let Some(state) = self.states.get(self.timeline()) { - state.time.floor() == needle + state.current.time.floor() == needle } else { false } @@ -539,12 +636,27 @@ impl TimeControl { self.set_time(time); } + pub fn time_for_timeline(&self, timeline: Timeline) -> Option { + self.states.get(&timeline).map(|state| state.current.time) + } + + pub fn set_time_for_timeline(&mut self, timeline: Timeline, time: impl Into) { + let time = time.into(); + + self.states + .entry(timeline) + .or_insert_with(|| TimeStateEntry::new(time)) + .current + .time = time; + } + pub fn set_time(&mut self, time: impl Into) { let time = time.into(); self.states .entry(*self.timeline) - .or_insert_with(|| TimeState::new(time)) + .or_insert_with(|| TimeStateEntry::new(time)) + .current .time = time; } @@ -552,21 +664,22 @@ impl TimeControl { pub fn time_view(&self) -> Option { self.states .get(self.timeline()) - .and_then(|state| state.view) + .and_then(|state| state.current.view) } /// The range of time we are currently zoomed in on. pub fn set_time_view(&mut self, view: TimeView) { self.states .entry(*self.timeline) - .or_insert_with(|| TimeState::new(view.min)) + .or_insert_with(|| TimeStateEntry::new(view.min)) + .current .view = Some(view); } /// The range of time we are currently zoomed in on. pub fn reset_time_view(&mut self) { if let Some(state) = self.states.get_mut(&self.timeline) { - state.view = None; + state.current.view = None; } } } diff --git a/rerun_js/package.json b/rerun_js/package.json index 77d6e52d2e30..05856f57a39d 100644 --- a/rerun_js/package.json +++ b/rerun_js/package.json @@ -11,5 +11,6 @@ "workspaces": [ "web-viewer", "web-viewer-react" - ] + ], + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/rerun_js/web-viewer/index.ts b/rerun_js/web-viewer/index.ts index e02b13b5cf2a..66d0e736b48d 100644 --- a/rerun_js/web-viewer/index.ts +++ b/rerun_js/web-viewer/index.ts @@ -101,16 +101,24 @@ export interface WebViewerOptions { export interface AppOptions extends WebViewerOptions { url?: string; manifest_url?: string; - video_decoder?: VideoDecoder, + video_decoder?: VideoDecoder; render_backend?: Backend; hide_welcome_screen?: boolean; panel_state_overrides?: Partial<{ [K in Panel]: PanelState; }>; + timeline?: TimelineOptions; fullscreen?: FullscreenOptions; enable_history?: boolean; } +interface TimelineOptions { + on_timelinechange: (timeline: string, time: number) => void; + on_timeupdate: (time: number) => void; + on_pause: () => void; + on_play: () => void; +} + interface FullscreenOptions { get_state: () => boolean; on_toggle: () => void; @@ -119,6 +127,11 @@ interface FullscreenOptions { interface WebViewerEvents { fullscreen: boolean; ready: void; + + timelinechange: [timeline_name: string, time: number]; + timeupdate: number; + play: void; + pause: void; } // This abomination is a mapped type with key filtering, and is used to split the events @@ -127,7 +140,9 @@ interface WebViewerEvents { type EventsWithValue = { [K in keyof WebViewerEvents as WebViewerEvents[K] extends void ? never - : K]: WebViewerEvents[K]; + : K]: WebViewerEvents[K] extends any[] + ? WebViewerEvents[K] + : [WebViewerEvents[K]]; }; type EventsWithoutValue = { @@ -197,7 +212,15 @@ export class WebViewer { } : undefined; - this.#handle = new WebHandle_class({ ...options, fullscreen }); + const timeline = { + on_timelinechange: (timeline: string, time: number) => + this.#dispatch_event("timelinechange", timeline, time), + on_timeupdate: (time: number) => this.#dispatch_event("timeupdate", time), + on_pause: () => this.#dispatch_event("pause"), + on_play: () => this.#dispatch_event("play"), + }; + + this.#handle = new WebHandle_class({ ...options, fullscreen, timeline }); try { await this.#handle.start(this.#canvas); } catch (e) { @@ -218,15 +241,15 @@ export class WebViewer { #event_map: Map< keyof WebViewerEvents, - Map<(value: any) => void, { once: boolean }> + Map<(...args: any[]) => void, { once: boolean }> > = new Map(); #dispatch_event( event: E, - value: EventsWithValue[E], + ...args: EventsWithValue[E] ): void; #dispatch_event(event: E): void; - #dispatch_event(event: any, value?: any): void { + #dispatch_event(event: any, ...args: any[]): void { // Dispatch events on next tick. // This is necessary because we may have been called somewhere deep within the viewer's call stack, // which means that `app` may be locked. The event will not actually be dispatched until the @@ -236,7 +259,7 @@ export class WebViewer { const callbacks = this.#event_map.get(event); if (callbacks) { for (const [callback, { once }] of [...callbacks.entries()]) { - callback(value); + callback(...args); if (once) callbacks.delete(callback); } } @@ -250,7 +273,7 @@ export class WebViewer { */ on( event: E, - callback: (value: EventsWithValue[E]) => void, + callback: (...args: EventsWithValue[E]) => void, ): Cancel; on( event: E, @@ -496,6 +519,149 @@ export class WebViewer { } } + /** + * Get the active recording id. + */ + get_active_recording_id(): string | null { + if (!this.#handle) { + throw new Error( + `attempted to get active recording id in a stopped web viewer`, + ); + } + + return this.#handle.get_active_recording_id() ?? null; + } + + /** + * Set the active recording id. + */ + set_active_recording_id(value: string) { + if (!this.#handle) { + throw new Error( + `attempted to set active recording id to ${value} in a stopped web viewer`, + ); + } + + this.#handle.set_active_recording_id(value); + } + + /** + * Get the play state. + * + * This always returns `false` if the recording can't be found. + */ + get_playing(recording_id: string): boolean { + if (!this.#handle) { + throw new Error(`attempted to get play state in a stopped web viewer`); + } + + return this.#handle.get_playing(recording_id) || false; + } + + /** + * Set the play state. + * + * This does nothing if the recording can't be found. + */ + set_playing(recording_id: string, value: boolean) { + if (!this.#handle) { + throw new Error( + `attempted to set play state to ${ + value ? "playing" : "paused" + } in a stopped web viewer`, + ); + } + + this.#handle.set_playing(recording_id, value); + } + + /** + * Get the current time. + * + * The interpretation of time depends on what kind of timeline it is: + * + * - For time timelines, this is the time in nanoseconds. + * - For sequence timelines, this is the sequence number. + * + * This always returns `0` if the recording or timeline can't be found. + */ + get_current_time(recording_id: string, timeline: string): number { + if (!this.#handle) { + throw new Error(`attempted to get current time in a stopped web viewer`); + } + + return this.#handle.get_time_for_timeline(recording_id, timeline) || 0; + } + + /** + * Set the current time. + * + * Equivalent to clicking on the timeline in the time panel at the specified `time`. + * The interpretation of `time` depends on what kind of timeline it is: + * + * - For time timelines, this is the time in nanoseconds. + * - For sequence timelines, this is the sequence number. + * + * This does nothing if the recording or timeline can't be found. + * + * @param value + */ + set_current_time(recording_id: string, timeline: string, time: number) { + if (!this.#handle) { + throw new Error( + `attempted to set current time to ${time} in a stopped web viewer`, + ); + } + + this.#handle.set_time_for_timeline(recording_id, timeline, time); + } + + /** + * Get the active timeline. + * + * This always returns `null` if the recording can't be found. + */ + get_active_timeline(recording_id: string): string | null { + if (!this.#handle) { + throw new Error( + `attempted to get active timeline in a stopped web viewer`, + ); + } + + return this.#handle.get_active_timeline(recording_id) ?? null; + } + + /** + * Set the active timeline. + * + * This does nothing if the recording or timeline can't be found. + */ + set_active_timeline(recording_id: string, timeline: string) { + if (!this.#handle) { + throw new Error( + `attempted to set active timeline to ${timeline} in a stopped web viewer`, + ); + } + + this.#handle.set_active_timeline(recording_id, timeline); + } + + /** + * Get the time range for a timeline. + * + * This always returns `null` if the recording or timeline can't be found. + */ + get_time_range( + recording_id: string, + timeline: string, + ): { min: number; max: number } | null { + if (!this.#handle) { + throw new Error(`attempted to get time range in a stopped web viewer`); + } + + return this.#handle.get_timeline_time_range(recording_id, timeline); + } + /** * Toggle fullscreen mode. * From ac80fbc2687daaea9cf26305b275a23c200cadaa Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 15 Jan 2025 17:08:17 +0100 Subject: [PATCH 43/57] Use full chunk table format for snapshot tests (#8699) * Part of #3741 Will make it easier to switch out the `TransportChunk` for an `RecordBatch` and still have the same test output --- crates/store/re_dataframe/src/query.rs | 51 ++++++++++--------- ..._query__tests__async_barebones_static.snap | 27 ++++++---- ...uery__tests__async_barebones_temporal.snap | 39 ++++++++++---- ..._dataframe__query__tests__barebones-2.snap | 39 ++++++++++---- ...re_dataframe__query__tests__barebones.snap | 27 ++++++---- .../re_dataframe__query__tests__clears-2.snap | 41 +++++++++++---- .../re_dataframe__query__tests__clears.snap | 41 +++++++++++---- ...e__query__tests__filtered_index_range.snap | 33 ++++++++---- ...__query__tests__filtered_index_values.snap | 29 +++++++---- ..._query__tests__filtered_is_not_null-2.snap | 14 +++-- ..._query__tests__filtered_is_not_null-3.snap | 39 ++++++++++---- ..._query__tests__filtered_is_not_null-4.snap | 33 ++++++++---- ...e__query__tests__filtered_is_not_null.snap | 12 ++++- ..._dataframe__query__tests__selection-2.snap | 34 ++++++++++--- ..._dataframe__query__tests__selection-3.snap | 37 +++++++++++--- ..._dataframe__query__tests__selection-4.snap | 50 ++++++++++++------ ...re_dataframe__query__tests__selection.snap | 6 ++- ...__sparse_fill_strategy_latestatglobal.snap | 39 ++++++++++---- ...e__query__tests__using_index_values-2.snap | 39 ++++++++++---- ...ame__query__tests__using_index_values.snap | 39 ++++++++++---- ...aframe__query__tests__view_contents-2.snap | 31 ++++++++--- ...ataframe__query__tests__view_contents.snap | 10 +++- ...y__tests__view_contents_and_selection.snap | 34 +++++++++---- 23 files changed, 547 insertions(+), 197 deletions(-) diff --git a/crates/store/re_dataframe/src/query.rs b/crates/store/re_dataframe/src/query.rs index 1a5c6358ba50..b57579be1f04 100644 --- a/crates/store/re_dataframe/src/query.rs +++ b/crates/store/re_dataframe/src/query.rs @@ -1323,7 +1323,6 @@ impl QueryHandle { mod tests { use std::sync::Arc; - use insta::assert_debug_snapshot; use re_chunk::{ concat_record_batches::concatenate_record_batches, Chunk, ChunkId, RowId, TimePoint, TransportChunk, @@ -1344,6 +1343,12 @@ mod tests { use super::*; + macro_rules! assert_snapshot_fixed_width { + ($($arg:tt)*) => { + insta::_assert_snapshot_base!(transform=|v| std::format!("{v:200}"), $($arg)*) + }; + } + // NOTE: The best way to understand what these tests are doing is to run them in verbose mode, // e.g. `cargo t -p re_dataframe -- --show-output barebones`. // Each test will print the state of the store, the query being run, and the results that were @@ -1399,7 +1404,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } // temporal @@ -1421,7 +1426,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } Ok(()) @@ -1455,7 +1460,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); Ok(()) } @@ -1488,7 +1493,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); Ok(()) } @@ -1527,7 +1532,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); Ok(()) } @@ -1569,7 +1574,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } // sparse-filled @@ -1599,7 +1604,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } Ok(()) @@ -1640,7 +1645,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } // non-existing component @@ -1666,7 +1671,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } // MyPoint @@ -1692,7 +1697,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } // MyColor @@ -1718,7 +1723,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } Ok(()) @@ -1760,7 +1765,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } { @@ -1797,7 +1802,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } Ok(()) @@ -1835,7 +1840,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } // only indices (+ duplication) @@ -1868,7 +1873,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } // only components (+ duplication) @@ -1908,7 +1913,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } // static @@ -1969,7 +1974,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } Ok(()) @@ -2038,7 +2043,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } Ok(()) @@ -2078,7 +2083,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } // sparse-filled @@ -2106,7 +2111,7 @@ mod tests { // static clear semantics in general are pretty unhinged right now, especially when // ranges are involved. // It's extremely niche, our time is better spent somewhere else right now. - assert_debug_snapshot!(dataframe.columns()); + assert_snapshot_fixed_width!(dataframe); } Ok(()) @@ -2344,7 +2349,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!("async_barebones_static", dataframe.columns()); + assert_snapshot_fixed_width!("async_barebones_static", dataframe); Ok::<_, anyhow::Error>(()) } @@ -2375,7 +2380,7 @@ mod tests { )?; eprintln!("{dataframe}"); - assert_debug_snapshot!("async_barebones_temporal", dataframe.columns()); + assert_snapshot_fixed_width!("async_barebones_temporal", dataframe); Ok::<_, anyhow::Error>(()) } diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__async_barebones_static.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__async_barebones_static.snap index ec3f6001de19..cbe93814410d 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__async_barebones_static.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__async_barebones_static.snap @@ -1,13 +1,22 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 2347 -expression: dataframe.columns() +assertion_line: 2353 +expression: dataframe snapshot_kind: text --- -[ - Int64[None], - Timestamp(Nanosecond, None)[None], - ListArray[None], - ListArray[[c]], - ListArray[None], -] +┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌───────────────────────────────┬───────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┐ │ +│ │ frame_nr ┆ log_time ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel ┆ /this/that:example.MyPoint │ │ +│ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ +│ │ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[Utf8]" ┆ type: "List[Struct[2]]" │ │ +│ │ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" ┆ sorbet.path: "/this/that" │ │ +│ │ ┆ ┆ sorbet.semantic_type: ┆ sorbet.path: "/this/that" ┆ sorbet.semantic_type: │ │ +│ │ ┆ ┆ "example.MyColor" ┆ sorbet.semantic_type: ┆ "example.MyPoint" │ │ +│ │ ┆ ┆ ┆ "example.MyLabel" ┆ │ │ +│ ╞═══════════════════════════════╪═══════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╡ │ +│ │ ┆ ┆ ┆ [c] ┆ │ │ +│ └───────────────────────────────┴───────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┘ │ +└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__async_barebones_temporal.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__async_barebones_temporal.snap index a037d330cd2c..fdade9434831 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__async_barebones_temporal.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__async_barebones_temporal.snap @@ -1,13 +1,34 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 2378 -expression: dataframe.columns() +assertion_line: 2384 +expression: dataframe snapshot_kind: text --- -[ - Int64[10, 20, 30, 40, 50, 60, 70], - Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, None, 1970-01-01 00:00:00.000000070], - ListArray[None, None, [2], [3], [4], None, [6]], - ListArray[[c], [c], [c], [c], [c], [c], [c]], - ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 5, y: 5}], [{x: 8, y: 8}]], -] +┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌───────────────────────────────┬───────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┐ │ +│ │ frame_nr ┆ log_time ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel ┆ /this/that:example.MyPoint │ │ +│ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ +│ │ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[Utf8]" ┆ type: "List[Struct[2]]" │ │ +│ │ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" ┆ sorbet.path: "/this/that" │ │ +│ │ ┆ ┆ sorbet.semantic_type: ┆ sorbet.path: "/this/that" ┆ sorbet.semantic_type: │ │ +│ │ ┆ ┆ "example.MyColor" ┆ sorbet.semantic_type: ┆ "example.MyPoint" │ │ +│ │ ┆ ┆ ┆ "example.MyLabel" ┆ │ │ +│ ╞═══════════════════════════════╪═══════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╡ │ +│ │ 10 ┆ 1970-01-01T00:00:00.000000010 ┆ ┆ [c] ┆ [{x: 0.0, y: 0.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 20 ┆ ┆ ┆ [c] ┆ [{x: 1.0, y: 1.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 30 ┆ ┆ [2] ┆ [c] ┆ [{x: 2.0, y: 2.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 40 ┆ ┆ [3] ┆ [c] ┆ [{x: 3.0, y: 3.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 50 ┆ 1970-01-01T00:00:00.000000050 ┆ [4] ┆ [c] ┆ [{x: 4.0, y: 4.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 60 ┆ ┆ ┆ [c] ┆ [{x: 5.0, y: 5.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 70 ┆ 1970-01-01T00:00:00.000000070 ┆ [6] ┆ [c] ┆ [{x: 8.0, y: 8.0}] │ │ +│ └───────────────────────────────┴───────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┘ │ +└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__barebones-2.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__barebones-2.snap index f143af9dbdba..eca4768c6474 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__barebones-2.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__barebones-2.snap @@ -1,13 +1,34 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 1424 -expression: dataframe.all_columns_collected() +assertion_line: 1429 +expression: dataframe snapshot_kind: text --- -[ - Int64[10, 20, 30, 40, 50, 60, 70], - Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, None, 1970-01-01 00:00:00.000000070], - ListArray[None, None, [2], [3], [4], None, [6]], - ListArray[[c], [c], [c], [c], [c], [c], [c]], - ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 5, y: 5}], [{x: 8, y: 8}]], -] +┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌───────────────────────────────┬───────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┐ │ +│ │ frame_nr ┆ log_time ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel ┆ /this/that:example.MyPoint │ │ +│ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ +│ │ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[Utf8]" ┆ type: "List[Struct[2]]" │ │ +│ │ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" ┆ sorbet.path: "/this/that" │ │ +│ │ ┆ ┆ sorbet.semantic_type: ┆ sorbet.path: "/this/that" ┆ sorbet.semantic_type: │ │ +│ │ ┆ ┆ "example.MyColor" ┆ sorbet.semantic_type: ┆ "example.MyPoint" │ │ +│ │ ┆ ┆ ┆ "example.MyLabel" ┆ │ │ +│ ╞═══════════════════════════════╪═══════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╡ │ +│ │ 10 ┆ 1970-01-01T00:00:00.000000010 ┆ ┆ [c] ┆ [{x: 0.0, y: 0.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 20 ┆ ┆ ┆ [c] ┆ [{x: 1.0, y: 1.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 30 ┆ ┆ [2] ┆ [c] ┆ [{x: 2.0, y: 2.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 40 ┆ ┆ [3] ┆ [c] ┆ [{x: 3.0, y: 3.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 50 ┆ 1970-01-01T00:00:00.000000050 ┆ [4] ┆ [c] ┆ [{x: 4.0, y: 4.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 60 ┆ ┆ ┆ [c] ┆ [{x: 5.0, y: 5.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 70 ┆ 1970-01-01T00:00:00.000000070 ┆ [6] ┆ [c] ┆ [{x: 8.0, y: 8.0}] │ │ +│ └───────────────────────────────┴───────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┘ │ +└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__barebones.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__barebones.snap index f3b4325d5236..aaca718fa9d2 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__barebones.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__barebones.snap @@ -1,13 +1,22 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 1402 -expression: dataframe.all_columns_collected() +assertion_line: 1408 +expression: dataframe snapshot_kind: text --- -[ - Int64[None], - Timestamp(Nanosecond, None)[None], - ListArray[None], - ListArray[[c]], - ListArray[None], -] +┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌───────────────────────────────┬───────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┐ │ +│ │ frame_nr ┆ log_time ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel ┆ /this/that:example.MyPoint │ │ +│ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ +│ │ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[Utf8]" ┆ type: "List[Struct[2]]" │ │ +│ │ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" ┆ sorbet.path: "/this/that" │ │ +│ │ ┆ ┆ sorbet.semantic_type: ┆ sorbet.path: "/this/that" ┆ sorbet.semantic_type: │ │ +│ │ ┆ ┆ "example.MyColor" ┆ sorbet.semantic_type: ┆ "example.MyPoint" │ │ +│ │ ┆ ┆ ┆ "example.MyLabel" ┆ │ │ +│ ╞═══════════════════════════════╪═══════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╡ │ +│ │ ┆ ┆ ┆ [c] ┆ │ │ +│ └───────────────────────────────┴───────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┘ │ +└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__clears-2.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__clears-2.snap index afc62129c581..8233f425b950 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__clears-2.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__clears-2.snap @@ -1,13 +1,36 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 2109 -expression: dataframe.all_columns_collected() +assertion_line: 2114 +expression: dataframe snapshot_kind: text --- -[ - Int64[10, 20, 30, 40, 50, 60, 65, 70], - Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, 1970-01-01 00:00:00.000000060, 1970-01-01 00:00:00.000000065, 1970-01-01 00:00:00.000000070], - ListArray[None, None, [2], [3], [4], [], [], [6]], - ListArray[[c], [c], [c], [c], [c], [c], [c], [c]], - ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [], [], [{x: 8, y: 8}]], -] +┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌───────────────────────────────┬───────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┐ │ +│ │ frame_nr ┆ log_time ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel ┆ /this/that:example.MyPoint │ │ +│ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ +│ │ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[Utf8]" ┆ type: "List[Struct[2]]" │ │ +│ │ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" ┆ sorbet.path: "/this/that" │ │ +│ │ ┆ ┆ sorbet.semantic_type: ┆ sorbet.path: "/this/that" ┆ sorbet.semantic_type: │ │ +│ │ ┆ ┆ "example.MyColor" ┆ sorbet.semantic_type: ┆ "example.MyPoint" │ │ +│ │ ┆ ┆ ┆ "example.MyLabel" ┆ │ │ +│ ╞═══════════════════════════════╪═══════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╡ │ +│ │ 10 ┆ 1970-01-01T00:00:00.000000010 ┆ ┆ [c] ┆ [{x: 0.0, y: 0.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 20 ┆ ┆ ┆ [c] ┆ [{x: 1.0, y: 1.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 30 ┆ ┆ [2] ┆ [c] ┆ [{x: 2.0, y: 2.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 40 ┆ ┆ [3] ┆ [c] ┆ [{x: 3.0, y: 3.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 50 ┆ 1970-01-01T00:00:00.000000050 ┆ [4] ┆ [c] ┆ [{x: 4.0, y: 4.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 60 ┆ 1970-01-01T00:00:00.000000060 ┆ [] ┆ [c] ┆ [] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 65 ┆ 1970-01-01T00:00:00.000000065 ┆ [] ┆ [c] ┆ [] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 70 ┆ 1970-01-01T00:00:00.000000070 ┆ [6] ┆ [c] ┆ [{x: 8.0, y: 8.0}] │ │ +│ └───────────────────────────────┴───────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┘ │ +└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__clears.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__clears.snap index bffc10269340..619d85efad1c 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__clears.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__clears.snap @@ -1,13 +1,36 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 2081 -expression: dataframe.all_columns_collected() +assertion_line: 2087 +expression: dataframe snapshot_kind: text --- -[ - Int64[10, 20, 30, 40, 50, 60, 65, 70], - Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, 1970-01-01 00:00:00.000000060, 1970-01-01 00:00:00.000000065, 1970-01-01 00:00:00.000000070], - ListArray[None, None, [2], [3], [4], [], [], [6]], - ListArray[[c], [c], [c], [c], [c], [c], [c], [c]], - ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [], [], [{x: 8, y: 8}]], -] +┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌───────────────────────────────┬───────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┐ │ +│ │ frame_nr ┆ log_time ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel ┆ /this/that:example.MyPoint │ │ +│ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ +│ │ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[Utf8]" ┆ type: "List[Struct[2]]" │ │ +│ │ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" ┆ sorbet.path: "/this/that" │ │ +│ │ ┆ ┆ sorbet.semantic_type: ┆ sorbet.path: "/this/that" ┆ sorbet.semantic_type: │ │ +│ │ ┆ ┆ "example.MyColor" ┆ sorbet.semantic_type: ┆ "example.MyPoint" │ │ +│ │ ┆ ┆ ┆ "example.MyLabel" ┆ │ │ +│ ╞═══════════════════════════════╪═══════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╡ │ +│ │ 10 ┆ 1970-01-01T00:00:00.000000010 ┆ ┆ [c] ┆ [{x: 0.0, y: 0.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 20 ┆ ┆ ┆ [c] ┆ [{x: 1.0, y: 1.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 30 ┆ ┆ [2] ┆ [c] ┆ [{x: 2.0, y: 2.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 40 ┆ ┆ [3] ┆ [c] ┆ [{x: 3.0, y: 3.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 50 ┆ 1970-01-01T00:00:00.000000050 ┆ [4] ┆ [c] ┆ [{x: 4.0, y: 4.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 60 ┆ 1970-01-01T00:00:00.000000060 ┆ [] ┆ [c] ┆ [] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 65 ┆ 1970-01-01T00:00:00.000000065 ┆ [] ┆ [c] ┆ [] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 70 ┆ 1970-01-01T00:00:00.000000070 ┆ [6] ┆ [c] ┆ [{x: 8.0, y: 8.0}] │ │ +│ └───────────────────────────────┴───────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┘ │ +└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_index_range.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_index_range.snap index 08ebd00df026..711f55766574 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_index_range.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_index_range.snap @@ -1,13 +1,28 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 1491 -expression: dataframe.all_columns_collected() +assertion_line: 1497 +expression: dataframe snapshot_kind: text --- -[ - Int64[30, 40, 50, 60], - Timestamp(Nanosecond, None)[None, None, 1970-01-01 00:00:00.000000050, None], - ListArray[[2], [3], [4], None], - ListArray[[c], [c], [c], [c]], - ListArray[[{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 5, y: 5}]], -] +┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌───────────────────────────────┬───────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┐ │ +│ │ frame_nr ┆ log_time ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel ┆ /this/that:example.MyPoint │ │ +│ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ +│ │ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[Utf8]" ┆ type: "List[Struct[2]]" │ │ +│ │ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" ┆ sorbet.path: "/this/that" │ │ +│ │ ┆ ┆ sorbet.semantic_type: ┆ sorbet.path: "/this/that" ┆ sorbet.semantic_type: │ │ +│ │ ┆ ┆ "example.MyColor" ┆ sorbet.semantic_type: ┆ "example.MyPoint" │ │ +│ │ ┆ ┆ ┆ "example.MyLabel" ┆ │ │ +│ ╞═══════════════════════════════╪═══════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╡ │ +│ │ 30 ┆ ┆ [2] ┆ [c] ┆ [{x: 2.0, y: 2.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 40 ┆ ┆ [3] ┆ [c] ┆ [{x: 3.0, y: 3.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 50 ┆ 1970-01-01T00:00:00.000000050 ┆ [4] ┆ [c] ┆ [{x: 4.0, y: 4.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 60 ┆ ┆ ┆ [c] ┆ [{x: 5.0, y: 5.0}] │ │ +│ └───────────────────────────────┴───────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┘ │ +└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_index_values.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_index_values.snap index e537db4b0d30..281d84b9f30f 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_index_values.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_index_values.snap @@ -1,13 +1,24 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 1530 -expression: dataframe.all_columns_collected() +assertion_line: 1536 +expression: dataframe snapshot_kind: text --- -[ - Int64[30, 60], - Timestamp(Nanosecond, None)[None, None], - ListArray[[2], None], - ListArray[[c], [c]], - ListArray[[{x: 2, y: 2}], [{x: 5, y: 5}]], -] +┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌───────────────────────────────┬───────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┐ │ +│ │ frame_nr ┆ log_time ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel ┆ /this/that:example.MyPoint │ │ +│ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ +│ │ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[Utf8]" ┆ type: "List[Struct[2]]" │ │ +│ │ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" ┆ sorbet.path: "/this/that" │ │ +│ │ ┆ ┆ sorbet.semantic_type: ┆ sorbet.path: "/this/that" ┆ sorbet.semantic_type: │ │ +│ │ ┆ ┆ "example.MyColor" ┆ sorbet.semantic_type: ┆ "example.MyPoint" │ │ +│ │ ┆ ┆ ┆ "example.MyLabel" ┆ │ │ +│ ╞═══════════════════════════════╪═══════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╡ │ +│ │ 30 ┆ ┆ [2] ┆ [c] ┆ [{x: 2.0, y: 2.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 60 ┆ ┆ ┆ [c] ┆ [{x: 5.0, y: 5.0}] │ │ +│ └───────────────────────────────┴───────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┘ │ +└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-2.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-2.snap index 7ddef2114658..a99a4c44ace7 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-2.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-2.snap @@ -1,7 +1,15 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 1669 -expression: dataframe.all_columns_collected() +assertion_line: 1675 +expression: dataframe snapshot_kind: text --- -[] +┌───────────────────────────────┬───────────────────────────────┬─────────────────────────────────────────┬─────────────────────────────────────────┬─────────────────────────────────────────┐ +│ frame_nr ┆ log_time ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel ┆ /this/that:example.MyPoint │ +│ --- ┆ --- ┆ --- ┆ --- ┆ --- │ +│ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[Utf8]" ┆ type: "List[Struct[2]]" │ +│ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" ┆ sorbet.path: "/this/that" │ +│ ┆ ┆ sorbet.semantic_type: "example.MyColor" ┆ sorbet.path: "/this/that" ┆ sorbet.semantic_type: "example.MyPoint" │ +│ ┆ ┆ ┆ sorbet.semantic_type: "example.MyLabel" ┆ │ +╞═══════════════════════════════╪═══════════════════════════════╪═════════════════════════════════════════╪═════════════════════════════════════════╪═════════════════════════════════════════╡ +└───────────────────────────────┴───────────────────────────────┴─────────────────────────────────────────┴─────────────────────────────────────────┴─────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-3.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-3.snap index 672f02d24438..f7d240711e6d 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-3.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-3.snap @@ -1,13 +1,34 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 1695 -expression: dataframe.all_columns_collected() +assertion_line: 1700 +expression: dataframe snapshot_kind: text --- -[ - Int64[10, 20, 30, 40, 50, 60, 70], - Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, None, 1970-01-01 00:00:00.000000070], - ListArray[None, None, [2], [3], [4], None, [6]], - ListArray[[c], [c], [c], [c], [c], [c], [c]], - ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 5, y: 5}], [{x: 8, y: 8}]], -] +┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌───────────────────────────────┬───────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┐ │ +│ │ frame_nr ┆ log_time ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel ┆ /this/that:example.MyPoint │ │ +│ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ +│ │ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[Utf8]" ┆ type: "List[Struct[2]]" │ │ +│ │ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" ┆ sorbet.path: "/this/that" │ │ +│ │ ┆ ┆ sorbet.semantic_type: ┆ sorbet.path: "/this/that" ┆ sorbet.semantic_type: │ │ +│ │ ┆ ┆ "example.MyColor" ┆ sorbet.semantic_type: ┆ "example.MyPoint" │ │ +│ │ ┆ ┆ ┆ "example.MyLabel" ┆ │ │ +│ ╞═══════════════════════════════╪═══════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╡ │ +│ │ 10 ┆ 1970-01-01T00:00:00.000000010 ┆ ┆ [c] ┆ [{x: 0.0, y: 0.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 20 ┆ ┆ ┆ [c] ┆ [{x: 1.0, y: 1.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 30 ┆ ┆ [2] ┆ [c] ┆ [{x: 2.0, y: 2.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 40 ┆ ┆ [3] ┆ [c] ┆ [{x: 3.0, y: 3.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 50 ┆ 1970-01-01T00:00:00.000000050 ┆ [4] ┆ [c] ┆ [{x: 4.0, y: 4.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 60 ┆ ┆ ┆ [c] ┆ [{x: 5.0, y: 5.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 70 ┆ 1970-01-01T00:00:00.000000070 ┆ [6] ┆ [c] ┆ [{x: 8.0, y: 8.0}] │ │ +│ └───────────────────────────────┴───────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┘ │ +└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-4.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-4.snap index e913daa93261..94729d8fa8eb 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-4.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null-4.snap @@ -1,13 +1,28 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 1721 -expression: dataframe.all_columns_collected() +assertion_line: 1726 +expression: dataframe snapshot_kind: text --- -[ - Int64[30, 40, 50, 70], - Timestamp(Nanosecond, None)[None, None, 1970-01-01 00:00:00.000000050, 1970-01-01 00:00:00.000000070], - ListArray[[2], [3], [4], [6]], - ListArray[[c], [c], [c], [c]], - ListArray[[{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 8, y: 8}]], -] +┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌───────────────────────────────┬───────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┐ │ +│ │ frame_nr ┆ log_time ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel ┆ /this/that:example.MyPoint │ │ +│ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ +│ │ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[Utf8]" ┆ type: "List[Struct[2]]" │ │ +│ │ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" ┆ sorbet.path: "/this/that" │ │ +│ │ ┆ ┆ sorbet.semantic_type: ┆ sorbet.path: "/this/that" ┆ sorbet.semantic_type: │ │ +│ │ ┆ ┆ "example.MyColor" ┆ sorbet.semantic_type: ┆ "example.MyPoint" │ │ +│ │ ┆ ┆ ┆ "example.MyLabel" ┆ │ │ +│ ╞═══════════════════════════════╪═══════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╡ │ +│ │ 30 ┆ ┆ [2] ┆ [c] ┆ [{x: 2.0, y: 2.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 40 ┆ ┆ [3] ┆ [c] ┆ [{x: 3.0, y: 3.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 50 ┆ 1970-01-01T00:00:00.000000050 ┆ [4] ┆ [c] ┆ [{x: 4.0, y: 4.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 70 ┆ 1970-01-01T00:00:00.000000070 ┆ [6] ┆ [c] ┆ [{x: 8.0, y: 8.0}] │ │ +│ └───────────────────────────────┴───────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┘ │ +└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null.snap index f18b0ee5e796..f3e086b9da57 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__filtered_is_not_null.snap @@ -1,7 +1,15 @@ --- source: crates/store/re_dataframe/src/query.rs assertion_line: 1643 -expression: dataframe.all_columns_collected() +expression: dataframe snapshot_kind: text --- -[] +┌───────────────────────────────┬───────────────────────────────┬─────────────────────────────────────────┬─────────────────────────────────────────┬─────────────────────────────────────────┐ +│ frame_nr ┆ log_time ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel ┆ /this/that:example.MyPoint │ +│ --- ┆ --- ┆ --- ┆ --- ┆ --- │ +│ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[Utf8]" ┆ type: "List[Struct[2]]" │ +│ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" ┆ sorbet.path: "/this/that" │ +│ ┆ ┆ sorbet.semantic_type: "example.MyColor" ┆ sorbet.path: "/this/that" ┆ sorbet.semantic_type: "example.MyPoint" │ +│ ┆ ┆ ┆ sorbet.semantic_type: "example.MyLabel" ┆ │ +╞═══════════════════════════════╪═══════════════════════════════╪═════════════════════════════════════════╪═════════════════════════════════════════╪═════════════════════════════════════════╡ +└───────────────────────────────┴───────────────────────────────┴─────────────────────────────────────────┴─────────────────────────────────────────┴─────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-2.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-2.snap index 821038ac14e8..e94d91a9ea02 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-2.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-2.snap @@ -1,11 +1,31 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 1871 -expression: dataframe.all_columns_collected() +assertion_line: 1877 +expression: dataframe snapshot_kind: text --- -[ - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - NullArray(7), -] +┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌───────────────────────────────┬───────────────────────────────┬─────────────────────────────────────────────────┐ │ +│ │ frame_nr ┆ frame_nr ┆ ATimeColumnThatDoesntExist │ │ +│ │ --- ┆ --- ┆ --- │ │ +│ │ type: "i64" ┆ type: "i64" ┆ type: "null" │ │ +│ │ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "ATimeColumnThatDoesntExist" │ │ +│ ╞═══════════════════════════════╪═══════════════════════════════╪═════════════════════════════════════════════════╡ │ +│ │ 10 ┆ 10 ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 20 ┆ 20 ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 30 ┆ 30 ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 40 ┆ 40 ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 50 ┆ 50 ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 60 ┆ 60 ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 70 ┆ 70 ┆ │ │ +│ └───────────────────────────────┴───────────────────────────────┴─────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-3.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-3.snap index d78191b475bf..a958131455c4 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-3.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-3.snap @@ -1,12 +1,33 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 1911 -expression: dataframe.all_columns_collected() +assertion_line: 1916 +expression: dataframe snapshot_kind: text --- -[ - ListArray[None, None, [2], [3], [4], None, [6]], - ListArray[None, None, [2], [3], [4], None, [6]], - NullArray(7), - NullArray(7), -] +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌─────────────────────────────────────────┬─────────────────────────────────────────┬─────────────────────────────────────────┬────────────────────────────────────────────────┐ │ +│ │ /this/that:example.MyColor ┆ /this/that:example.MyColor ┆ /non_existing_entity:example.MyColor ┆ /this/that:AComponentColumnThatDoesntExist │ │ +│ │ --- ┆ --- ┆ --- ┆ --- │ │ +│ │ type: "List[u32]" ┆ type: "List[u32]" ┆ type: "null" ┆ type: "null" │ │ +│ │ sorbet.path: "/this/that" ┆ sorbet.path: "/this/that" ┆ sorbet.path: "/non_existing_entity" ┆ sorbet.path: "/this/that" │ │ +│ │ sorbet.semantic_type: "example.MyColor" ┆ sorbet.semantic_type: "example.MyColor" ┆ sorbet.semantic_type: "example.MyColor" ┆ sorbet.semantic_type: │ │ +│ │ ┆ ┆ ┆ "AComponentColumnThatDoesntExist" │ │ +│ ╞═════════════════════════════════════════╪═════════════════════════════════════════╪═════════════════════════════════════════╪════════════════════════════════════════════════╡ │ +│ │ ┆ ┆ ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ ┆ ┆ ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ [2] ┆ [2] ┆ ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ [3] ┆ [3] ┆ ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ [4] ┆ [4] ┆ ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ ┆ ┆ ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ [6] ┆ [6] ┆ ┆ │ │ +│ └─────────────────────────────────────────┴─────────────────────────────────────────┴─────────────────────────────────────────┴────────────────────────────────────────────────┘ │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-4.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-4.snap index ab708132a72b..3e33a0898bbb 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-4.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection-4.snap @@ -1,19 +1,39 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 1972 -expression: dataframe.all_columns_collected() +assertion_line: 1977 +expression: dataframe snapshot_kind: text --- -[ - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - Int64[10, 20, 30, 40, 50, 60, 70], - ListArray[[c], [c], [c], [c], [c], [c], [c]], -] +┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┬────────────────┐ │ +│ │ frame_nr ┆ frame_nr ┆ frame_nr ┆ frame_nr ┆ frame_nr ┆ frame_nr ┆ frame_nr ┆ frame_nr ┆ frame_nr ┆ frame_nr ┆ /this/that:exa │ │ +│ │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ mple.MyLabel │ │ +│ │ type: "i64" ┆ type: "i64" ┆ type: "i64" ┆ type: "i64" ┆ type: "i64" ┆ type: "i64" ┆ type: "i64" ┆ type: "i64" ┆ type: "i64" ┆ type: "i64" ┆ --- │ │ +│ │ sorbet.index_n ┆ sorbet.index_n ┆ sorbet.index_n ┆ sorbet.index_n ┆ sorbet.index_n ┆ sorbet.index_n ┆ sorbet.index_n ┆ sorbet.index_n ┆ sorbet.index_n ┆ sorbet.index_n ┆ type: │ │ +│ │ ame: ┆ ame: ┆ ame: ┆ ame: ┆ ame: ┆ ame: ┆ ame: ┆ ame: ┆ ame: ┆ ame: ┆ "List[Utf8]" │ │ +│ │ "frame_nr" ┆ "frame_nr" ┆ "frame_nr" ┆ "frame_nr" ┆ "frame_nr" ┆ "frame_nr" ┆ "frame_nr" ┆ "frame_nr" ┆ "frame_nr" ┆ "frame_nr" ┆ sorbet.is_stat │ │ +│ │ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ic: "yes" │ │ +│ │ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ sorbet.path: │ │ +│ │ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ "/this/that" │ │ +│ │ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ sorbet.semanti │ │ +│ │ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ c_type: "examp │ │ +│ │ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ le.MyLabel" │ │ +│ ╞════════════════╪════════════════╪════════════════╪════════════════╪════════════════╪════════════════╪════════════════╪════════════════╪════════════════╪════════════════╪════════════════╡ │ +│ │ 10 ┆ 10 ┆ 10 ┆ 10 ┆ 10 ┆ 10 ┆ 10 ┆ 10 ┆ 10 ┆ 10 ┆ [c] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 20 ┆ 20 ┆ 20 ┆ 20 ┆ 20 ┆ 20 ┆ 20 ┆ 20 ┆ 20 ┆ 20 ┆ [c] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 30 ┆ 30 ┆ 30 ┆ 30 ┆ 30 ┆ 30 ┆ 30 ┆ 30 ┆ 30 ┆ 30 ┆ [c] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 40 ┆ 40 ┆ 40 ┆ 40 ┆ 40 ┆ 40 ┆ 40 ┆ 40 ┆ 40 ┆ 40 ┆ [c] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 50 ┆ 50 ┆ 50 ┆ 50 ┆ 50 ┆ 50 ┆ 50 ┆ 50 ┆ 50 ┆ 50 ┆ [c] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 60 ┆ 60 ┆ 60 ┆ 60 ┆ 60 ┆ 60 ┆ 60 ┆ 60 ┆ 60 ┆ 60 ┆ [c] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 70 ┆ 70 ┆ 70 ┆ 70 ┆ 70 ┆ 70 ┆ 70 ┆ 70 ┆ 70 ┆ 70 ┆ [c] │ │ +│ └────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┴────────────────┘ │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection.snap index af25dece2e43..375f0a7e0bc7 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__selection.snap @@ -1,7 +1,9 @@ --- source: crates/store/re_dataframe/src/query.rs assertion_line: 1838 -expression: dataframe.all_columns_collected() +expression: dataframe snapshot_kind: text --- -[] +┌┐ +╞╡ +└┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__sparse_fill_strategy_latestatglobal.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__sparse_fill_strategy_latestatglobal.snap index a2063e9472af..452615ba580b 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__sparse_fill_strategy_latestatglobal.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__sparse_fill_strategy_latestatglobal.snap @@ -1,13 +1,34 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 1458 -expression: dataframe.all_columns_collected() +assertion_line: 1464 +expression: dataframe snapshot_kind: text --- -[ - Int64[10, 20, 30, 40, 50, 60, 70], - Timestamp(Nanosecond, None)[1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000050, None, 1970-01-01 00:00:00.000000070], - ListArray[None, None, [2], [3], [4], [4], [6]], - ListArray[[c], [c], [c], [c], [c], [c], [c]], - ListArray[[{x: 0, y: 0}], [{x: 1, y: 1}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 4, y: 4}], [{x: 5, y: 5}], [{x: 8, y: 8}]], -] +┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌───────────────────────────────┬───────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┐ │ +│ │ frame_nr ┆ log_time ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel ┆ /this/that:example.MyPoint │ │ +│ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ +│ │ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[Utf8]" ┆ type: "List[Struct[2]]" │ │ +│ │ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" ┆ sorbet.path: "/this/that" │ │ +│ │ ┆ ┆ sorbet.semantic_type: ┆ sorbet.path: "/this/that" ┆ sorbet.semantic_type: │ │ +│ │ ┆ ┆ "example.MyColor" ┆ sorbet.semantic_type: ┆ "example.MyPoint" │ │ +│ │ ┆ ┆ ┆ "example.MyLabel" ┆ │ │ +│ ╞═══════════════════════════════╪═══════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╡ │ +│ │ 10 ┆ 1970-01-01T00:00:00.000000010 ┆ ┆ [c] ┆ [{x: 0.0, y: 0.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 20 ┆ ┆ ┆ [c] ┆ [{x: 1.0, y: 1.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 30 ┆ ┆ [2] ┆ [c] ┆ [{x: 2.0, y: 2.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 40 ┆ ┆ [3] ┆ [c] ┆ [{x: 3.0, y: 3.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 50 ┆ 1970-01-01T00:00:00.000000050 ┆ [4] ┆ [c] ┆ [{x: 4.0, y: 4.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 60 ┆ ┆ [4] ┆ [c] ┆ [{x: 5.0, y: 5.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 70 ┆ 1970-01-01T00:00:00.000000070 ┆ [6] ┆ [c] ┆ [{x: 8.0, y: 8.0}] │ │ +│ └───────────────────────────────┴───────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┘ │ +└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__using_index_values-2.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__using_index_values-2.snap index 7329e2113b69..389d7ae538ad 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__using_index_values-2.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__using_index_values-2.snap @@ -1,13 +1,34 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 1602 -expression: dataframe.all_columns_collected() +assertion_line: 1607 +expression: dataframe snapshot_kind: text --- -[ - Int64[0, 15, 30, 45, 60, 75, 90], - Timestamp(Nanosecond, None)[None, 1970-01-01 00:00:00.000000010, None, None, None, 1970-01-01 00:00:00.000000070, 1970-01-01 00:00:00.000000070], - ListArray[None, None, [2], [3], [4], [6], [6]], - ListArray[[c], [c], [c], [c], [c], [c], [c]], - ListArray[None, [{x: 0, y: 0}], [{x: 2, y: 2}], [{x: 3, y: 3}], [{x: 5, y: 5}], [{x: 8, y: 8}], [{x: 8, y: 8}]], -] +┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌───────────────────────────────┬───────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┐ │ +│ │ frame_nr ┆ log_time ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel ┆ /this/that:example.MyPoint │ │ +│ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ +│ │ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[Utf8]" ┆ type: "List[Struct[2]]" │ │ +│ │ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" ┆ sorbet.path: "/this/that" │ │ +│ │ ┆ ┆ sorbet.semantic_type: ┆ sorbet.path: "/this/that" ┆ sorbet.semantic_type: │ │ +│ │ ┆ ┆ "example.MyColor" ┆ sorbet.semantic_type: ┆ "example.MyPoint" │ │ +│ │ ┆ ┆ ┆ "example.MyLabel" ┆ │ │ +│ ╞═══════════════════════════════╪═══════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╡ │ +│ │ 0 ┆ ┆ ┆ [c] ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 15 ┆ 1970-01-01T00:00:00.000000010 ┆ ┆ [c] ┆ [{x: 0.0, y: 0.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 30 ┆ ┆ [2] ┆ [c] ┆ [{x: 2.0, y: 2.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 45 ┆ ┆ [3] ┆ [c] ┆ [{x: 3.0, y: 3.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 60 ┆ ┆ [4] ┆ [c] ┆ [{x: 5.0, y: 5.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 75 ┆ 1970-01-01T00:00:00.000000070 ┆ [6] ┆ [c] ┆ [{x: 8.0, y: 8.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 90 ┆ 1970-01-01T00:00:00.000000070 ┆ [6] ┆ [c] ┆ [{x: 8.0, y: 8.0}] │ │ +│ └───────────────────────────────┴───────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┘ │ +└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__using_index_values.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__using_index_values.snap index 357656d2c29c..391fe11fbf63 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__using_index_values.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__using_index_values.snap @@ -1,13 +1,34 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 1572 -expression: dataframe.all_columns_collected() +assertion_line: 1578 +expression: dataframe snapshot_kind: text --- -[ - Int64[0, 15, 30, 45, 60, 75, 90], - Timestamp(Nanosecond, None)[None, None, None, None, None, None, None], - ListArray[None, None, [2], None, None, None, None], - ListArray[[c], [c], [c], [c], [c], [c], [c]], - ListArray[None, None, [{x: 2, y: 2}], None, [{x: 5, y: 5}], None, None], -] +┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌───────────────────────────────┬───────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┬──────────────────────────────────────┐ │ +│ │ frame_nr ┆ log_time ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel ┆ /this/that:example.MyPoint │ │ +│ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ +│ │ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[Utf8]" ┆ type: "List[Struct[2]]" │ │ +│ │ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" ┆ sorbet.path: "/this/that" │ │ +│ │ ┆ ┆ sorbet.semantic_type: ┆ sorbet.path: "/this/that" ┆ sorbet.semantic_type: │ │ +│ │ ┆ ┆ "example.MyColor" ┆ sorbet.semantic_type: ┆ "example.MyPoint" │ │ +│ │ ┆ ┆ ┆ "example.MyLabel" ┆ │ │ +│ ╞═══════════════════════════════╪═══════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╡ │ +│ │ 0 ┆ ┆ ┆ [c] ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 15 ┆ ┆ ┆ [c] ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 30 ┆ ┆ [2] ┆ [c] ┆ [{x: 2.0, y: 2.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 45 ┆ ┆ ┆ [c] ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 60 ┆ ┆ ┆ [c] ┆ [{x: 5.0, y: 5.0}] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 75 ┆ ┆ ┆ [c] ┆ │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 90 ┆ ┆ ┆ [c] ┆ │ │ +│ └───────────────────────────────┴───────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┴──────────────────────────────────────┘ │ +└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents-2.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents-2.snap index 340c56ae733b..d11f263319f0 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents-2.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents-2.snap @@ -1,12 +1,27 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 1800 -expression: dataframe.all_columns_collected() +assertion_line: 1806 +expression: dataframe snapshot_kind: text --- -[ - Int64[30, 40, 50, 70], - Timestamp(Nanosecond, None)[None, None, None, None], - ListArray[[2], [3], [4], [6]], - ListArray[[c], [c], [c], [c]], -] +┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌───────────────────────────────┬───────────────────────────────┬─────────────────────────────────────────┬─────────────────────────────────────────┐ │ +│ │ frame_nr ┆ log_time ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel │ │ +│ │ --- ┆ --- ┆ --- ┆ --- │ │ +│ │ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "List[u32]" ┆ type: "List[Utf8]" │ │ +│ │ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" │ │ +│ │ ┆ ┆ sorbet.semantic_type: "example.MyColor" ┆ sorbet.path: "/this/that" │ │ +│ │ ┆ ┆ ┆ sorbet.semantic_type: "example.MyLabel" │ │ +│ ╞═══════════════════════════════╪═══════════════════════════════╪═════════════════════════════════════════╪═════════════════════════════════════════╡ │ +│ │ 30 ┆ ┆ [2] ┆ [c] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 40 ┆ ┆ [3] ┆ [c] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 50 ┆ ┆ [4] ┆ [c] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 70 ┆ ┆ [6] ┆ [c] │ │ +│ └───────────────────────────────┴───────────────────────────────┴─────────────────────────────────────────┴─────────────────────────────────────────┘ │ +└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents.snap index c43c3d2929cc..74ea5b40180d 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents.snap @@ -1,7 +1,13 @@ --- source: crates/store/re_dataframe/src/query.rs assertion_line: 1763 -expression: dataframe.all_columns_collected() +expression: dataframe snapshot_kind: text --- -[] +┌───────────────────────────────┬───────────────────────────────┐ +│ frame_nr ┆ log_time │ +│ --- ┆ --- │ +│ type: "i64" ┆ type: "Timestamp(ns)" │ +│ sorbet.index_name: "frame_nr" ┆ sorbet.index_name: "log_time" │ +╞═══════════════════════════════╪═══════════════════════════════╡ +└───────────────────────────────┴───────────────────────────────┘ diff --git a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents_and_selection.snap b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents_and_selection.snap index 5b5a196fff87..bc1e8c0b1c7c 100644 --- a/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents_and_selection.snap +++ b/crates/store/re_dataframe/src/snapshots/re_dataframe__query__tests__view_contents_and_selection.snap @@ -1,14 +1,28 @@ --- source: crates/store/re_dataframe/src/query.rs -assertion_line: 2041 -expression: dataframe.all_columns_collected() +assertion_line: 2047 +expression: dataframe snapshot_kind: text --- -[ - Int64[30, 40, 50, 70], - Timestamp(Nanosecond, None)[None, None, None, None], - NullArray(4), - NullArray(4), - ListArray[[2], [3], [4], [6]], - ListArray[[c], [c], [c], [c]], -] +┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ CHUNK METADATA: │ +│ │ +├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ +│ ┌──────────────────────────────┬──────────────────────────────┬──────────────────────────────┬──────────────────────────────┬──────────────────────────────┬──────────────────────────────┐ │ +│ │ frame_nr ┆ log_time ┆ log_tick ┆ /this/that:example.MyPoint ┆ /this/that:example.MyColor ┆ /this/that:example.MyLabel │ │ +│ │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ +│ │ type: "i64" ┆ type: "Timestamp(ns)" ┆ type: "null" ┆ type: "null" ┆ type: "List[u32]" ┆ type: "List[Utf8]" │ │ +│ │ sorbet.index_name: ┆ sorbet.index_name: ┆ sorbet.index_name: ┆ sorbet.path: "/this/that" ┆ sorbet.path: "/this/that" ┆ sorbet.is_static: "yes" │ │ +│ │ "frame_nr" ┆ "log_time" ┆ "log_tick" ┆ sorbet.semantic_type: ┆ sorbet.semantic_type: ┆ sorbet.path: "/this/that" │ │ +│ │ ┆ ┆ ┆ "example.MyPoint" ┆ "example.MyColor" ┆ sorbet.semantic_type: │ │ +│ │ ┆ ┆ ┆ ┆ ┆ "example.MyLabel" │ │ +│ ╞══════════════════════════════╪══════════════════════════════╪══════════════════════════════╪══════════════════════════════╪══════════════════════════════╪══════════════════════════════╡ │ +│ │ 30 ┆ ┆ ┆ ┆ [2] ┆ [c] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 40 ┆ ┆ ┆ ┆ [3] ┆ [c] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 50 ┆ ┆ ┆ ┆ [4] ┆ [c] │ │ +│ ├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤ │ +│ │ 70 ┆ ┆ ┆ ┆ [6] ┆ [c] │ │ +│ └──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ From b19ec4f29524bf98a7c9deec824dd5e1df17d661 Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Wed, 15 Jan 2025 18:12:37 +0100 Subject: [PATCH 44/57] Autogenerated partial updates APIs for Python (#8671) There really is not much to be said that wouldn't be made clearer by just looking at the code. Specifically: * Look at the codegen changes. * Now look at the changes to one of the generated archetypes (probably `Transform3D`). * Now look especially at the changes to `transform3d_ext`. That one's important. * Now look at how the different "partial updates" snippets evolved. Overall I hate everything here, literally every single bit -- but that's the best I managed to get out of the status quo without ridiculous amounts of efforts. * DNM: requires #8690 * Closes #8582 --------- Co-authored-by: Antoine Beyeler --- .../src/codegen/python/mod.rs | 218 +++++++++---- docs/snippets/INDEX.md | 8 +- .../archetypes/points3d_partial_updates.py | 20 +- .../archetypes/transform3d_partial_updates.py | 19 +- docs/snippets/snippets.toml | 1 - pixi.lock | 127 ++++---- pixi.toml | 2 +- rerun_py/rerun_sdk/rerun/_baseclasses.py | 16 +- .../rerun/archetypes/annotation_context.py | 52 +++- .../rerun_sdk/rerun/archetypes/arrows2d.py | 144 +++++++-- .../rerun_sdk/rerun/archetypes/arrows3d.py | 131 ++++++-- .../rerun_sdk/rerun/archetypes/asset3d.py | 89 +++++- .../rerun_sdk/rerun/archetypes/asset_video.py | 72 ++++- .../rerun_sdk/rerun/archetypes/bar_chart.py | 61 +++- .../rerun_sdk/rerun/archetypes/boxes2d.py | 141 +++++++-- .../rerun_sdk/rerun/archetypes/boxes3d.py | 168 ++++++++-- .../rerun_sdk/rerun/archetypes/capsules3d.py | 157 ++++++++-- rerun_py/rerun_sdk/rerun/archetypes/clear.py | 45 ++- .../rerun_sdk/rerun/archetypes/depth_image.py | 150 +++++++-- .../rerun/archetypes/ellipsoids3d.py | 167 ++++++++-- .../rerun/archetypes/encoded_image.py | 99 +++++- .../rerun/archetypes/geo_line_strings.py | 83 ++++- .../rerun_sdk/rerun/archetypes/geo_points.py | 95 +++++- .../rerun_sdk/rerun/archetypes/graph_edges.py | 65 +++- .../rerun_sdk/rerun/archetypes/graph_nodes.py | 107 +++++-- rerun_py/rerun_sdk/rerun/archetypes/image.py | 95 +++++- .../rerun/archetypes/instance_poses3d.py | 93 +++++- .../rerun/archetypes/line_strips2d.py | 125 ++++++-- .../rerun/archetypes/line_strips3d.py | 112 +++++-- rerun_py/rerun_sdk/rerun/archetypes/mesh3d.py | 152 +++++++-- .../rerun_sdk/rerun/archetypes/pinhole.py | 123 +++++++- .../rerun_sdk/rerun/archetypes/points2d.py | 149 +++++++-- .../rerun_sdk/rerun/archetypes/points3d.py | 136 ++++++-- rerun_py/rerun_sdk/rerun/archetypes/scalar.py | 52 +++- .../rerun/archetypes/segmentation_image.py | 95 +++++- .../rerun_sdk/rerun/archetypes/series_line.py | 88 +++++- .../rerun/archetypes/series_point.py | 84 ++++- rerun_py/rerun_sdk/rerun/archetypes/tensor.py | 76 ++++- .../rerun/archetypes/text_document.py | 69 +++- .../rerun_sdk/rerun/archetypes/text_log.py | 76 ++++- .../rerun_sdk/rerun/archetypes/transform3d.py | 121 +++++-- .../rerun/archetypes/transform3d_ext.py | 32 +- .../rerun/archetypes/video_frame_reference.py | 81 ++++- .../rerun/archetypes/view_coordinates.py | 52 +++- .../rerun/blueprint/archetypes/background.py | 66 +++- .../archetypes/container_blueprint.py | 145 +++++++-- .../blueprint/archetypes/dataframe_query.py | 101 +++++- .../blueprint/archetypes/force_center.py | 62 +++- .../archetypes/force_collision_radius.py | 75 ++++- .../rerun/blueprint/archetypes/force_link.py | 75 ++++- .../blueprint/archetypes/force_many_body.py | 65 +++- .../blueprint/archetypes/force_position.py | 73 ++++- .../rerun/blueprint/archetypes/line_grid3d.py | 105 ++++++- .../blueprint/archetypes/map_background.py | 54 +++- .../rerun/blueprint/archetypes/map_zoom.py | 54 +++- .../blueprint/archetypes/near_clip_plane.py | 54 +++- .../blueprint/archetypes/panel_blueprint.py | 49 ++- .../rerun/blueprint/archetypes/plot_legend.py | 66 +++- .../rerun/blueprint/archetypes/scalar_axis.py | 62 +++- .../archetypes/tensor_scalar_mapping.py | 79 ++++- .../archetypes/tensor_slice_selection.py | 92 +++++- .../blueprint/archetypes/tensor_view_fit.py | 50 ++- .../blueprint/archetypes/view_blueprint.py | 93 +++++- .../blueprint/archetypes/view_contents.py | 54 +++- .../archetypes/viewport_blueprint.py | 105 ++++++- .../archetypes/visible_time_ranges.py | 56 +++- .../blueprint/archetypes/visual_bounds2d.py | 56 +++- .../test_types/archetypes/affix_fuzzer1.py | 294 ++++++++++++------ .../test_types/archetypes/affix_fuzzer2.py | 258 ++++++++++----- .../test_types/archetypes/affix_fuzzer3.py | 192 ++++++++---- .../test_types/archetypes/affix_fuzzer4.py | 192 ++++++++---- rerun_py/tests/unit/common_arrays.py | 40 +-- rerun_py/tests/unit/test_asset3d.py | 5 +- rerun_py/tests/unit/test_box3d.py | 2 +- .../tests/unit/test_container_blueprint.py | 16 +- rerun_py/tests/unit/test_depth_image.py | 9 +- rerun_py/tests/unit/test_ellipsoids3d.py | 2 +- rerun_py/tests/unit/test_exceptions.py | 4 +- rerun_py/tests/unit/test_geo_line_strings.py | 2 +- rerun_py/tests/unit/test_image_encoded.py | 1 + rerun_py/tests/unit/test_instance_pose3d.py | 10 +- rerun_py/tests/unit/test_line_strips2d.py | 2 +- rerun_py/tests/unit/test_line_strips3d.py | 18 +- rerun_py/tests/unit/test_mesh3d.py | 2 +- rerun_py/tests/unit/test_pinhole.py | 6 +- rerun_py/tests/unit/test_plot_legend.py | 4 +- rerun_py/tests/unit/test_scalar_axis.py | 4 +- rerun_py/tests/unit/test_series_styles.py | 14 +- .../tests/unit/test_tensor_slice_selection.py | 8 +- rerun_py/tests/unit/test_transform3d.py | 14 +- rerun_py/tests/unit/test_uuid.py | 2 +- rerun_py/tests/unit/test_view_blueprint.py | 6 +- rerun_py/tests/unit/test_view_coordinates.py | 3 +- .../tests/unit/test_viewport_blueprint.py | 10 +- 94 files changed, 5570 insertions(+), 1289 deletions(-) diff --git a/crates/build/re_types_builder/src/codegen/python/mod.rs b/crates/build/re_types_builder/src/codegen/python/mod.rs index 59f5be324598..f4a1a30d2f4f 100644 --- a/crates/build/re_types_builder/src/codegen/python/mod.rs +++ b/crates/build/re_types_builder/src/codegen/python/mod.rs @@ -19,7 +19,6 @@ use crate::{ objects::ObjectClass, ArrowRegistry, CodeGenerator, Docs, ElementType, GeneratedFiles, Object, ObjectField, ObjectKind, Objects, Reporter, Type, ATTR_PYTHON_ALIASES, ATTR_PYTHON_ARRAY_ALIASES, - ATTR_RERUN_LOG_MISSING_AS_EMPTY, }; use self::views::code_for_view; @@ -592,11 +591,7 @@ fn code_for_struct( } else if *kind == ObjectKind::Archetype { // Archetypes use the ComponentBatch constructor for their fields let (typ_unwrapped, _) = quote_field_type_from_field(objects, field, true); - if field.is_nullable && !obj.attrs.has(ATTR_RERUN_LOG_MISSING_AS_EMPTY) { - format!("converter={typ_unwrapped}Batch._optional, # type: ignore[misc]\n") - } else { - format!("converter={typ_unwrapped}Batch._required, # type: ignore[misc]\n") - } + format!("converter={typ_unwrapped}Batch._converter, # type: ignore[misc]\n") } else if !default_converter.is_empty() { code.push_indented(0, &converter_function, 1); format!("converter={default_converter}") @@ -699,6 +694,7 @@ fn code_for_struct( if obj.kind == ObjectKind::Archetype { code.push_indented(1, quote_clear_methods(obj), 2); + code.push_indented(1, quote_partial_update_methods(reporter, obj, objects), 2); } if obj.is_delegating_component() { @@ -739,10 +735,7 @@ fn code_for_struct( }; let metadata = if *kind == ObjectKind::Archetype { - format!( - "\nmetadata={{'component': '{}'}}, ", - if *is_nullable { "optional" } else { "required" } - ) + "\nmetadata={'component': True}, ".to_owned() } else { String::new() }; @@ -756,7 +749,7 @@ fn code_for_struct( String::new() }; // Note: mypy gets confused using staticmethods for field-converters - let typ = if !*is_nullable { + let typ = if !obj.is_archetype() && !*is_nullable { format!("{typ} = field(\n{metadata}{converter}{type_ignore}\n)") } else { format!( @@ -2336,60 +2329,57 @@ fn quote_init_parameter_from_field( } } -fn quote_init_method( - reporter: &Reporter, - obj: &Object, - ext_class: &ExtensionClass, - objects: &Objects, -) -> String { +fn compute_init_parameters(obj: &Object, objects: &Objects) -> Vec { // If the type is fully transparent (single non-nullable field and not an archetype), // we have to use the "{obj.name}Like" type directly since the type of the field itself might be too narrow. // -> Whatever type aliases there are for this type, we need to pick them up. - let parameters: Vec<_> = - if obj.kind != ObjectKind::Archetype && obj.fields.len() == 1 && !obj.fields[0].is_nullable - { - vec![format!( - "{}: {}", - obj.fields[0].name, - quote_parameter_type_alias(&obj.fqname, &obj.fqname, objects, false) - )] - } else if obj.is_union() { - vec![format!( - "inner: {} | None = None", - quote_parameter_type_alias(&obj.fqname, &obj.fqname, objects, false) - )] - } else { - let required = obj - .fields - .iter() - .filter(|field| !field.is_nullable) - .map(|field| quote_init_parameter_from_field(field, objects, &obj.fqname)) - .collect_vec(); - - let optional = obj - .fields - .iter() - .filter(|field| field.is_nullable) - .map(|field| quote_init_parameter_from_field(field, objects, &obj.fqname)) - .collect_vec(); - - if optional.is_empty() { - required - } else if obj.kind == ObjectKind::Archetype { - // Force kw-args for all optional arguments: - required - .into_iter() - .chain(std::iter::once("*".to_owned())) - .chain(optional) - .collect() - } else { - required.into_iter().chain(optional).collect() - } - }; + if obj.kind != ObjectKind::Archetype && obj.fields.len() == 1 && !obj.fields[0].is_nullable { + vec![format!( + "{}: {}", + obj.fields[0].name, + quote_parameter_type_alias(&obj.fqname, &obj.fqname, objects, false) + )] + } else if obj.is_union() { + vec![format!( + "inner: {} | None = None", + quote_parameter_type_alias(&obj.fqname, &obj.fqname, objects, false) + )] + } else { + let required = obj + .fields + .iter() + .filter(|field| !field.is_nullable) + .map(|field| quote_init_parameter_from_field(field, objects, &obj.fqname)) + .collect_vec(); - let head = format!("def __init__(self: Any, {}):", parameters.join(", ")); + let optional = obj + .fields + .iter() + .filter(|field| field.is_nullable) + .map(|field| quote_init_parameter_from_field(field, objects, &obj.fqname)) + .collect_vec(); + + if optional.is_empty() { + required + } else if obj.kind == ObjectKind::Archetype { + // Force kw-args for all optional arguments: + required + .into_iter() + .chain(std::iter::once("*".to_owned())) + .chain(optional) + .collect() + } else { + required.into_iter().chain(optional).collect() + } + } +} - let parameter_docs = if obj.is_union() { +fn compute_init_parameter_docs( + reporter: &Reporter, + obj: &Object, + objects: &Objects, +) -> Vec { + if obj.is_union() { Vec::new() } else { obj.fields @@ -2414,7 +2404,19 @@ fn quote_init_method( } }) .collect::>() - }; + } +} + +fn quote_init_method( + reporter: &Reporter, + obj: &Object, + ext_class: &ExtensionClass, + objects: &Objects, +) -> String { + let parameters = compute_init_parameters(obj, objects); + let head = format!("def __init__(self: Any, {}):", parameters.join(", ")); + + let parameter_docs = compute_init_parameter_docs(reporter, obj, objects); let mut doc_string_lines = vec![format!( "Create a new instance of the {} {}.", obj.name, @@ -2474,7 +2476,7 @@ fn quote_clear_methods(obj: &Object) -> String { let param_nones = obj .fields .iter() - .map(|field| format!("{} = None, # type: ignore[arg-type]", field.name)) + .map(|field| format!("{} = None,", field.name)) .join("\n "); let classname = &obj.name; @@ -2497,6 +2499,98 @@ fn quote_clear_methods(obj: &Object) -> String { )) } +fn quote_partial_update_methods(reporter: &Reporter, obj: &Object, objects: &Objects) -> String { + let name = &obj.name; + + let parameters = obj + .fields + .iter() + .map(|field| { + let mut field = field.clone(); + field.is_nullable = true; + quote_init_parameter_from_field(&field, objects, &obj.fqname) + }) + .collect_vec() + .join(", "); + + let kwargs = obj + .fields + .iter() + .map(|field| { + let field_name = field.snake_case_name(); + format!("'{field_name}': {field_name}") + }) + .collect_vec() + .join(", "); + + let parameter_docs = compute_init_parameter_docs(reporter, obj, objects); + let mut doc_string_lines = vec![format!("Update only some specific fields of a `{name}`.")]; + if !parameter_docs.is_empty() { + doc_string_lines.push("\n".to_owned()); + doc_string_lines.push("Parameters".to_owned()); + doc_string_lines.push("----------".to_owned()); + doc_string_lines.push("clear:".to_owned()); + doc_string_lines + .push(" If true, all unspecified fields will be explicitly cleared.".to_owned()); + for doc in parameter_docs { + doc_string_lines.push(doc); + } + }; + let doc_block = quote_doc_lines(doc_string_lines) + .lines() + .map(|line| format!(" {line}")) + .collect_vec() + .join("\n"); + + let field_clears = obj + .fields + .iter() + .map(|field| { + let field_name = field.snake_case_name(); + format!("{field_name}=[],") + }) + .collect_vec() + .join("\n "); + let field_clears = indent::indent_by(4, field_clears); + + unindent(&format!( + r#" + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + {parameters}, + ) -> {name}: + +{doc_block} + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = {{ + {kwargs}, + }} + + if clear: + kwargs = {{k: v if v is not None else [] for k, v in kwargs.items()}} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> {name}: + """Clear all the fields of a `{name}`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + {field_clears} + ) + return inst + "# + )) +} + // --- Arrow registry code generators --- use arrow2::datatypes::{DataType, Field, UnionMode}; diff --git a/docs/snippets/INDEX.md b/docs/snippets/INDEX.md index f77453ae1a2e..abd75b46af08 100644 --- a/docs/snippets/INDEX.md +++ b/docs/snippets/INDEX.md @@ -72,6 +72,7 @@ _All snippets, organized by the [`Archetype`](https://rerun.io/docs/reference/ty | **[`Capsules3D`](https://rerun.io/docs/reference/types/archetypes/capsules3d)** | `archetypes/capsules3d_batch` | Log a batch of capsules | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/capsules3d_batch.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/capsules3d_batch.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/capsules3d_batch.cpp) | | **[`Clear`](https://rerun.io/docs/reference/types/archetypes/clear)** | `archetypes/clear_simple` | Log and then clear data | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/clear_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/clear_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/clear_simple.cpp) | | **[`Clear`](https://rerun.io/docs/reference/types/archetypes/clear)** | `archetypes/clear_recursive` | Log and then clear data recursively | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/clear_recursive.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/clear_recursive.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/clear_recursive.cpp) | +| **[`Clear`](https://rerun.io/docs/reference/types/archetypes/clear)** | `archetypes/transform3d_partial_updates` | Log different transforms with visualized coordinates axes | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.cpp) | | **[`Clear`](https://rerun.io/docs/reference/types/archetypes/clear)** | `concepts/different_data_per_timeline` | Log different data on different timelines | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.cpp) | | **[`DepthImage`](https://rerun.io/docs/reference/types/archetypes/depth_image)** | `archetypes/depth_image_simple` | Create and log a depth image | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/depth_image_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/depth_image_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/depth_image_simple.cpp) | | **[`DepthImage`](https://rerun.io/docs/reference/types/archetypes/depth_image)** | `archetypes/depth_image_3d` | Create and log a depth image and pinhole camera | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/depth_image_3d.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/depth_image_3d.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/depth_image_3d.cpp) | @@ -200,9 +201,7 @@ _All snippets, organized by the [`Component`](https://rerun.io/docs/reference/ty | **[`AnnotationContext`](https://rerun.io/docs/reference/types/components/annotation_context)** | `archetypes/annotation_context_connections` | Log annotation context with connections between keypoints | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_connections.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_connections.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_connections.cpp) | | **[`AnnotationContext`](https://rerun.io/docs/reference/types/components/annotation_context)** | `archetypes/segmentation_image_simple` | Create and log a segmentation image | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/segmentation_image_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/segmentation_image_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/segmentation_image_simple.cpp) | | **[`AnnotationContext`](https://rerun.io/docs/reference/types/components/annotation_context)** | `tutorials/annotation-context` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation-context.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation-context.rs) | | -| **[`ClassId`](https://rerun.io/docs/reference/types/components/class_id)** | `archetypes/points3d_partial_updates` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp) | | **[`ClassId`](https://rerun.io/docs/reference/types/components/class_id)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | -| **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `archetypes/points3d_partial_updates` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp) | | **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | | **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `archetypes/points3d_send_columns` | Use the `send_columns` API to send several point clouds over time in a single call | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_send_columns.py) | | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_send_columns.cpp) | | **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `concepts/different_data_per_timeline` | Log different data on different timelines | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.cpp) | @@ -221,13 +220,11 @@ _All snippets, organized by the [`Component`](https://rerun.io/docs/reference/ty | **[`GraphNode`](https://rerun.io/docs/reference/types/components/graph_node)** | `views/graph` | Use a blueprint to customize a graph view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/graph.py) | | | | **[`ImageBuffer`](https://rerun.io/docs/reference/types/components/image_buffer)** | `archetypes/image_send_columns` | Send multiple images at once using `send_columns` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.cpp) | | **[`ImageFormat`](https://rerun.io/docs/reference/types/components/image_format)** | `archetypes/image_send_columns` | Send multiple images at once using `send_columns` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/image_send_columns.cpp) | -| **[`KeypointId`](https://rerun.io/docs/reference/types/components/keypoint_id)** | `archetypes/points3d_partial_updates` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp) | | **[`KeypointId`](https://rerun.io/docs/reference/types/components/keypoint_id)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | | **[`MediaType`](https://rerun.io/docs/reference/types/components/media_type)** | `archetypes/text_document` | Log a `TextDocument` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_document.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_document.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_document.cpp) | | **[`MediaType`](https://rerun.io/docs/reference/types/components/media_type)** | `views/text_document` | Use a blueprint to show a text document | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/text_document.py) | | | | **[`Plane3D`](https://rerun.io/docs/reference/types/components/plane3d)** | `views/spatial3d` | Use a blueprint to customize a Spatial3DView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/spatial3d.py) | | | | **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `archetypes/mesh3d_partial_updates` | Log a simple colored triangle, then update its vertices' positions each frame | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/mesh3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/mesh3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/mesh3d_partial_updates.cpp) | -| **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `archetypes/points3d_partial_updates` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp) | | **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | | **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `archetypes/points3d_send_columns` | Use the `send_columns` API to send several point clouds over time in a single call | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_send_columns.py) | | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_send_columns.cpp) | | **[`Position3D`](https://rerun.io/docs/reference/types/components/position3d)** | `descriptors/descr_builtin_component` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_component.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_component.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/descriptors/descr_builtin_component.cpp) | @@ -239,7 +236,6 @@ _All snippets, organized by the [`Component`](https://rerun.io/docs/reference/ty | **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `archetypes/line_strips2d_ui_radius` | Log lines with ui points & scene unit radii | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/line_strips2d_ui_radius.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/line_strips2d_ui_radius.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/line_strips2d_ui_radius.cpp) | | **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `archetypes/geo_line_strings_simple` | Log a simple geospatial line string | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_line_strings_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_line_strings_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_line_strings_simple.cpp) | | **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `archetypes/geo_points_simple` | Log some very simple geospatial point | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_points_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_points_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/geo_points_simple.cpp) | -| **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `archetypes/points3d_partial_updates` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp) | | **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | | **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `concepts/different_data_per_timeline` | Log different data on different timelines | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.cpp) | | **[`Radius`](https://rerun.io/docs/reference/types/components/radius)** | `views/map` | Use a blueprint to customize a map view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/map.py) | | | @@ -261,7 +257,6 @@ _All snippets, organized by the [`Component`](https://rerun.io/docs/reference/ty | **[`Scalar`](https://rerun.io/docs/reference/types/components/scalar)** | `views/dataframe` | Use a blueprint to customize a DataframeView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/dataframe.py) | | | | **[`Scalar`](https://rerun.io/docs/reference/types/components/scalar)** | `views/tensor` | Use a blueprint to show a tensor view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/tensor.py) | | | | **[`Scalar`](https://rerun.io/docs/reference/types/components/scalar)** | `views/timeseries` | Use a blueprint to customize a TimeSeriesView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/timeseries.py) | | | -| **[`ShowLabels`](https://rerun.io/docs/reference/types/components/show_labels)** | `archetypes/points3d_partial_updates` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp) | | **[`ShowLabels`](https://rerun.io/docs/reference/types/components/show_labels)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | | **[`TensorDimensionIndexSelection`](https://rerun.io/docs/reference/types/components/tensor_dimension_index_selection)** | `views/tensor` | Use a blueprint to show a tensor view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/tensor.py) | | | | **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `views/text_log` | Use a blueprint to show a text log | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/text_log.py) | | | @@ -270,7 +265,6 @@ _All snippets, organized by the [`Component`](https://rerun.io/docs/reference/ty | **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `archetypes/text_log` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_log.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_log.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_log.cpp) | | **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `archetypes/text_document` | Log a `TextDocument` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_document.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_document.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/text_document.cpp) | | **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `archetypes/entity_path` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/entity_path.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/entity_path.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/entity_path.cpp) | -| **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `archetypes/points3d_partial_updates` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp) | | **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | | **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `concepts/app-model/native-async` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-async.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-async.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-async.cpp) | | **[`Text`](https://rerun.io/docs/reference/types/components/text)** | `concepts/app-model/native-sync` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-sync.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-sync.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/app-model/native-sync.cpp) | diff --git a/docs/snippets/all/archetypes/points3d_partial_updates.py b/docs/snippets/all/archetypes/points3d_partial_updates.py index 69f56d5c62ae..f97d4b766b06 100644 --- a/docs/snippets/all/archetypes/points3d_partial_updates.py +++ b/docs/snippets/all/archetypes/points3d_partial_updates.py @@ -14,23 +14,7 @@ radii = [0.6 if n < i else 0.2 for n in range(0, 10)] rr.set_time_sequence("frame", i) - rr.log("points", [rr.Points3D.indicator(), rr.components.ColorBatch(colors), rr.components.RadiusBatch(radii)]) - # TODO(cmc): implement new APIs and use them! - # rr.log("points", rr.Points3D.update_fields(radii=radii, colors=colors)) + rr.log("points", rr.Points3D.update_fields(radii=radii, colors=colors)) rr.set_time_sequence("frame", 20) -rr.log( - "points", - [ - rr.Points3D.indicator(), - rr.components.Position3DBatch(positions), - rr.components.RadiusBatch(0.3), - rr.components.ColorBatch([]), - rr.components.TextBatch([]), - rr.components.ShowLabelsBatch([]), - rr.components.ClassIdBatch([]), - rr.components.KeypointIdBatch([]), - ], -) -# TODO(cmc): implement new APIs and use them! -# rr.log("points", rr.Points3D.clear_fields().update_fields(positions=positions, radii=0.3)) +rr.log("points", rr.Points3D.update_fields(clear=True, positions=positions, radii=0.3)) diff --git a/docs/snippets/all/archetypes/transform3d_partial_updates.py b/docs/snippets/all/archetypes/transform3d_partial_updates.py index 1b05dd5db502..fba4a436cd49 100644 --- a/docs/snippets/all/archetypes/transform3d_partial_updates.py +++ b/docs/snippets/all/archetypes/transform3d_partial_updates.py @@ -11,43 +11,44 @@ def truncated_radians(deg: float) -> float: rr.init("rerun_example_transform3d_partial_updates", spawn=True) +# Set up a 3D box. rr.log( "box", rr.Boxes3D(half_sizes=[4.0, 2.0, 1.0], fill_mode=rr.components.FillMode.Solid), - rr.Transform3D(axis_length=10), + rr.Transform3D(clear=False, axis_length=10), ) +# Update only the rotation of the box. for deg in range(46): rad = truncated_radians(deg * 4) - # TODO(#8582): update_fields rr.log( "box", - rr.Transform3D( + rr.Transform3D.update_fields( # TODO(cmc): we should have access to all the fields of the extended constructor too. rotation_axis_angle=rr.RotationAxisAngle(axis=[0.0, 1.0, 0.0], radians=rad), ), ) +# Update only the position of the box. for t in range(51): - # TODO(#8582): update_fields rr.log( "box", - rr.Transform3D(translation=[0, 0, t / 10.0]), + rr.Transform3D.update_fields(translation=[0, 0, t / 10.0]), ) +# Update only the rotation of the box. for deg in range(46): rad = truncated_radians((deg + 45) * 4) - # TODO(#8582): update_fields rr.log( "box", - rr.Transform3D( + rr.Transform3D.update_fields( # TODO(cmc): we should have access to all the fields of the extended constructor too. rotation_axis_angle=rr.RotationAxisAngle(axis=[0.0, 1.0, 0.0], radians=rad), ), ) -# TODO(#8582): update_fields(clear=True) +# Clear all of the box's attributes, and reset its axis length. rr.log( "box", - rr.Transform3D(axis_length=15), + rr.Transform3D.update_fields(clear=True, axis_length=15), ) diff --git a/docs/snippets/snippets.toml b/docs/snippets/snippets.toml index 6b66945e367c..3001e5c1b9dc 100644 --- a/docs/snippets/snippets.toml +++ b/docs/snippets/snippets.toml @@ -273,7 +273,6 @@ quick_start = [ # These examples don't have exactly the same implementation. ] "archetypes/transform3d_partial_updates" = [ "cpp", # TODO(#8583): remove once C++ partial updates APIs have shipped - "py", # TODO(#8582): remove once Python partial updates APIs have shipped ] "archetypes/instance_poses3d_combined" = [ # TODO(#3235): Slight floating point differences in point grid. "cpp", diff --git a/pixi.lock b/pixi.lock index ad8fed5b1757..999d8638a8e1 100644 --- a/pixi.lock +++ b/pixi.lock @@ -125,7 +125,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.1-py311h2dc5d0c_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/meilisearch-1.5.1-he8a937b_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/multidict-6.1.0-py311h2dc5d0c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.8.0-py311h459d7ec_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.14.1-py311h9ecbd09_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nasm-2.16.03-h4bc722e_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda @@ -353,7 +353,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lz4-c-1.9.4-hd600fc2_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/markupsafe-3.0.1-py311ha09ea12_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/multidict-6.1.0-py311h58d527c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mypy-1.8.0-py311hcd402e7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mypy-1.14.1-py311ha879c10_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nasm-2.16.03-h68df207_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-hcccb83c_1.conda @@ -570,7 +570,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/lz4-c-1.9.4-hf0c8a7f_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/markupsafe-3.0.1-py311ha971863_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/multidict-6.1.0-py311h1cc1194_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.8.0-py311he705e18_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.14.1-py311h4d7f069_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nasm-2.16.03-hfdf4475_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-hf036a51_1.conda @@ -786,7 +786,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.1-py311h0ecf0c1_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/meilisearch-1.5.1-h5ef7bb8_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/multidict-6.1.0-py311h30e7462_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.8.0-py311h05b510d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.14.1-py311h917b07b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nasm-2.16.03-h99b78c6_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda @@ -973,7 +973,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.1.0-h66d3029_694.conda - conda: https://conda.anaconda.org/conda-forge/win-64/msys2-conda-epoch-20160418-1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/multidict-6.1.0-py311h5082efb_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.8.0-py311ha68e1ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.14.1-py311he736701_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/nasm-2.16.03-hfd05255_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.11.1-h91493d7_0.conda @@ -1194,7 +1194,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/maturin-1.5.1-py311h63ff55d_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/meilisearch-1.5.1-he8a937b_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/multidict-6.1.0-py311h2dc5d0c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.8.0-py311h459d7ec_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.14.1-py311h9ecbd09_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nasm-2.16.03-h4bc722e_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda @@ -1406,7 +1406,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/markupsafe-3.0.1-py311ha09ea12_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/maturin-1.5.1-py311h06e5ef9_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/multidict-6.1.0-py311h58d527c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mypy-1.8.0-py311hcd402e7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mypy-1.14.1-py311ha879c10_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nasm-2.16.03-h68df207_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-hcccb83c_1.conda @@ -1607,7 +1607,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/markupsafe-3.0.1-py311ha971863_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/maturin-1.5.1-py311h24bb903_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/multidict-6.1.0-py311h1cc1194_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.8.0-py311he705e18_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.14.1-py311h4d7f069_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nasm-2.16.03-hfdf4475_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-hf036a51_1.conda @@ -1806,7 +1806,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/maturin-1.5.1-py311h71175c2_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/meilisearch-1.5.1-h5ef7bb8_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/multidict-6.1.0-py311h30e7462_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.8.0-py311h05b510d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.14.1-py311h917b07b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nasm-2.16.03-h99b78c6_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda @@ -1993,7 +1993,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.1.0-h66d3029_694.conda - conda: https://conda.anaconda.org/conda-forge/win-64/msys2-conda-epoch-20160418-1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/multidict-6.1.0-py311h5082efb_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.8.0-py311ha68e1ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.14.1-py311he736701_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/nasm-2.16.03-hfd05255_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.11.1-h91493d7_0.conda @@ -6121,7 +6121,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/maturin-1.5.1-py311h63ff55d_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/meilisearch-1.5.1-he8a937b_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/multidict-6.1.0-py311h2dc5d0c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.8.0-py311h459d7ec_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.14.1-py311h9ecbd09_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/mysql-common-9.0.1-h266115a_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/mysql-libs-9.0.1-he0572af_1.conda @@ -6466,7 +6466,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/markupsafe-3.0.1-py311ha09ea12_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/maturin-1.5.1-py311h06e5ef9_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/multidict-6.1.0-py311h58d527c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mypy-1.8.0-py311hcd402e7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mypy-1.14.1-py311ha879c10_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nasm-2.16.03-h68df207_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-hcccb83c_1.conda @@ -6765,7 +6765,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/markupsafe-3.0.1-py311ha971863_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/maturin-1.5.1-py311h24bb903_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/multidict-6.1.0-py311h1cc1194_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.8.0-py311he705e18_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.14.1-py311h4d7f069_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nasm-2.16.03-hfdf4475_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-hf036a51_1.conda @@ -7050,7 +7050,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/maturin-1.5.1-py311h71175c2_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/meilisearch-1.5.1-h5ef7bb8_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/multidict-6.1.0-py311h30e7462_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.8.0-py311h05b510d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.14.1-py311h917b07b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nasm-2.16.03-h99b78c6_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda @@ -7322,7 +7322,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.1.0-h66d3029_694.conda - conda: https://conda.anaconda.org/conda-forge/win-64/msys2-conda-epoch-20160418-1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/multidict-6.1.0-py311h5082efb_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.8.0-py311ha68e1ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.14.1-py311he736701_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/nasm-2.16.03-hfd05255_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.11.1-h91493d7_0.conda @@ -7577,7 +7577,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.1-py311h2dc5d0c_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/meilisearch-1.5.1-he8a937b_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/multidict-6.1.0-py311h2dc5d0c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.8.0-py311h459d7ec_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.14.1-py311h9ecbd09_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nasm-2.16.03-h4bc722e_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda @@ -7815,7 +7815,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lz4-c-1.9.4-hd600fc2_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/markupsafe-3.0.1-py311ha09ea12_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/multidict-6.1.0-py311h58d527c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mypy-1.8.0-py311hcd402e7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mypy-1.14.1-py311ha879c10_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nasm-2.16.03-h68df207_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-hcccb83c_1.conda @@ -8042,7 +8042,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/lz4-c-1.9.4-hf0c8a7f_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/markupsafe-3.0.1-py311ha971863_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/multidict-6.1.0-py311h1cc1194_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.8.0-py311he705e18_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.14.1-py311h4d7f069_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nasm-2.16.03-hfdf4475_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-hf036a51_1.conda @@ -8267,7 +8267,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.1-py311h0ecf0c1_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/meilisearch-1.5.1-h5ef7bb8_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/multidict-6.1.0-py311h30e7462_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.8.0-py311h05b510d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.14.1-py311h917b07b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nasm-2.16.03-h99b78c6_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda @@ -8480,7 +8480,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.1.0-h66d3029_694.conda - conda: https://conda.anaconda.org/conda-forge/win-64/msys2-conda-epoch-20160418-1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/multidict-6.1.0-py311h5082efb_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.8.0-py311ha68e1ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.14.1-py311he736701_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/nasm-2.16.03-hfd05255_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.11.1-h91493d7_0.conda @@ -8814,7 +8814,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/maturin-1.5.1-py311h63ff55d_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/meilisearch-1.5.1-he8a937b_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/multidict-6.1.0-py311h2dc5d0c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.8.0-py311h459d7ec_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.14.1-py311h9ecbd09_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/mysql-common-9.0.1-h266115a_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/mysql-libs-9.0.1-he0572af_1.conda @@ -9356,7 +9356,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/markupsafe-3.0.1-py311ha09ea12_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/maturin-1.5.1-py311h06e5ef9_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/multidict-6.1.0-py311h58d527c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mypy-1.8.0-py311hcd402e7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mypy-1.14.1-py311ha879c10_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nasm-2.16.03-h68df207_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-hcccb83c_1.conda @@ -9841,7 +9841,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/markupsafe-3.0.1-py311ha971863_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/maturin-1.5.1-py311h24bb903_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/multidict-6.1.0-py311h1cc1194_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.8.0-py311he705e18_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.14.1-py311h4d7f069_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nasm-2.16.03-hfdf4475_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-hf036a51_1.conda @@ -10321,7 +10321,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/maturin-1.5.1-py311h71175c2_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/meilisearch-1.5.1-h5ef7bb8_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/multidict-6.1.0-py311h30e7462_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.8.0-py311h05b510d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.14.1-py311h917b07b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nasm-2.16.03-h99b78c6_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda @@ -10771,7 +10771,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.1.0-h66d3029_694.conda - conda: https://conda.anaconda.org/conda-forge/win-64/msys2-conda-epoch-20160418-1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/multidict-6.1.0-py311h5082efb_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.8.0-py311ha68e1ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.14.1-py311he736701_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/nasm-2.16.03-hfd05255_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.11.1-h91493d7_0.conda @@ -11296,7 +11296,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/maturin-1.5.1-py311h63ff55d_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/meilisearch-1.5.1-he8a937b_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/multidict-6.1.0-py311h2dc5d0c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.8.0-py311h459d7ec_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.14.1-py311h9ecbd09_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/mysql-common-9.0.1-h266115a_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/mysql-libs-9.0.1-he0572af_1.conda @@ -11661,7 +11661,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/markupsafe-3.0.1-py311ha09ea12_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/maturin-1.5.1-py311h06e5ef9_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/multidict-6.1.0-py311h58d527c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mypy-1.8.0-py311hcd402e7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mypy-1.14.1-py311ha879c10_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nasm-2.16.03-h68df207_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-hcccb83c_1.conda @@ -11980,7 +11980,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/markupsafe-3.0.1-py311ha971863_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/maturin-1.5.1-py311h24bb903_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/multidict-6.1.0-py311h1cc1194_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.8.0-py311he705e18_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.14.1-py311h4d7f069_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nasm-2.16.03-hfdf4475_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-hf036a51_1.conda @@ -12286,7 +12286,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/maturin-1.5.1-py311h71175c2_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/meilisearch-1.5.1-h5ef7bb8_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/multidict-6.1.0-py311h30e7462_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.8.0-py311h05b510d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.14.1-py311h917b07b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nasm-2.16.03-h99b78c6_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h7bae524_1.conda @@ -12562,7 +12562,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.1.0-h66d3029_694.conda - conda: https://conda.anaconda.org/conda-forge/win-64/msys2-conda-epoch-20160418-1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/multidict-6.1.0-py311h5082efb_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.8.0-py311ha68e1ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.14.1-py311he736701_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/nasm-2.16.03-hfd05255_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.11.1-h91493d7_0.conda @@ -26010,73 +26010,84 @@ packages: - numpy - rerun-sdk editable: true -- conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.8.0-py311h459d7ec_0.conda - sha256: 943c43f2d68a6d4e8fa8a3a4e62538e090f5f0afe551f50092ea024850f5cccb - md5: 93b7b2391a045cea0d97772f550f1d77 +- conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.14.1-py311h9ecbd09_0.conda + sha256: 583282ca209e9dc9f91e28bb4d47bbf31456c2d437a4b4bdc3b1684b916b6264 + md5: 2bf2e229fee8e7649a7567dc61156437 depends: - - libgcc-ng >=12 + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 - mypy_extensions >=1.0.0 - psutil >=4.0 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 - typing_extensions >=4.1.0 + arch: x86_64 + platform: linux license: MIT license_family: MIT purls: - pkg:pypi/mypy?source=hash-mapping - size: 17719191 - timestamp: 1703185056003 -- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mypy-1.8.0-py311hcd402e7_0.conda - sha256: 2a1d84dc94a02ed3cae2fad6dfea0fab4a9504649c1a009d1fff7bfbd9d48e57 - md5: 22b4d0e0a591e6dba331d95f8a702517 + size: 18730461 + timestamp: 1735601000085 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mypy-1.14.1-py311ha879c10_0.conda + sha256: dc6f8258ebb3539b6ab27b5a78a1d2339b99a19c6396d29ffa3286664b0d671d + md5: e9e333fbbbc7571fb70f8e47edafdddd depends: - - libgcc-ng >=12 + - libgcc >=13 - mypy_extensions >=1.0.0 - psutil >=4.0 - python >=3.11,<3.12.0a0 - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 - typing_extensions >=4.1.0 + arch: aarch64 + platform: linux license: MIT license_family: MIT purls: - pkg:pypi/mypy?source=hash-mapping - size: 15129179 - timestamp: 1703185374507 -- conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.8.0-py311he705e18_0.conda - sha256: affdf64692efcf05888cc42fc2c4159fe5bade7d610847b5610e5b2cc621cd3a - md5: c32cbc41e84a67f1b30b3f157b46996b + size: 16065092 + timestamp: 1735600817630 +- conda: https://conda.anaconda.org/conda-forge/osx-64/mypy-1.14.1-py311h4d7f069_0.conda + sha256: 5b5043cb2eeec8d0821130bf0e7ef62df44cbcff7220dca7e8497382f39f40b1 + md5: 285e86076c2a98bb57c7080a11095c69 depends: + - __osx >=10.13 - mypy_extensions >=1.0.0 - psutil >=4.0 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 - typing_extensions >=4.1.0 + arch: x86_64 + platform: osx license: MIT license_family: MIT purls: - pkg:pypi/mypy?source=hash-mapping - size: 11969071 - timestamp: 1703184938293 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.8.0-py311h05b510d_0.conda - sha256: e31c811f99b842020350f9df6c6e4b5e2bf07353fee3cc0029c655e8980d9431 - md5: 93010b2e72e263002f6c60dc1c1f7e1d + size: 12710578 + timestamp: 1735600553201 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.14.1-py311h917b07b_0.conda + sha256: 0d891fd3d73ddcece659e62b765ddd6023b1296d69943481dc9910107071307a + md5: c09549d23170ecaabfa4a8162b5d4f10 depends: + - __osx >=11.0 - mypy_extensions >=1.0.0 - psutil >=4.0 - python >=3.11,<3.12.0a0 - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 - typing_extensions >=4.1.0 + arch: arm64 + platform: osx license: MIT license_family: MIT purls: - pkg:pypi/mypy?source=hash-mapping - size: 9655583 - timestamp: 1703185105616 -- conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.8.0-py311ha68e1ae_0.conda - sha256: cebfab3f247a752be06e945a3a2a1281195d6917fa09906a9618dbc7b2cf734e - md5: 9a949cc91276bf313755857a11ce1ec3 + size: 10180870 + timestamp: 1735600589567 +- conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.14.1-py311he736701_0.conda + sha256: 12a90fb2507dd5c56a0e846bf828fe8b3197aa79ec8d655934d455d20101a640 + md5: a3f3aebd6fbdbdec85098e24d14f89aa depends: - mypy_extensions >=1.0.0 - psutil >=4.0 @@ -26086,12 +26097,14 @@ packages: - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 + arch: x86_64 + platform: win license: MIT license_family: MIT purls: - pkg:pypi/mypy?source=hash-mapping - size: 9963457 - timestamp: 1703184979309 + size: 10553025 + timestamp: 1735600107955 - pypi: https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl name: mypy-extensions version: 1.0.0 diff --git a/pixi.toml b/pixi.toml index aeefdea6dacf..01f21c2b81fa 100644 --- a/pixi.toml +++ b/pixi.toml @@ -459,7 +459,7 @@ flatbuffers = ">=23" gitignore-parser = ">=0.1.9" gitpython = ">=3.1.40" jinja2 = ">=3.1.3,<3.2" # For `build_screenshot_compare.py` and other utilities that build websites. -mypy = "1.8.0" +mypy = "1.14.1" nasm = ">=2.16" # Required by https://github.com/memorysafety/rav1d for native video support ninja = "1.11.1" numpy = ">=1.23,<2" diff --git a/rerun_py/rerun_sdk/rerun/_baseclasses.py b/rerun_py/rerun_sdk/rerun/_baseclasses.py index 8b2e50bfa39a..9c5056e64c74 100644 --- a/rerun_py/rerun_sdk/rerun/_baseclasses.py +++ b/rerun_py/rerun_sdk/rerun/_baseclasses.py @@ -281,21 +281,11 @@ def __init__(self, data: T | None, strict: bool | None = None) -> None: self.pa_array = _empty_pa_array(self._ARROW_DATATYPE) @classmethod - def _required(cls, data: T | None) -> BaseBatch[T]: + def _converter(cls, data: T | None) -> BaseBatch[T] | None: """ - Primary method for creating Arrow arrays for optional components. + Primary method for creating Arrow arrays for components. - Just calls through to __init__, but with clearer type annotations. - """ - return cls(data) - - @classmethod - def _optional(cls, data: T | None) -> BaseBatch[T] | None: - """ - Primary method for creating Arrow arrays for optional components. - - For optional components, the default value of None is preserved in the field to indicate that the optional - field was not specified. + The default value of None is preserved in the field to indicate that the optional field was not specified. If any value other than None is provided, it is passed through to `__init__`. Parameters diff --git a/rerun_py/rerun_sdk/rerun/archetypes/annotation_context.py b/rerun_py/rerun_sdk/rerun/archetypes/annotation_context.py index da29c3817e22..8aa27d7a7a02 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/annotation_context.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/annotation_context.py @@ -82,7 +82,7 @@ def __init__(self: Any, context: components.AnnotationContextLike): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - context=None, # type: ignore[arg-type] + context=None, ) @classmethod @@ -92,9 +92,53 @@ def _clear(cls) -> AnnotationContext: inst.__attrs_clear__() return inst - context: components.AnnotationContextBatch = field( - metadata={"component": "required"}, - converter=components.AnnotationContextBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + context: components.AnnotationContextLike | None = None, + ) -> AnnotationContext: + """ + Update only some specific fields of a `AnnotationContext`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + context: + List of class descriptions, mapping class indices to class names, colors etc. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "context": context, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> AnnotationContext: + """Clear all the fields of a `AnnotationContext`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + context=[], + ) + return inst + + context: components.AnnotationContextBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.AnnotationContextBatch._converter, # type: ignore[misc] ) # List of class descriptions, mapping class indices to class names, colors etc. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/arrows2d.py b/rerun_py/rerun_sdk/rerun/archetypes/arrows2d.py index e31a9836628a..cfd1323ef72c 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/arrows2d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/arrows2d.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .arrows2d_ext import Arrows2DExt __all__ = ["Arrows2D"] @@ -57,14 +58,14 @@ class Arrows2D(Arrows2DExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - vectors=None, # type: ignore[arg-type] - origins=None, # type: ignore[arg-type] - radii=None, # type: ignore[arg-type] - colors=None, # type: ignore[arg-type] - labels=None, # type: ignore[arg-type] - show_labels=None, # type: ignore[arg-type] - draw_order=None, # type: ignore[arg-type] - class_ids=None, # type: ignore[arg-type] + vectors=None, + origins=None, + radii=None, + colors=None, + labels=None, + show_labels=None, + draw_order=None, + class_ids=None, ) @classmethod @@ -74,18 +75,109 @@ def _clear(cls) -> Arrows2D: inst.__attrs_clear__() return inst - vectors: components.Vector2DBatch = field( - metadata={"component": "required"}, - converter=components.Vector2DBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + vectors: datatypes.Vec2DArrayLike | None = None, + origins: datatypes.Vec2DArrayLike | None = None, + radii: datatypes.Float32ArrayLike | None = None, + colors: datatypes.Rgba32ArrayLike | None = None, + labels: datatypes.Utf8ArrayLike | None = None, + show_labels: datatypes.BoolLike | None = None, + draw_order: datatypes.Float32Like | None = None, + class_ids: datatypes.ClassIdArrayLike | None = None, + ) -> Arrows2D: + """ + Update only some specific fields of a `Arrows2D`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + vectors: + All the vectors for each arrow in the batch. + origins: + All the origin (base) positions for each arrow in the batch. + + If no origins are set, (0, 0) is used as the origin for each arrow. + radii: + Optional radii for the arrows. + + The shaft is rendered as a line with `radius = 0.5 * radius`. + The tip is rendered with `height = 2.0 * radius` and `radius = 1.0 * radius`. + colors: + Optional colors for the points. + labels: + Optional text labels for the arrows. + + If there's a single label present, it will be placed at the center of the entity. + Otherwise, each instance will have its own label. + show_labels: + Optional choice of whether the text labels should be shown by default. + draw_order: + An optional floating point value that specifies the 2D drawing order. + + Objects with higher values are drawn on top of those with lower values. + class_ids: + Optional class Ids for the points. + + The [`components.ClassId`][rerun.components.ClassId] provides colors and labels if not specified explicitly. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "vectors": vectors, + "origins": origins, + "radii": radii, + "colors": colors, + "labels": labels, + "show_labels": show_labels, + "draw_order": draw_order, + "class_ids": class_ids, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Arrows2D: + """Clear all the fields of a `Arrows2D`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + vectors=[], + origins=[], + radii=[], + colors=[], + labels=[], + show_labels=[], + draw_order=[], + class_ids=[], + ) + return inst + + vectors: components.Vector2DBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.Vector2DBatch._converter, # type: ignore[misc] ) # All the vectors for each arrow in the batch. # # (Docstring intentionally commented out to hide this field from the docs) origins: components.Position2DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.Position2DBatch._optional, # type: ignore[misc] + converter=components.Position2DBatch._converter, # type: ignore[misc] ) # All the origin (base) positions for each arrow in the batch. # @@ -94,9 +186,9 @@ def _clear(cls) -> Arrows2D: # (Docstring intentionally commented out to hide this field from the docs) radii: components.RadiusBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.RadiusBatch._optional, # type: ignore[misc] + converter=components.RadiusBatch._converter, # type: ignore[misc] ) # Optional radii for the arrows. # @@ -106,18 +198,18 @@ def _clear(cls) -> Arrows2D: # (Docstring intentionally commented out to hide this field from the docs) colors: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Optional colors for the points. # # (Docstring intentionally commented out to hide this field from the docs) labels: components.TextBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TextBatch._optional, # type: ignore[misc] + converter=components.TextBatch._converter, # type: ignore[misc] ) # Optional text labels for the arrows. # @@ -127,18 +219,18 @@ def _clear(cls) -> Arrows2D: # (Docstring intentionally commented out to hide this field from the docs) show_labels: components.ShowLabelsBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ShowLabelsBatch._optional, # type: ignore[misc] + converter=components.ShowLabelsBatch._converter, # type: ignore[misc] ) # Optional choice of whether the text labels should be shown by default. # # (Docstring intentionally commented out to hide this field from the docs) draw_order: components.DrawOrderBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.DrawOrderBatch._optional, # type: ignore[misc] + converter=components.DrawOrderBatch._converter, # type: ignore[misc] ) # An optional floating point value that specifies the 2D drawing order. # @@ -147,9 +239,9 @@ def _clear(cls) -> Arrows2D: # (Docstring intentionally commented out to hide this field from the docs) class_ids: components.ClassIdBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ClassIdBatch._optional, # type: ignore[misc] + converter=components.ClassIdBatch._converter, # type: ignore[misc] ) # Optional class Ids for the points. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/arrows3d.py b/rerun_py/rerun_sdk/rerun/archetypes/arrows3d.py index 282065177c60..576a461e992e 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/arrows3d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/arrows3d.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .arrows3d_ext import Arrows3DExt __all__ = ["Arrows3D"] @@ -57,13 +58,13 @@ class Arrows3D(Arrows3DExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - vectors=None, # type: ignore[arg-type] - origins=None, # type: ignore[arg-type] - radii=None, # type: ignore[arg-type] - colors=None, # type: ignore[arg-type] - labels=None, # type: ignore[arg-type] - show_labels=None, # type: ignore[arg-type] - class_ids=None, # type: ignore[arg-type] + vectors=None, + origins=None, + radii=None, + colors=None, + labels=None, + show_labels=None, + class_ids=None, ) @classmethod @@ -73,18 +74,102 @@ def _clear(cls) -> Arrows3D: inst.__attrs_clear__() return inst - vectors: components.Vector3DBatch = field( - metadata={"component": "required"}, - converter=components.Vector3DBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + vectors: datatypes.Vec3DArrayLike | None = None, + origins: datatypes.Vec3DArrayLike | None = None, + radii: datatypes.Float32ArrayLike | None = None, + colors: datatypes.Rgba32ArrayLike | None = None, + labels: datatypes.Utf8ArrayLike | None = None, + show_labels: datatypes.BoolLike | None = None, + class_ids: datatypes.ClassIdArrayLike | None = None, + ) -> Arrows3D: + """ + Update only some specific fields of a `Arrows3D`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + vectors: + All the vectors for each arrow in the batch. + origins: + All the origin (base) positions for each arrow in the batch. + + If no origins are set, (0, 0, 0) is used as the origin for each arrow. + radii: + Optional radii for the arrows. + + The shaft is rendered as a line with `radius = 0.5 * radius`. + The tip is rendered with `height = 2.0 * radius` and `radius = 1.0 * radius`. + colors: + Optional colors for the points. + labels: + Optional text labels for the arrows. + + If there's a single label present, it will be placed at the center of the entity. + Otherwise, each instance will have its own label. + show_labels: + Optional choice of whether the text labels should be shown by default. + class_ids: + Optional class Ids for the points. + + The [`components.ClassId`][rerun.components.ClassId] provides colors and labels if not specified explicitly. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "vectors": vectors, + "origins": origins, + "radii": radii, + "colors": colors, + "labels": labels, + "show_labels": show_labels, + "class_ids": class_ids, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Arrows3D: + """Clear all the fields of a `Arrows3D`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + vectors=[], + origins=[], + radii=[], + colors=[], + labels=[], + show_labels=[], + class_ids=[], + ) + return inst + + vectors: components.Vector3DBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.Vector3DBatch._converter, # type: ignore[misc] ) # All the vectors for each arrow in the batch. # # (Docstring intentionally commented out to hide this field from the docs) origins: components.Position3DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.Position3DBatch._optional, # type: ignore[misc] + converter=components.Position3DBatch._converter, # type: ignore[misc] ) # All the origin (base) positions for each arrow in the batch. # @@ -93,9 +178,9 @@ def _clear(cls) -> Arrows3D: # (Docstring intentionally commented out to hide this field from the docs) radii: components.RadiusBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.RadiusBatch._optional, # type: ignore[misc] + converter=components.RadiusBatch._converter, # type: ignore[misc] ) # Optional radii for the arrows. # @@ -105,18 +190,18 @@ def _clear(cls) -> Arrows3D: # (Docstring intentionally commented out to hide this field from the docs) colors: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Optional colors for the points. # # (Docstring intentionally commented out to hide this field from the docs) labels: components.TextBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TextBatch._optional, # type: ignore[misc] + converter=components.TextBatch._converter, # type: ignore[misc] ) # Optional text labels for the arrows. # @@ -126,18 +211,18 @@ def _clear(cls) -> Arrows3D: # (Docstring intentionally commented out to hide this field from the docs) show_labels: components.ShowLabelsBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ShowLabelsBatch._optional, # type: ignore[misc] + converter=components.ShowLabelsBatch._converter, # type: ignore[misc] ) # Optional choice of whether the text labels should be shown by default. # # (Docstring intentionally commented out to hide this field from the docs) class_ids: components.ClassIdBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ClassIdBatch._optional, # type: ignore[misc] + converter=components.ClassIdBatch._converter, # type: ignore[misc] ) # Optional class Ids for the points. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/asset3d.py b/rerun_py/rerun_sdk/rerun/archetypes/asset3d.py index 2f0d74c87bcc..eecdd926d70b 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/asset3d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/asset3d.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .asset3d_ext import Asset3DExt __all__ = ["Asset3D"] @@ -60,9 +61,9 @@ class Asset3D(Asset3DExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - blob=None, # type: ignore[arg-type] - media_type=None, # type: ignore[arg-type] - albedo_factor=None, # type: ignore[arg-type] + blob=None, + media_type=None, + albedo_factor=None, ) @classmethod @@ -72,18 +73,84 @@ def _clear(cls) -> Asset3D: inst.__attrs_clear__() return inst - blob: components.BlobBatch = field( - metadata={"component": "required"}, - converter=components.BlobBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + blob: datatypes.BlobLike | None = None, + media_type: datatypes.Utf8Like | None = None, + albedo_factor: datatypes.Rgba32Like | None = None, + ) -> Asset3D: + """ + Update only some specific fields of a `Asset3D`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + blob: + The asset's bytes. + media_type: + The Media Type of the asset. + + Supported values: + * `model/gltf-binary` + * `model/gltf+json` + * `model/obj` (.mtl material files are not supported yet, references are silently ignored) + * `model/stl` + + If omitted, the viewer will try to guess from the data blob. + If it cannot guess, it won't be able to render the asset. + albedo_factor: + A color multiplier applied to the whole asset. + + For mesh who already have `albedo_factor` in materials, + it will be overwritten by actual `albedo_factor` of [`archetypes.Asset3D`][rerun.archetypes.Asset3D] (if specified). + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "blob": blob, + "media_type": media_type, + "albedo_factor": albedo_factor, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Asset3D: + """Clear all the fields of a `Asset3D`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + blob=[], + media_type=[], + albedo_factor=[], + ) + return inst + + blob: components.BlobBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.BlobBatch._converter, # type: ignore[misc] ) # The asset's bytes. # # (Docstring intentionally commented out to hide this field from the docs) media_type: components.MediaTypeBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.MediaTypeBatch._optional, # type: ignore[misc] + converter=components.MediaTypeBatch._converter, # type: ignore[misc] ) # The Media Type of the asset. # @@ -99,9 +166,9 @@ def _clear(cls) -> Asset3D: # (Docstring intentionally commented out to hide this field from the docs) albedo_factor: components.AlbedoFactorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AlbedoFactorBatch._optional, # type: ignore[misc] + converter=components.AlbedoFactorBatch._converter, # type: ignore[misc] ) # A color multiplier applied to the whole asset. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/asset_video.py b/rerun_py/rerun_sdk/rerun/archetypes/asset_video.py index f78337f6e421..23b4c55968e2 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/asset_video.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/asset_video.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .asset_video_ext import AssetVideoExt __all__ = ["AssetVideo"] @@ -117,8 +118,8 @@ class AssetVideo(AssetVideoExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - blob=None, # type: ignore[arg-type] - media_type=None, # type: ignore[arg-type] + blob=None, + media_type=None, ) @classmethod @@ -128,18 +129,73 @@ def _clear(cls) -> AssetVideo: inst.__attrs_clear__() return inst - blob: components.BlobBatch = field( - metadata={"component": "required"}, - converter=components.BlobBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + blob: datatypes.BlobLike | None = None, + media_type: datatypes.Utf8Like | None = None, + ) -> AssetVideo: + """ + Update only some specific fields of a `AssetVideo`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + blob: + The asset's bytes. + media_type: + The Media Type of the asset. + + Supported values: + * `video/mp4` + + If omitted, the viewer will try to guess from the data blob. + If it cannot guess, it won't be able to render the asset. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "blob": blob, + "media_type": media_type, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> AssetVideo: + """Clear all the fields of a `AssetVideo`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + blob=[], + media_type=[], + ) + return inst + + blob: components.BlobBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.BlobBatch._converter, # type: ignore[misc] ) # The asset's bytes. # # (Docstring intentionally commented out to hide this field from the docs) media_type: components.MediaTypeBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.MediaTypeBatch._optional, # type: ignore[misc] + converter=components.MediaTypeBatch._converter, # type: ignore[misc] ) # The Media Type of the asset. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/bar_chart.py b/rerun_py/rerun_sdk/rerun/archetypes/bar_chart.py index f7951e40d071..d6f211e046c4 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/bar_chart.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/bar_chart.py @@ -69,8 +69,8 @@ def __init__(self: Any, values: datatypes.TensorDataLike, *, color: datatypes.Rg def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - values=None, # type: ignore[arg-type] - color=None, # type: ignore[arg-type] + values=None, + color=None, ) @classmethod @@ -80,8 +80,57 @@ def _clear(cls) -> BarChart: inst.__attrs_clear__() return inst - values: components.TensorDataBatch = field( - metadata={"component": "required"}, + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + values: datatypes.TensorDataLike | None = None, + color: datatypes.Rgba32Like | None = None, + ) -> BarChart: + """ + Update only some specific fields of a `BarChart`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + values: + The values. Should always be a 1-dimensional tensor (i.e. a vector). + color: + The color of the bar chart + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "values": values, + "color": color, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> BarChart: + """Clear all the fields of a `BarChart`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + values=[], + color=[], + ) + return inst + + values: components.TensorDataBatch | None = field( + metadata={"component": True}, + default=None, converter=BarChartExt.values__field_converter_override, # type: ignore[misc] ) # The values. Should always be a 1-dimensional tensor (i.e. a vector). @@ -89,9 +138,9 @@ def _clear(cls) -> BarChart: # (Docstring intentionally commented out to hide this field from the docs) color: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # The color of the bar chart # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/boxes2d.py b/rerun_py/rerun_sdk/rerun/archetypes/boxes2d.py index 1e22d23e0e2f..651f1bb79725 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/boxes2d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/boxes2d.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .boxes2d_ext import Boxes2DExt __all__ = ["Boxes2D"] @@ -48,14 +49,14 @@ class Boxes2D(Boxes2DExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - half_sizes=None, # type: ignore[arg-type] - centers=None, # type: ignore[arg-type] - colors=None, # type: ignore[arg-type] - radii=None, # type: ignore[arg-type] - labels=None, # type: ignore[arg-type] - show_labels=None, # type: ignore[arg-type] - draw_order=None, # type: ignore[arg-type] - class_ids=None, # type: ignore[arg-type] + half_sizes=None, + centers=None, + colors=None, + radii=None, + labels=None, + show_labels=None, + draw_order=None, + class_ids=None, ) @classmethod @@ -65,45 +66,133 @@ def _clear(cls) -> Boxes2D: inst.__attrs_clear__() return inst - half_sizes: components.HalfSize2DBatch = field( - metadata={"component": "required"}, - converter=components.HalfSize2DBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + half_sizes: datatypes.Vec2DArrayLike | None = None, + centers: datatypes.Vec2DArrayLike | None = None, + colors: datatypes.Rgba32ArrayLike | None = None, + radii: datatypes.Float32ArrayLike | None = None, + labels: datatypes.Utf8ArrayLike | None = None, + show_labels: datatypes.BoolLike | None = None, + draw_order: datatypes.Float32Like | None = None, + class_ids: datatypes.ClassIdArrayLike | None = None, + ) -> Boxes2D: + """ + Update only some specific fields of a `Boxes2D`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + half_sizes: + All half-extents that make up the batch of boxes. + centers: + Optional center positions of the boxes. + colors: + Optional colors for the boxes. + radii: + Optional radii for the lines that make up the boxes. + labels: + Optional text labels for the boxes. + + If there's a single label present, it will be placed at the center of the entity. + Otherwise, each instance will have its own label. + show_labels: + Optional choice of whether the text labels should be shown by default. + draw_order: + An optional floating point value that specifies the 2D drawing order. + + Objects with higher values are drawn on top of those with lower values. + + The default for 2D boxes is 10.0. + class_ids: + Optional [`components.ClassId`][rerun.components.ClassId]s for the boxes. + + The [`components.ClassId`][rerun.components.ClassId] provides colors and labels if not specified explicitly. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "half_sizes": half_sizes, + "centers": centers, + "colors": colors, + "radii": radii, + "labels": labels, + "show_labels": show_labels, + "draw_order": draw_order, + "class_ids": class_ids, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Boxes2D: + """Clear all the fields of a `Boxes2D`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + half_sizes=[], + centers=[], + colors=[], + radii=[], + labels=[], + show_labels=[], + draw_order=[], + class_ids=[], + ) + return inst + + half_sizes: components.HalfSize2DBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.HalfSize2DBatch._converter, # type: ignore[misc] ) # All half-extents that make up the batch of boxes. # # (Docstring intentionally commented out to hide this field from the docs) centers: components.Position2DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.Position2DBatch._optional, # type: ignore[misc] + converter=components.Position2DBatch._converter, # type: ignore[misc] ) # Optional center positions of the boxes. # # (Docstring intentionally commented out to hide this field from the docs) colors: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Optional colors for the boxes. # # (Docstring intentionally commented out to hide this field from the docs) radii: components.RadiusBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.RadiusBatch._optional, # type: ignore[misc] + converter=components.RadiusBatch._converter, # type: ignore[misc] ) # Optional radii for the lines that make up the boxes. # # (Docstring intentionally commented out to hide this field from the docs) labels: components.TextBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TextBatch._optional, # type: ignore[misc] + converter=components.TextBatch._converter, # type: ignore[misc] ) # Optional text labels for the boxes. # @@ -113,18 +202,18 @@ def _clear(cls) -> Boxes2D: # (Docstring intentionally commented out to hide this field from the docs) show_labels: components.ShowLabelsBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ShowLabelsBatch._optional, # type: ignore[misc] + converter=components.ShowLabelsBatch._converter, # type: ignore[misc] ) # Optional choice of whether the text labels should be shown by default. # # (Docstring intentionally commented out to hide this field from the docs) draw_order: components.DrawOrderBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.DrawOrderBatch._optional, # type: ignore[misc] + converter=components.DrawOrderBatch._converter, # type: ignore[misc] ) # An optional floating point value that specifies the 2D drawing order. # @@ -135,9 +224,9 @@ def _clear(cls) -> Boxes2D: # (Docstring intentionally commented out to hide this field from the docs) class_ids: components.ClassIdBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ClassIdBatch._optional, # type: ignore[misc] + converter=components.ClassIdBatch._converter, # type: ignore[misc] ) # Optional [`components.ClassId`][rerun.components.ClassId]s for the boxes. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/boxes3d.py b/rerun_py/rerun_sdk/rerun/archetypes/boxes3d.py index ff33da0d72a1..a600bbcad191 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/boxes3d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/boxes3d.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .boxes3d_ext import Boxes3DExt __all__ = ["Boxes3D"] @@ -66,16 +67,16 @@ class Boxes3D(Boxes3DExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - half_sizes=None, # type: ignore[arg-type] - centers=None, # type: ignore[arg-type] - rotation_axis_angles=None, # type: ignore[arg-type] - quaternions=None, # type: ignore[arg-type] - colors=None, # type: ignore[arg-type] - radii=None, # type: ignore[arg-type] - fill_mode=None, # type: ignore[arg-type] - labels=None, # type: ignore[arg-type] - show_labels=None, # type: ignore[arg-type] - class_ids=None, # type: ignore[arg-type] + half_sizes=None, + centers=None, + rotation_axis_angles=None, + quaternions=None, + colors=None, + radii=None, + fill_mode=None, + labels=None, + show_labels=None, + class_ids=None, ) @classmethod @@ -85,18 +86,121 @@ def _clear(cls) -> Boxes3D: inst.__attrs_clear__() return inst - half_sizes: components.HalfSize3DBatch = field( - metadata={"component": "required"}, - converter=components.HalfSize3DBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + half_sizes: datatypes.Vec3DArrayLike | None = None, + centers: datatypes.Vec3DArrayLike | None = None, + rotation_axis_angles: datatypes.RotationAxisAngleArrayLike | None = None, + quaternions: datatypes.QuaternionArrayLike | None = None, + colors: datatypes.Rgba32ArrayLike | None = None, + radii: datatypes.Float32ArrayLike | None = None, + fill_mode: components.FillModeLike | None = None, + labels: datatypes.Utf8ArrayLike | None = None, + show_labels: datatypes.BoolLike | None = None, + class_ids: datatypes.ClassIdArrayLike | None = None, + ) -> Boxes3D: + """ + Update only some specific fields of a `Boxes3D`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + half_sizes: + All half-extents that make up the batch of boxes. + centers: + Optional center positions of the boxes. + + If not specified, the centers will be at (0, 0, 0). + Note that this uses a [`components.PoseTranslation3D`][rerun.components.PoseTranslation3D] which is also used by [`archetypes.InstancePoses3D`][rerun.archetypes.InstancePoses3D]. + rotation_axis_angles: + Rotations via axis + angle. + + If no rotation is specified, the axes of the boxes align with the axes of the local coordinate system. + Note that this uses a [`components.PoseRotationAxisAngle`][rerun.components.PoseRotationAxisAngle] which is also used by [`archetypes.InstancePoses3D`][rerun.archetypes.InstancePoses3D]. + quaternions: + Rotations via quaternion. + + If no rotation is specified, the axes of the boxes align with the axes of the local coordinate system. + Note that this uses a [`components.PoseRotationQuat`][rerun.components.PoseRotationQuat] which is also used by [`archetypes.InstancePoses3D`][rerun.archetypes.InstancePoses3D]. + colors: + Optional colors for the boxes. + radii: + Optional radii for the lines that make up the boxes. + fill_mode: + Optionally choose whether the boxes are drawn with lines or solid. + labels: + Optional text labels for the boxes. + + If there's a single label present, it will be placed at the center of the entity. + Otherwise, each instance will have its own label. + show_labels: + Optional choice of whether the text labels should be shown by default. + class_ids: + Optional [`components.ClassId`][rerun.components.ClassId]s for the boxes. + + The [`components.ClassId`][rerun.components.ClassId] provides colors and labels if not specified explicitly. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "half_sizes": half_sizes, + "centers": centers, + "rotation_axis_angles": rotation_axis_angles, + "quaternions": quaternions, + "colors": colors, + "radii": radii, + "fill_mode": fill_mode, + "labels": labels, + "show_labels": show_labels, + "class_ids": class_ids, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Boxes3D: + """Clear all the fields of a `Boxes3D`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + half_sizes=[], + centers=[], + rotation_axis_angles=[], + quaternions=[], + colors=[], + radii=[], + fill_mode=[], + labels=[], + show_labels=[], + class_ids=[], + ) + return inst + + half_sizes: components.HalfSize3DBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.HalfSize3DBatch._converter, # type: ignore[misc] ) # All half-extents that make up the batch of boxes. # # (Docstring intentionally commented out to hide this field from the docs) centers: components.PoseTranslation3DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.PoseTranslation3DBatch._optional, # type: ignore[misc] + converter=components.PoseTranslation3DBatch._converter, # type: ignore[misc] ) # Optional center positions of the boxes. # @@ -106,9 +210,9 @@ def _clear(cls) -> Boxes3D: # (Docstring intentionally commented out to hide this field from the docs) rotation_axis_angles: components.PoseRotationAxisAngleBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.PoseRotationAxisAngleBatch._optional, # type: ignore[misc] + converter=components.PoseRotationAxisAngleBatch._converter, # type: ignore[misc] ) # Rotations via axis + angle. # @@ -118,9 +222,9 @@ def _clear(cls) -> Boxes3D: # (Docstring intentionally commented out to hide this field from the docs) quaternions: components.PoseRotationQuatBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.PoseRotationQuatBatch._optional, # type: ignore[misc] + converter=components.PoseRotationQuatBatch._converter, # type: ignore[misc] ) # Rotations via quaternion. # @@ -130,36 +234,36 @@ def _clear(cls) -> Boxes3D: # (Docstring intentionally commented out to hide this field from the docs) colors: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Optional colors for the boxes. # # (Docstring intentionally commented out to hide this field from the docs) radii: components.RadiusBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.RadiusBatch._optional, # type: ignore[misc] + converter=components.RadiusBatch._converter, # type: ignore[misc] ) # Optional radii for the lines that make up the boxes. # # (Docstring intentionally commented out to hide this field from the docs) fill_mode: components.FillModeBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.FillModeBatch._optional, # type: ignore[misc] + converter=components.FillModeBatch._converter, # type: ignore[misc] ) # Optionally choose whether the boxes are drawn with lines or solid. # # (Docstring intentionally commented out to hide this field from the docs) labels: components.TextBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TextBatch._optional, # type: ignore[misc] + converter=components.TextBatch._converter, # type: ignore[misc] ) # Optional text labels for the boxes. # @@ -169,18 +273,18 @@ def _clear(cls) -> Boxes3D: # (Docstring intentionally commented out to hide this field from the docs) show_labels: components.ShowLabelsBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ShowLabelsBatch._optional, # type: ignore[misc] + converter=components.ShowLabelsBatch._converter, # type: ignore[misc] ) # Optional choice of whether the text labels should be shown by default. # # (Docstring intentionally commented out to hide this field from the docs) class_ids: components.ClassIdBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ClassIdBatch._optional, # type: ignore[misc] + converter=components.ClassIdBatch._converter, # type: ignore[misc] ) # Optional [`components.ClassId`][rerun.components.ClassId]s for the boxes. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/capsules3d.py b/rerun_py/rerun_sdk/rerun/archetypes/capsules3d.py index 88516b702c89..798ea93dd751 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/capsules3d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/capsules3d.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .capsules3d_ext import Capsules3DExt __all__ = ["Capsules3D"] @@ -80,15 +81,15 @@ class Capsules3D(Capsules3DExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - lengths=None, # type: ignore[arg-type] - radii=None, # type: ignore[arg-type] - translations=None, # type: ignore[arg-type] - rotation_axis_angles=None, # type: ignore[arg-type] - quaternions=None, # type: ignore[arg-type] - colors=None, # type: ignore[arg-type] - labels=None, # type: ignore[arg-type] - show_labels=None, # type: ignore[arg-type] - class_ids=None, # type: ignore[arg-type] + lengths=None, + radii=None, + translations=None, + rotation_axis_angles=None, + quaternions=None, + colors=None, + labels=None, + show_labels=None, + class_ids=None, ) @classmethod @@ -98,26 +99,122 @@ def _clear(cls) -> Capsules3D: inst.__attrs_clear__() return inst - lengths: components.LengthBatch = field( - metadata={"component": "required"}, - converter=components.LengthBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + lengths: datatypes.Float32ArrayLike | None = None, + radii: datatypes.Float32ArrayLike | None = None, + translations: datatypes.Vec3DArrayLike | None = None, + rotation_axis_angles: datatypes.RotationAxisAngleArrayLike | None = None, + quaternions: datatypes.QuaternionArrayLike | None = None, + colors: datatypes.Rgba32ArrayLike | None = None, + labels: datatypes.Utf8ArrayLike | None = None, + show_labels: datatypes.BoolLike | None = None, + class_ids: datatypes.ClassIdArrayLike | None = None, + ) -> Capsules3D: + """ + Update only some specific fields of a `Capsules3D`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + lengths: + Lengths of the capsules, defined as the distance between the centers of the endcaps. + radii: + Radii of the capsules. + translations: + Optional translations of the capsules. + + If not specified, one end of each capsule will be at (0, 0, 0). + Note that this uses a [`components.PoseTranslation3D`][rerun.components.PoseTranslation3D] which is also used by [`archetypes.InstancePoses3D`][rerun.archetypes.InstancePoses3D]. + rotation_axis_angles: + Rotations via axis + angle. + + If no rotation is specified, the capsules align with the +Z axis of the local coordinate system. + Note that this uses a [`components.PoseRotationAxisAngle`][rerun.components.PoseRotationAxisAngle] which is also used by [`archetypes.InstancePoses3D`][rerun.archetypes.InstancePoses3D]. + quaternions: + Rotations via quaternion. + + If no rotation is specified, the capsules align with the +Z axis of the local coordinate system. + Note that this uses a [`components.PoseRotationQuat`][rerun.components.PoseRotationQuat] which is also used by [`archetypes.InstancePoses3D`][rerun.archetypes.InstancePoses3D]. + colors: + Optional colors for the capsules. + labels: + Optional text labels for the capsules, which will be located at their centers. + show_labels: + Optional choice of whether the text labels should be shown by default. + class_ids: + Optional class ID for the ellipsoids. + + The class ID provides colors and labels if not specified explicitly. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "lengths": lengths, + "radii": radii, + "translations": translations, + "rotation_axis_angles": rotation_axis_angles, + "quaternions": quaternions, + "colors": colors, + "labels": labels, + "show_labels": show_labels, + "class_ids": class_ids, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Capsules3D: + """Clear all the fields of a `Capsules3D`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + lengths=[], + radii=[], + translations=[], + rotation_axis_angles=[], + quaternions=[], + colors=[], + labels=[], + show_labels=[], + class_ids=[], + ) + return inst + + lengths: components.LengthBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.LengthBatch._converter, # type: ignore[misc] ) # Lengths of the capsules, defined as the distance between the centers of the endcaps. # # (Docstring intentionally commented out to hide this field from the docs) - radii: components.RadiusBatch = field( - metadata={"component": "required"}, - converter=components.RadiusBatch._required, # type: ignore[misc] + radii: components.RadiusBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.RadiusBatch._converter, # type: ignore[misc] ) # Radii of the capsules. # # (Docstring intentionally commented out to hide this field from the docs) translations: components.PoseTranslation3DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.PoseTranslation3DBatch._optional, # type: ignore[misc] + converter=components.PoseTranslation3DBatch._converter, # type: ignore[misc] ) # Optional translations of the capsules. # @@ -127,9 +224,9 @@ def _clear(cls) -> Capsules3D: # (Docstring intentionally commented out to hide this field from the docs) rotation_axis_angles: components.PoseRotationAxisAngleBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.PoseRotationAxisAngleBatch._optional, # type: ignore[misc] + converter=components.PoseRotationAxisAngleBatch._converter, # type: ignore[misc] ) # Rotations via axis + angle. # @@ -139,9 +236,9 @@ def _clear(cls) -> Capsules3D: # (Docstring intentionally commented out to hide this field from the docs) quaternions: components.PoseRotationQuatBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.PoseRotationQuatBatch._optional, # type: ignore[misc] + converter=components.PoseRotationQuatBatch._converter, # type: ignore[misc] ) # Rotations via quaternion. # @@ -151,36 +248,36 @@ def _clear(cls) -> Capsules3D: # (Docstring intentionally commented out to hide this field from the docs) colors: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Optional colors for the capsules. # # (Docstring intentionally commented out to hide this field from the docs) labels: components.TextBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TextBatch._optional, # type: ignore[misc] + converter=components.TextBatch._converter, # type: ignore[misc] ) # Optional text labels for the capsules, which will be located at their centers. # # (Docstring intentionally commented out to hide this field from the docs) show_labels: components.ShowLabelsBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ShowLabelsBatch._optional, # type: ignore[misc] + converter=components.ShowLabelsBatch._converter, # type: ignore[misc] ) # Optional choice of whether the text labels should be shown by default. # # (Docstring intentionally commented out to hide this field from the docs) class_ids: components.ClassIdBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ClassIdBatch._optional, # type: ignore[misc] + converter=components.ClassIdBatch._converter, # type: ignore[misc] ) # Optional class ID for the ellipsoids. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/clear.py b/rerun_py/rerun_sdk/rerun/archetypes/clear.py index 47c13e4383e3..24f9d45ab594 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/clear.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/clear.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .clear_ext import ClearExt __all__ = ["Clear"] @@ -68,7 +69,7 @@ class Clear(ClearExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - is_recursive=None, # type: ignore[arg-type] + is_recursive=None, ) @classmethod @@ -78,9 +79,43 @@ def _clear(cls) -> Clear: inst.__attrs_clear__() return inst - is_recursive: components.ClearIsRecursiveBatch = field( - metadata={"component": "required"}, - converter=components.ClearIsRecursiveBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + is_recursive: datatypes.BoolLike | None = None, + ) -> Clear: + """Update only some specific fields of a `Clear`.""" + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "is_recursive": is_recursive, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Clear: + """Clear all the fields of a `Clear`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + is_recursive=[], + ) + return inst + + is_recursive: components.ClearIsRecursiveBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.ClearIsRecursiveBatch._converter, # type: ignore[misc] ) __str__ = Archetype.__str__ __repr__ = Archetype.__repr__ # type: ignore[assignment] diff --git a/rerun_py/rerun_sdk/rerun/archetypes/depth_image.py b/rerun_py/rerun_sdk/rerun/archetypes/depth_image.py index 5fc1d1ed023c..a357abff9aa1 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/depth_image.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/depth_image.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .depth_image_ext import DepthImageExt __all__ = ["DepthImage"] @@ -66,13 +67,13 @@ class DepthImage(DepthImageExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - buffer=None, # type: ignore[arg-type] - format=None, # type: ignore[arg-type] - meter=None, # type: ignore[arg-type] - colormap=None, # type: ignore[arg-type] - depth_range=None, # type: ignore[arg-type] - point_fill_ratio=None, # type: ignore[arg-type] - draw_order=None, # type: ignore[arg-type] + buffer=None, + format=None, + meter=None, + colormap=None, + depth_range=None, + point_fill_ratio=None, + draw_order=None, ) @classmethod @@ -82,26 +83,127 @@ def _clear(cls) -> DepthImage: inst.__attrs_clear__() return inst - buffer: components.ImageBufferBatch = field( - metadata={"component": "required"}, - converter=components.ImageBufferBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + buffer: datatypes.BlobLike | None = None, + format: datatypes.ImageFormatLike | None = None, + meter: datatypes.Float32Like | None = None, + colormap: components.ColormapLike | None = None, + depth_range: datatypes.Range1DLike | None = None, + point_fill_ratio: datatypes.Float32Like | None = None, + draw_order: datatypes.Float32Like | None = None, + ) -> DepthImage: + """ + Update only some specific fields of a `DepthImage`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + buffer: + The raw depth image data. + format: + The format of the image. + meter: + An optional floating point value that specifies how long a meter is in the native depth units. + + For instance: with uint16, perhaps meter=1000 which would mean you have millimeter precision + and a range of up to ~65 meters (2^16 / 1000). + + Note that the only effect on 2D views is the physical depth values shown when hovering the image. + In 3D views on the other hand, this affects where the points of the point cloud are placed. + colormap: + Colormap to use for rendering the depth image. + + If not set, the depth image will be rendered using the Turbo colormap. + depth_range: + The expected range of depth values. + + This is typically the expected range of valid values. + Everything outside of the range is clamped to the range for the purpose of colormpaping. + Note that point clouds generated from this image will still display all points, regardless of this range. + + If not specified, the range will be automatically estimated from the data. + Note that the Viewer may try to guess a wider range than the minimum/maximum of values + in the contents of the depth image. + E.g. if all values are positive, some bigger than 1.0 and all smaller than 255.0, + the Viewer will guess that the data likely came from an 8bit image, thus assuming a range of 0-255. + point_fill_ratio: + Scale the radii of the points in the point cloud generated from this image. + + A fill ratio of 1.0 (the default) means that each point is as big as to touch the center of its neighbor + if it is at the same depth, leaving no gaps. + A fill ratio of 0.5 means that each point touches the edge of its neighbor if it has the same depth. + + TODO(#6744): This applies only to 3D views! + draw_order: + An optional floating point value that specifies the 2D drawing order, used only if the depth image is shown as a 2D image. + + Objects with higher values are drawn on top of those with lower values. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "buffer": buffer, + "format": format, + "meter": meter, + "colormap": colormap, + "depth_range": depth_range, + "point_fill_ratio": point_fill_ratio, + "draw_order": draw_order, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> DepthImage: + """Clear all the fields of a `DepthImage`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + buffer=[], + format=[], + meter=[], + colormap=[], + depth_range=[], + point_fill_ratio=[], + draw_order=[], + ) + return inst + + buffer: components.ImageBufferBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.ImageBufferBatch._converter, # type: ignore[misc] ) # The raw depth image data. # # (Docstring intentionally commented out to hide this field from the docs) - format: components.ImageFormatBatch = field( - metadata={"component": "required"}, - converter=components.ImageFormatBatch._required, # type: ignore[misc] + format: components.ImageFormatBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.ImageFormatBatch._converter, # type: ignore[misc] ) # The format of the image. # # (Docstring intentionally commented out to hide this field from the docs) meter: components.DepthMeterBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.DepthMeterBatch._optional, # type: ignore[misc] + converter=components.DepthMeterBatch._converter, # type: ignore[misc] ) # An optional floating point value that specifies how long a meter is in the native depth units. # @@ -114,9 +216,9 @@ def _clear(cls) -> DepthImage: # (Docstring intentionally commented out to hide this field from the docs) colormap: components.ColormapBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColormapBatch._optional, # type: ignore[misc] + converter=components.ColormapBatch._converter, # type: ignore[misc] ) # Colormap to use for rendering the depth image. # @@ -125,9 +227,9 @@ def _clear(cls) -> DepthImage: # (Docstring intentionally commented out to hide this field from the docs) depth_range: components.ValueRangeBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ValueRangeBatch._optional, # type: ignore[misc] + converter=components.ValueRangeBatch._converter, # type: ignore[misc] ) # The expected range of depth values. # @@ -144,9 +246,9 @@ def _clear(cls) -> DepthImage: # (Docstring intentionally commented out to hide this field from the docs) point_fill_ratio: components.FillRatioBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.FillRatioBatch._optional, # type: ignore[misc] + converter=components.FillRatioBatch._converter, # type: ignore[misc] ) # Scale the radii of the points in the point cloud generated from this image. # @@ -159,9 +261,9 @@ def _clear(cls) -> DepthImage: # (Docstring intentionally commented out to hide this field from the docs) draw_order: components.DrawOrderBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.DrawOrderBatch._optional, # type: ignore[misc] + converter=components.DrawOrderBatch._converter, # type: ignore[misc] ) # An optional floating point value that specifies the 2D drawing order, used only if the depth image is shown as a 2D image. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/ellipsoids3d.py b/rerun_py/rerun_sdk/rerun/archetypes/ellipsoids3d.py index d96015a93802..fa001fc3f920 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/ellipsoids3d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/ellipsoids3d.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .ellipsoids3d_ext import Ellipsoids3DExt __all__ = ["Ellipsoids3D"] @@ -69,16 +70,16 @@ class Ellipsoids3D(Ellipsoids3DExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - half_sizes=None, # type: ignore[arg-type] - centers=None, # type: ignore[arg-type] - rotation_axis_angles=None, # type: ignore[arg-type] - quaternions=None, # type: ignore[arg-type] - colors=None, # type: ignore[arg-type] - line_radii=None, # type: ignore[arg-type] - fill_mode=None, # type: ignore[arg-type] - labels=None, # type: ignore[arg-type] - show_labels=None, # type: ignore[arg-type] - class_ids=None, # type: ignore[arg-type] + half_sizes=None, + centers=None, + rotation_axis_angles=None, + quaternions=None, + colors=None, + line_radii=None, + fill_mode=None, + labels=None, + show_labels=None, + class_ids=None, ) @classmethod @@ -88,9 +89,111 @@ def _clear(cls) -> Ellipsoids3D: inst.__attrs_clear__() return inst - half_sizes: components.HalfSize3DBatch = field( - metadata={"component": "required"}, - converter=components.HalfSize3DBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + half_sizes: datatypes.Vec3DArrayLike | None = None, + centers: datatypes.Vec3DArrayLike | None = None, + rotation_axis_angles: datatypes.RotationAxisAngleArrayLike | None = None, + quaternions: datatypes.QuaternionArrayLike | None = None, + colors: datatypes.Rgba32ArrayLike | None = None, + line_radii: datatypes.Float32ArrayLike | None = None, + fill_mode: components.FillModeLike | None = None, + labels: datatypes.Utf8ArrayLike | None = None, + show_labels: datatypes.BoolLike | None = None, + class_ids: datatypes.ClassIdArrayLike | None = None, + ) -> Ellipsoids3D: + """ + Update only some specific fields of a `Ellipsoids3D`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + half_sizes: + For each ellipsoid, half of its size on its three axes. + + If all components are equal, then it is a sphere with that radius. + centers: + Optional center positions of the ellipsoids. + + If not specified, the centers will be at (0, 0, 0). + Note that this uses a [`components.PoseTranslation3D`][rerun.components.PoseTranslation3D] which is also used by [`archetypes.InstancePoses3D`][rerun.archetypes.InstancePoses3D]. + rotation_axis_angles: + Rotations via axis + angle. + + If no rotation is specified, the axes of the ellipsoid align with the axes of the local coordinate system. + Note that this uses a [`components.PoseRotationAxisAngle`][rerun.components.PoseRotationAxisAngle] which is also used by [`archetypes.InstancePoses3D`][rerun.archetypes.InstancePoses3D]. + quaternions: + Rotations via quaternion. + + If no rotation is specified, the axes of the ellipsoid align with the axes of the local coordinate system. + Note that this uses a [`components.PoseRotationQuat`][rerun.components.PoseRotationQuat] which is also used by [`archetypes.InstancePoses3D`][rerun.archetypes.InstancePoses3D]. + colors: + Optional colors for the ellipsoids. + line_radii: + Optional radii for the lines used when the ellipsoid is rendered as a wireframe. + fill_mode: + Optionally choose whether the ellipsoids are drawn with lines or solid. + labels: + Optional text labels for the ellipsoids. + show_labels: + Optional choice of whether the text labels should be shown by default. + class_ids: + Optional class ID for the ellipsoids. + + The class ID provides colors and labels if not specified explicitly. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "half_sizes": half_sizes, + "centers": centers, + "rotation_axis_angles": rotation_axis_angles, + "quaternions": quaternions, + "colors": colors, + "line_radii": line_radii, + "fill_mode": fill_mode, + "labels": labels, + "show_labels": show_labels, + "class_ids": class_ids, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Ellipsoids3D: + """Clear all the fields of a `Ellipsoids3D`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + half_sizes=[], + centers=[], + rotation_axis_angles=[], + quaternions=[], + colors=[], + line_radii=[], + fill_mode=[], + labels=[], + show_labels=[], + class_ids=[], + ) + return inst + + half_sizes: components.HalfSize3DBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.HalfSize3DBatch._converter, # type: ignore[misc] ) # For each ellipsoid, half of its size on its three axes. # @@ -99,9 +202,9 @@ def _clear(cls) -> Ellipsoids3D: # (Docstring intentionally commented out to hide this field from the docs) centers: components.PoseTranslation3DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.PoseTranslation3DBatch._optional, # type: ignore[misc] + converter=components.PoseTranslation3DBatch._converter, # type: ignore[misc] ) # Optional center positions of the ellipsoids. # @@ -111,9 +214,9 @@ def _clear(cls) -> Ellipsoids3D: # (Docstring intentionally commented out to hide this field from the docs) rotation_axis_angles: components.PoseRotationAxisAngleBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.PoseRotationAxisAngleBatch._optional, # type: ignore[misc] + converter=components.PoseRotationAxisAngleBatch._converter, # type: ignore[misc] ) # Rotations via axis + angle. # @@ -123,9 +226,9 @@ def _clear(cls) -> Ellipsoids3D: # (Docstring intentionally commented out to hide this field from the docs) quaternions: components.PoseRotationQuatBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.PoseRotationQuatBatch._optional, # type: ignore[misc] + converter=components.PoseRotationQuatBatch._converter, # type: ignore[misc] ) # Rotations via quaternion. # @@ -135,54 +238,54 @@ def _clear(cls) -> Ellipsoids3D: # (Docstring intentionally commented out to hide this field from the docs) colors: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Optional colors for the ellipsoids. # # (Docstring intentionally commented out to hide this field from the docs) line_radii: components.RadiusBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.RadiusBatch._optional, # type: ignore[misc] + converter=components.RadiusBatch._converter, # type: ignore[misc] ) # Optional radii for the lines used when the ellipsoid is rendered as a wireframe. # # (Docstring intentionally commented out to hide this field from the docs) fill_mode: components.FillModeBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.FillModeBatch._optional, # type: ignore[misc] + converter=components.FillModeBatch._converter, # type: ignore[misc] ) # Optionally choose whether the ellipsoids are drawn with lines or solid. # # (Docstring intentionally commented out to hide this field from the docs) labels: components.TextBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TextBatch._optional, # type: ignore[misc] + converter=components.TextBatch._converter, # type: ignore[misc] ) # Optional text labels for the ellipsoids. # # (Docstring intentionally commented out to hide this field from the docs) show_labels: components.ShowLabelsBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ShowLabelsBatch._optional, # type: ignore[misc] + converter=components.ShowLabelsBatch._converter, # type: ignore[misc] ) # Optional choice of whether the text labels should be shown by default. # # (Docstring intentionally commented out to hide this field from the docs) class_ids: components.ClassIdBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ClassIdBatch._optional, # type: ignore[misc] + converter=components.ClassIdBatch._converter, # type: ignore[misc] ) # Optional class ID for the ellipsoids. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/encoded_image.py b/rerun_py/rerun_sdk/rerun/archetypes/encoded_image.py index 8cc606648010..290025516502 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/encoded_image.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/encoded_image.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .encoded_image_ext import EncodedImageExt __all__ = ["EncodedImage"] @@ -48,10 +49,10 @@ class EncodedImage(EncodedImageExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - blob=None, # type: ignore[arg-type] - media_type=None, # type: ignore[arg-type] - opacity=None, # type: ignore[arg-type] - draw_order=None, # type: ignore[arg-type] + blob=None, + media_type=None, + opacity=None, + draw_order=None, ) @classmethod @@ -61,18 +62,88 @@ def _clear(cls) -> EncodedImage: inst.__attrs_clear__() return inst - blob: components.BlobBatch = field( - metadata={"component": "required"}, - converter=components.BlobBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + blob: datatypes.BlobLike | None = None, + media_type: datatypes.Utf8Like | None = None, + opacity: datatypes.Float32Like | None = None, + draw_order: datatypes.Float32Like | None = None, + ) -> EncodedImage: + """ + Update only some specific fields of a `EncodedImage`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + blob: + The encoded content of some image file, e.g. a PNG or JPEG. + media_type: + The Media Type of the asset. + + Supported values: + * `image/jpeg` + * `image/png` + + If omitted, the viewer will try to guess from the data blob. + If it cannot guess, it won't be able to render the asset. + opacity: + Opacity of the image, useful for layering several images. + + Defaults to 1.0 (fully opaque). + draw_order: + An optional floating point value that specifies the 2D drawing order. + + Objects with higher values are drawn on top of those with lower values. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "blob": blob, + "media_type": media_type, + "opacity": opacity, + "draw_order": draw_order, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> EncodedImage: + """Clear all the fields of a `EncodedImage`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + blob=[], + media_type=[], + opacity=[], + draw_order=[], + ) + return inst + + blob: components.BlobBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.BlobBatch._converter, # type: ignore[misc] ) # The encoded content of some image file, e.g. a PNG or JPEG. # # (Docstring intentionally commented out to hide this field from the docs) media_type: components.MediaTypeBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.MediaTypeBatch._optional, # type: ignore[misc] + converter=components.MediaTypeBatch._converter, # type: ignore[misc] ) # The Media Type of the asset. # @@ -86,9 +157,9 @@ def _clear(cls) -> EncodedImage: # (Docstring intentionally commented out to hide this field from the docs) opacity: components.OpacityBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.OpacityBatch._optional, # type: ignore[misc] + converter=components.OpacityBatch._converter, # type: ignore[misc] ) # Opacity of the image, useful for layering several images. # @@ -97,9 +168,9 @@ def _clear(cls) -> EncodedImage: # (Docstring intentionally commented out to hide this field from the docs) draw_order: components.DrawOrderBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.DrawOrderBatch._optional, # type: ignore[misc] + converter=components.DrawOrderBatch._converter, # type: ignore[misc] ) # An optional floating point value that specifies the 2D drawing order. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/geo_line_strings.py b/rerun_py/rerun_sdk/rerun/archetypes/geo_line_strings.py index 4e79737a229b..56a9c1d78513 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/geo_line_strings.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/geo_line_strings.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .geo_line_strings_ext import GeoLineStringsExt __all__ = ["GeoLineStrings"] @@ -63,9 +64,9 @@ class GeoLineStrings(GeoLineStringsExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - line_strings=None, # type: ignore[arg-type] - radii=None, # type: ignore[arg-type] - colors=None, # type: ignore[arg-type] + line_strings=None, + radii=None, + colors=None, ) @classmethod @@ -75,18 +76,78 @@ def _clear(cls) -> GeoLineStrings: inst.__attrs_clear__() return inst - line_strings: components.GeoLineStringBatch = field( - metadata={"component": "required"}, - converter=components.GeoLineStringBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + line_strings: components.GeoLineStringArrayLike | None = None, + radii: datatypes.Float32ArrayLike | None = None, + colors: datatypes.Rgba32ArrayLike | None = None, + ) -> GeoLineStrings: + """ + Update only some specific fields of a `GeoLineStrings`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + line_strings: + The line strings, expressed in [EPSG:4326](https://epsg.io/4326) coordinates (North/East-positive degrees). + radii: + Optional radii for the line strings. + + *Note*: scene units radiii are interpreted as meters. Currently, the display scale only considers the latitude of + the first vertex of each line string (see [this issue](https://github.com/rerun-io/rerun/issues/8013)). + colors: + Optional colors for the line strings. + + The colors are interpreted as RGB or RGBA in sRGB gamma-space, + As either 0-1 floats or 0-255 integers, with separate alpha. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "line_strings": line_strings, + "radii": radii, + "colors": colors, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> GeoLineStrings: + """Clear all the fields of a `GeoLineStrings`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + line_strings=[], + radii=[], + colors=[], + ) + return inst + + line_strings: components.GeoLineStringBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.GeoLineStringBatch._converter, # type: ignore[misc] ) # The line strings, expressed in [EPSG:4326](https://epsg.io/4326) coordinates (North/East-positive degrees). # # (Docstring intentionally commented out to hide this field from the docs) radii: components.RadiusBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.RadiusBatch._optional, # type: ignore[misc] + converter=components.RadiusBatch._converter, # type: ignore[misc] ) # Optional radii for the line strings. # @@ -96,9 +157,9 @@ def _clear(cls) -> GeoLineStrings: # (Docstring intentionally commented out to hide this field from the docs) colors: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Optional colors for the line strings. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/geo_points.py b/rerun_py/rerun_sdk/rerun/archetypes/geo_points.py index bb707e903c4c..024a8332c32e 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/geo_points.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/geo_points.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .geo_points_ext import GeoPointsExt __all__ = ["GeoPoints"] @@ -55,10 +56,10 @@ class GeoPoints(GeoPointsExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - positions=None, # type: ignore[arg-type] - radii=None, # type: ignore[arg-type] - colors=None, # type: ignore[arg-type] - class_ids=None, # type: ignore[arg-type] + positions=None, + radii=None, + colors=None, + class_ids=None, ) @classmethod @@ -68,18 +69,84 @@ def _clear(cls) -> GeoPoints: inst.__attrs_clear__() return inst - positions: components.LatLonBatch = field( - metadata={"component": "required"}, - converter=components.LatLonBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + positions: datatypes.DVec2DArrayLike | None = None, + radii: datatypes.Float32ArrayLike | None = None, + colors: datatypes.Rgba32ArrayLike | None = None, + class_ids: datatypes.ClassIdArrayLike | None = None, + ) -> GeoPoints: + """ + Update only some specific fields of a `GeoPoints`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + positions: + The [EPSG:4326](https://epsg.io/4326) coordinates for the points (North/East-positive degrees). + radii: + Optional radii for the points, effectively turning them into circles. + + *Note*: scene units radiii are interpreted as meters. + colors: + Optional colors for the points. + + The colors are interpreted as RGB or RGBA in sRGB gamma-space, + As either 0-1 floats or 0-255 integers, with separate alpha. + class_ids: + Optional class Ids for the points. + + The [`components.ClassId`][rerun.components.ClassId] provides colors if not specified explicitly. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "positions": positions, + "radii": radii, + "colors": colors, + "class_ids": class_ids, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> GeoPoints: + """Clear all the fields of a `GeoPoints`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + positions=[], + radii=[], + colors=[], + class_ids=[], + ) + return inst + + positions: components.LatLonBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.LatLonBatch._converter, # type: ignore[misc] ) # The [EPSG:4326](https://epsg.io/4326) coordinates for the points (North/East-positive degrees). # # (Docstring intentionally commented out to hide this field from the docs) radii: components.RadiusBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.RadiusBatch._optional, # type: ignore[misc] + converter=components.RadiusBatch._converter, # type: ignore[misc] ) # Optional radii for the points, effectively turning them into circles. # @@ -88,9 +155,9 @@ def _clear(cls) -> GeoPoints: # (Docstring intentionally commented out to hide this field from the docs) colors: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Optional colors for the points. # @@ -100,9 +167,9 @@ def _clear(cls) -> GeoPoints: # (Docstring intentionally commented out to hide this field from the docs) class_ids: components.ClassIdBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ClassIdBatch._optional, # type: ignore[misc] + converter=components.ClassIdBatch._converter, # type: ignore[misc] ) # Optional class Ids for the points. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/graph_edges.py b/rerun_py/rerun_sdk/rerun/archetypes/graph_edges.py index 9cc648521d64..fd89ff88fa56 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/graph_edges.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/graph_edges.py @@ -77,8 +77,8 @@ def __init__(self: Any, edges: datatypes.Utf8PairArrayLike, *, graph_type: compo def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - edges=None, # type: ignore[arg-type] - graph_type=None, # type: ignore[arg-type] + edges=None, + graph_type=None, ) @classmethod @@ -88,18 +88,69 @@ def _clear(cls) -> GraphEdges: inst.__attrs_clear__() return inst - edges: components.GraphEdgeBatch = field( - metadata={"component": "required"}, - converter=components.GraphEdgeBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + edges: datatypes.Utf8PairArrayLike | None = None, + graph_type: components.GraphTypeLike | None = None, + ) -> GraphEdges: + """ + Update only some specific fields of a `GraphEdges`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + edges: + A list of node tuples. + graph_type: + Specifies if the graph is directed or undirected. + + If no [`components.GraphType`][rerun.components.GraphType] is provided, the graph is assumed to be undirected. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "edges": edges, + "graph_type": graph_type, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> GraphEdges: + """Clear all the fields of a `GraphEdges`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + edges=[], + graph_type=[], + ) + return inst + + edges: components.GraphEdgeBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.GraphEdgeBatch._converter, # type: ignore[misc] ) # A list of node tuples. # # (Docstring intentionally commented out to hide this field from the docs) graph_type: components.GraphTypeBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.GraphTypeBatch._optional, # type: ignore[misc] + converter=components.GraphTypeBatch._converter, # type: ignore[misc] ) # Specifies if the graph is directed or undirected. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/graph_nodes.py b/rerun_py/rerun_sdk/rerun/archetypes/graph_nodes.py index ad23e270e2dc..9e3f77b69065 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/graph_nodes.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/graph_nodes.py @@ -97,12 +97,12 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - node_ids=None, # type: ignore[arg-type] - positions=None, # type: ignore[arg-type] - colors=None, # type: ignore[arg-type] - labels=None, # type: ignore[arg-type] - show_labels=None, # type: ignore[arg-type] - radii=None, # type: ignore[arg-type] + node_ids=None, + positions=None, + colors=None, + labels=None, + show_labels=None, + radii=None, ) @classmethod @@ -112,54 +112,123 @@ def _clear(cls) -> GraphNodes: inst.__attrs_clear__() return inst - node_ids: components.GraphNodeBatch = field( - metadata={"component": "required"}, - converter=components.GraphNodeBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + node_ids: datatypes.Utf8ArrayLike | None = None, + positions: datatypes.Vec2DArrayLike | None = None, + colors: datatypes.Rgba32ArrayLike | None = None, + labels: datatypes.Utf8ArrayLike | None = None, + show_labels: datatypes.BoolLike | None = None, + radii: datatypes.Float32ArrayLike | None = None, + ) -> GraphNodes: + """ + Update only some specific fields of a `GraphNodes`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + node_ids: + A list of node IDs. + positions: + Optional center positions of the nodes. + colors: + Optional colors for the boxes. + labels: + Optional text labels for the node. + show_labels: + Optional choice of whether the text labels should be shown by default. + radii: + Optional radii for nodes. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "node_ids": node_ids, + "positions": positions, + "colors": colors, + "labels": labels, + "show_labels": show_labels, + "radii": radii, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> GraphNodes: + """Clear all the fields of a `GraphNodes`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + node_ids=[], + positions=[], + colors=[], + labels=[], + show_labels=[], + radii=[], + ) + return inst + + node_ids: components.GraphNodeBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.GraphNodeBatch._converter, # type: ignore[misc] ) # A list of node IDs. # # (Docstring intentionally commented out to hide this field from the docs) positions: components.Position2DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.Position2DBatch._optional, # type: ignore[misc] + converter=components.Position2DBatch._converter, # type: ignore[misc] ) # Optional center positions of the nodes. # # (Docstring intentionally commented out to hide this field from the docs) colors: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Optional colors for the boxes. # # (Docstring intentionally commented out to hide this field from the docs) labels: components.TextBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TextBatch._optional, # type: ignore[misc] + converter=components.TextBatch._converter, # type: ignore[misc] ) # Optional text labels for the node. # # (Docstring intentionally commented out to hide this field from the docs) show_labels: components.ShowLabelsBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ShowLabelsBatch._optional, # type: ignore[misc] + converter=components.ShowLabelsBatch._converter, # type: ignore[misc] ) # Optional choice of whether the text labels should be shown by default. # # (Docstring intentionally commented out to hide this field from the docs) radii: components.RadiusBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.RadiusBatch._optional, # type: ignore[misc] + converter=components.RadiusBatch._converter, # type: ignore[misc] ) # Optional radii for nodes. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/image.py b/rerun_py/rerun_sdk/rerun/archetypes/image.py index c0cfb2703d40..de908e7840ea 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/image.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/image.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .image_ext import ImageExt __all__ = ["Image"] @@ -92,10 +93,10 @@ class Image(ImageExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - buffer=None, # type: ignore[arg-type] - format=None, # type: ignore[arg-type] - opacity=None, # type: ignore[arg-type] - draw_order=None, # type: ignore[arg-type] + buffer=None, + format=None, + opacity=None, + draw_order=None, ) @classmethod @@ -105,26 +106,90 @@ def _clear(cls) -> Image: inst.__attrs_clear__() return inst - buffer: components.ImageBufferBatch = field( - metadata={"component": "required"}, - converter=components.ImageBufferBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + buffer: datatypes.BlobLike | None = None, + format: datatypes.ImageFormatLike | None = None, + opacity: datatypes.Float32Like | None = None, + draw_order: datatypes.Float32Like | None = None, + ) -> Image: + """ + Update only some specific fields of a `Image`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + buffer: + The raw image data. + format: + The format of the image. + opacity: + Opacity of the image, useful for layering several images. + + Defaults to 1.0 (fully opaque). + draw_order: + An optional floating point value that specifies the 2D drawing order. + + Objects with higher values are drawn on top of those with lower values. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "buffer": buffer, + "format": format, + "opacity": opacity, + "draw_order": draw_order, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Image: + """Clear all the fields of a `Image`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + buffer=[], + format=[], + opacity=[], + draw_order=[], + ) + return inst + + buffer: components.ImageBufferBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.ImageBufferBatch._converter, # type: ignore[misc] ) # The raw image data. # # (Docstring intentionally commented out to hide this field from the docs) - format: components.ImageFormatBatch = field( - metadata={"component": "required"}, - converter=components.ImageFormatBatch._required, # type: ignore[misc] + format: components.ImageFormatBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.ImageFormatBatch._converter, # type: ignore[misc] ) # The format of the image. # # (Docstring intentionally commented out to hide this field from the docs) opacity: components.OpacityBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.OpacityBatch._optional, # type: ignore[misc] + converter=components.OpacityBatch._converter, # type: ignore[misc] ) # Opacity of the image, useful for layering several images. # @@ -133,9 +198,9 @@ def _clear(cls) -> Image: # (Docstring intentionally commented out to hide this field from the docs) draw_order: components.DrawOrderBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.DrawOrderBatch._optional, # type: ignore[misc] + converter=components.DrawOrderBatch._converter, # type: ignore[misc] ) # An optional floating point value that specifies the 2D drawing order. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/instance_poses3d.py b/rerun_py/rerun_sdk/rerun/archetypes/instance_poses3d.py index 0532c2968c76..146e397d8b9b 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/instance_poses3d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/instance_poses3d.py @@ -114,11 +114,11 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - translations=None, # type: ignore[arg-type] - rotation_axis_angles=None, # type: ignore[arg-type] - quaternions=None, # type: ignore[arg-type] - scales=None, # type: ignore[arg-type] - mat3x3=None, # type: ignore[arg-type] + translations=None, + rotation_axis_angles=None, + quaternions=None, + scales=None, + mat3x3=None, ) @classmethod @@ -128,46 +128,109 @@ def _clear(cls) -> InstancePoses3D: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + translations: datatypes.Vec3DArrayLike | None = None, + rotation_axis_angles: datatypes.RotationAxisAngleArrayLike | None = None, + quaternions: datatypes.QuaternionArrayLike | None = None, + scales: datatypes.Vec3DArrayLike | None = None, + mat3x3: datatypes.Mat3x3ArrayLike | None = None, + ) -> InstancePoses3D: + """ + Update only some specific fields of a `InstancePoses3D`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + translations: + Translation vectors. + rotation_axis_angles: + Rotations via axis + angle. + quaternions: + Rotations via quaternion. + scales: + Scaling factors. + mat3x3: + 3x3 transformation matrices. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "translations": translations, + "rotation_axis_angles": rotation_axis_angles, + "quaternions": quaternions, + "scales": scales, + "mat3x3": mat3x3, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> InstancePoses3D: + """Clear all the fields of a `InstancePoses3D`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + translations=[], + rotation_axis_angles=[], + quaternions=[], + scales=[], + mat3x3=[], + ) + return inst + translations: components.PoseTranslation3DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.PoseTranslation3DBatch._optional, # type: ignore[misc] + converter=components.PoseTranslation3DBatch._converter, # type: ignore[misc] ) # Translation vectors. # # (Docstring intentionally commented out to hide this field from the docs) rotation_axis_angles: components.PoseRotationAxisAngleBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.PoseRotationAxisAngleBatch._optional, # type: ignore[misc] + converter=components.PoseRotationAxisAngleBatch._converter, # type: ignore[misc] ) # Rotations via axis + angle. # # (Docstring intentionally commented out to hide this field from the docs) quaternions: components.PoseRotationQuatBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.PoseRotationQuatBatch._optional, # type: ignore[misc] + converter=components.PoseRotationQuatBatch._converter, # type: ignore[misc] ) # Rotations via quaternion. # # (Docstring intentionally commented out to hide this field from the docs) scales: components.PoseScale3DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.PoseScale3DBatch._optional, # type: ignore[misc] + converter=components.PoseScale3DBatch._converter, # type: ignore[misc] ) # Scaling factors. # # (Docstring intentionally commented out to hide this field from the docs) mat3x3: components.PoseTransformMat3x3Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.PoseTransformMat3x3Batch._optional, # type: ignore[misc] + converter=components.PoseTransformMat3x3Batch._converter, # type: ignore[misc] ) # 3x3 transformation matrices. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/line_strips2d.py b/rerun_py/rerun_sdk/rerun/archetypes/line_strips2d.py index 89891b327415..6f48d660b8c5 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/line_strips2d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/line_strips2d.py @@ -154,13 +154,13 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - strips=None, # type: ignore[arg-type] - radii=None, # type: ignore[arg-type] - colors=None, # type: ignore[arg-type] - labels=None, # type: ignore[arg-type] - show_labels=None, # type: ignore[arg-type] - draw_order=None, # type: ignore[arg-type] - class_ids=None, # type: ignore[arg-type] + strips=None, + radii=None, + colors=None, + labels=None, + show_labels=None, + draw_order=None, + class_ids=None, ) @classmethod @@ -170,36 +170,117 @@ def _clear(cls) -> LineStrips2D: inst.__attrs_clear__() return inst - strips: components.LineStrip2DBatch = field( - metadata={"component": "required"}, - converter=components.LineStrip2DBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + strips: components.LineStrip2DArrayLike | None = None, + radii: datatypes.Float32ArrayLike | None = None, + colors: datatypes.Rgba32ArrayLike | None = None, + labels: datatypes.Utf8ArrayLike | None = None, + show_labels: datatypes.BoolLike | None = None, + draw_order: datatypes.Float32Like | None = None, + class_ids: datatypes.ClassIdArrayLike | None = None, + ) -> LineStrips2D: + """ + Update only some specific fields of a `LineStrips2D`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + strips: + All the actual 2D line strips that make up the batch. + radii: + Optional radii for the line strips. + colors: + Optional colors for the line strips. + labels: + Optional text labels for the line strips. + + If there's a single label present, it will be placed at the center of the entity. + Otherwise, each instance will have its own label. + show_labels: + Optional choice of whether the text labels should be shown by default. + draw_order: + An optional floating point value that specifies the 2D drawing order of each line strip. + + Objects with higher values are drawn on top of those with lower values. + class_ids: + Optional [`components.ClassId`][rerun.components.ClassId]s for the lines. + + The [`components.ClassId`][rerun.components.ClassId] provides colors and labels if not specified explicitly. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "strips": strips, + "radii": radii, + "colors": colors, + "labels": labels, + "show_labels": show_labels, + "draw_order": draw_order, + "class_ids": class_ids, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> LineStrips2D: + """Clear all the fields of a `LineStrips2D`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + strips=[], + radii=[], + colors=[], + labels=[], + show_labels=[], + draw_order=[], + class_ids=[], + ) + return inst + + strips: components.LineStrip2DBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.LineStrip2DBatch._converter, # type: ignore[misc] ) # All the actual 2D line strips that make up the batch. # # (Docstring intentionally commented out to hide this field from the docs) radii: components.RadiusBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.RadiusBatch._optional, # type: ignore[misc] + converter=components.RadiusBatch._converter, # type: ignore[misc] ) # Optional radii for the line strips. # # (Docstring intentionally commented out to hide this field from the docs) colors: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Optional colors for the line strips. # # (Docstring intentionally commented out to hide this field from the docs) labels: components.TextBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TextBatch._optional, # type: ignore[misc] + converter=components.TextBatch._converter, # type: ignore[misc] ) # Optional text labels for the line strips. # @@ -209,18 +290,18 @@ def _clear(cls) -> LineStrips2D: # (Docstring intentionally commented out to hide this field from the docs) show_labels: components.ShowLabelsBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ShowLabelsBatch._optional, # type: ignore[misc] + converter=components.ShowLabelsBatch._converter, # type: ignore[misc] ) # Optional choice of whether the text labels should be shown by default. # # (Docstring intentionally commented out to hide this field from the docs) draw_order: components.DrawOrderBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.DrawOrderBatch._optional, # type: ignore[misc] + converter=components.DrawOrderBatch._converter, # type: ignore[misc] ) # An optional floating point value that specifies the 2D drawing order of each line strip. # @@ -229,9 +310,9 @@ def _clear(cls) -> LineStrips2D: # (Docstring intentionally commented out to hide this field from the docs) class_ids: components.ClassIdBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ClassIdBatch._optional, # type: ignore[misc] + converter=components.ClassIdBatch._converter, # type: ignore[misc] ) # Optional [`components.ClassId`][rerun.components.ClassId]s for the lines. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/line_strips3d.py b/rerun_py/rerun_sdk/rerun/archetypes/line_strips3d.py index 36d6e2e164df..0ed372d2c377 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/line_strips3d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/line_strips3d.py @@ -158,12 +158,12 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - strips=None, # type: ignore[arg-type] - radii=None, # type: ignore[arg-type] - colors=None, # type: ignore[arg-type] - labels=None, # type: ignore[arg-type] - show_labels=None, # type: ignore[arg-type] - class_ids=None, # type: ignore[arg-type] + strips=None, + radii=None, + colors=None, + labels=None, + show_labels=None, + class_ids=None, ) @classmethod @@ -173,36 +173,110 @@ def _clear(cls) -> LineStrips3D: inst.__attrs_clear__() return inst - strips: components.LineStrip3DBatch = field( - metadata={"component": "required"}, - converter=components.LineStrip3DBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + strips: components.LineStrip3DArrayLike | None = None, + radii: datatypes.Float32ArrayLike | None = None, + colors: datatypes.Rgba32ArrayLike | None = None, + labels: datatypes.Utf8ArrayLike | None = None, + show_labels: datatypes.BoolLike | None = None, + class_ids: datatypes.ClassIdArrayLike | None = None, + ) -> LineStrips3D: + """ + Update only some specific fields of a `LineStrips3D`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + strips: + All the actual 3D line strips that make up the batch. + radii: + Optional radii for the line strips. + colors: + Optional colors for the line strips. + labels: + Optional text labels for the line strips. + + If there's a single label present, it will be placed at the center of the entity. + Otherwise, each instance will have its own label. + show_labels: + Optional choice of whether the text labels should be shown by default. + class_ids: + Optional [`components.ClassId`][rerun.components.ClassId]s for the lines. + + The [`components.ClassId`][rerun.components.ClassId] provides colors and labels if not specified explicitly. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "strips": strips, + "radii": radii, + "colors": colors, + "labels": labels, + "show_labels": show_labels, + "class_ids": class_ids, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> LineStrips3D: + """Clear all the fields of a `LineStrips3D`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + strips=[], + radii=[], + colors=[], + labels=[], + show_labels=[], + class_ids=[], + ) + return inst + + strips: components.LineStrip3DBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.LineStrip3DBatch._converter, # type: ignore[misc] ) # All the actual 3D line strips that make up the batch. # # (Docstring intentionally commented out to hide this field from the docs) radii: components.RadiusBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.RadiusBatch._optional, # type: ignore[misc] + converter=components.RadiusBatch._converter, # type: ignore[misc] ) # Optional radii for the line strips. # # (Docstring intentionally commented out to hide this field from the docs) colors: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Optional colors for the line strips. # # (Docstring intentionally commented out to hide this field from the docs) labels: components.TextBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TextBatch._optional, # type: ignore[misc] + converter=components.TextBatch._converter, # type: ignore[misc] ) # Optional text labels for the line strips. # @@ -212,18 +286,18 @@ def _clear(cls) -> LineStrips3D: # (Docstring intentionally commented out to hide this field from the docs) show_labels: components.ShowLabelsBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ShowLabelsBatch._optional, # type: ignore[misc] + converter=components.ShowLabelsBatch._converter, # type: ignore[misc] ) # Optional choice of whether the text labels should be shown by default. # # (Docstring intentionally commented out to hide this field from the docs) class_ids: components.ClassIdBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ClassIdBatch._optional, # type: ignore[misc] + converter=components.ClassIdBatch._converter, # type: ignore[misc] ) # Optional [`components.ClassId`][rerun.components.ClassId]s for the lines. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/mesh3d.py b/rerun_py/rerun_sdk/rerun/archetypes/mesh3d.py index c8ef042185e9..5b58a8239e24 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/mesh3d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/mesh3d.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .mesh3d_ext import Mesh3DExt __all__ = ["Mesh3D"] @@ -102,15 +103,15 @@ class Mesh3D(Mesh3DExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - vertex_positions=None, # type: ignore[arg-type] - triangle_indices=None, # type: ignore[arg-type] - vertex_normals=None, # type: ignore[arg-type] - vertex_colors=None, # type: ignore[arg-type] - vertex_texcoords=None, # type: ignore[arg-type] - albedo_factor=None, # type: ignore[arg-type] - albedo_texture_buffer=None, # type: ignore[arg-type] - albedo_texture_format=None, # type: ignore[arg-type] - class_ids=None, # type: ignore[arg-type] + vertex_positions=None, + triangle_indices=None, + vertex_normals=None, + vertex_colors=None, + vertex_texcoords=None, + albedo_factor=None, + albedo_texture_buffer=None, + albedo_texture_format=None, + class_ids=None, ) @classmethod @@ -120,9 +121,102 @@ def _clear(cls) -> Mesh3D: inst.__attrs_clear__() return inst - vertex_positions: components.Position3DBatch = field( - metadata={"component": "required"}, - converter=components.Position3DBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + vertex_positions: datatypes.Vec3DArrayLike | None = None, + triangle_indices: datatypes.UVec3DArrayLike | None = None, + vertex_normals: datatypes.Vec3DArrayLike | None = None, + vertex_colors: datatypes.Rgba32ArrayLike | None = None, + vertex_texcoords: datatypes.Vec2DArrayLike | None = None, + albedo_factor: datatypes.Rgba32Like | None = None, + albedo_texture_buffer: datatypes.BlobLike | None = None, + albedo_texture_format: datatypes.ImageFormatLike | None = None, + class_ids: datatypes.ClassIdArrayLike | None = None, + ) -> Mesh3D: + """ + Update only some specific fields of a `Mesh3D`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + vertex_positions: + The positions of each vertex. + + If no `triangle_indices` are specified, then each triplet of positions is interpreted as a triangle. + triangle_indices: + Optional indices for the triangles that make up the mesh. + vertex_normals: + An optional normal for each vertex. + vertex_colors: + An optional color for each vertex. + vertex_texcoords: + An optional uv texture coordinate for each vertex. + albedo_factor: + A color multiplier applied to the whole mesh. + albedo_texture_buffer: + Optional albedo texture. + + Used with the [`components.Texcoord2D`][rerun.components.Texcoord2D] of the mesh. + + Currently supports only sRGB(A) textures, ignoring alpha. + (meaning that the tensor must have 3 or 4 channels and use the `u8` format) + albedo_texture_format: + The format of the `albedo_texture_buffer`, if any. + class_ids: + Optional class Ids for the vertices. + + The [`components.ClassId`][rerun.components.ClassId] provides colors and labels if not specified explicitly. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "vertex_positions": vertex_positions, + "triangle_indices": triangle_indices, + "vertex_normals": vertex_normals, + "vertex_colors": vertex_colors, + "vertex_texcoords": vertex_texcoords, + "albedo_factor": albedo_factor, + "albedo_texture_buffer": albedo_texture_buffer, + "albedo_texture_format": albedo_texture_format, + "class_ids": class_ids, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Mesh3D: + """Clear all the fields of a `Mesh3D`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + vertex_positions=[], + triangle_indices=[], + vertex_normals=[], + vertex_colors=[], + vertex_texcoords=[], + albedo_factor=[], + albedo_texture_buffer=[], + albedo_texture_format=[], + class_ids=[], + ) + return inst + + vertex_positions: components.Position3DBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.Position3DBatch._converter, # type: ignore[misc] ) # The positions of each vertex. # @@ -131,54 +225,54 @@ def _clear(cls) -> Mesh3D: # (Docstring intentionally commented out to hide this field from the docs) triangle_indices: components.TriangleIndicesBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TriangleIndicesBatch._optional, # type: ignore[misc] + converter=components.TriangleIndicesBatch._converter, # type: ignore[misc] ) # Optional indices for the triangles that make up the mesh. # # (Docstring intentionally commented out to hide this field from the docs) vertex_normals: components.Vector3DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.Vector3DBatch._optional, # type: ignore[misc] + converter=components.Vector3DBatch._converter, # type: ignore[misc] ) # An optional normal for each vertex. # # (Docstring intentionally commented out to hide this field from the docs) vertex_colors: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # An optional color for each vertex. # # (Docstring intentionally commented out to hide this field from the docs) vertex_texcoords: components.Texcoord2DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.Texcoord2DBatch._optional, # type: ignore[misc] + converter=components.Texcoord2DBatch._converter, # type: ignore[misc] ) # An optional uv texture coordinate for each vertex. # # (Docstring intentionally commented out to hide this field from the docs) albedo_factor: components.AlbedoFactorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AlbedoFactorBatch._optional, # type: ignore[misc] + converter=components.AlbedoFactorBatch._converter, # type: ignore[misc] ) # A color multiplier applied to the whole mesh. # # (Docstring intentionally commented out to hide this field from the docs) albedo_texture_buffer: components.ImageBufferBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ImageBufferBatch._optional, # type: ignore[misc] + converter=components.ImageBufferBatch._converter, # type: ignore[misc] ) # Optional albedo texture. # @@ -190,18 +284,18 @@ def _clear(cls) -> Mesh3D: # (Docstring intentionally commented out to hide this field from the docs) albedo_texture_format: components.ImageFormatBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ImageFormatBatch._optional, # type: ignore[misc] + converter=components.ImageFormatBatch._converter, # type: ignore[misc] ) # The format of the `albedo_texture_buffer`, if any. # # (Docstring intentionally commented out to hide this field from the docs) class_ids: components.ClassIdBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ClassIdBatch._optional, # type: ignore[misc] + converter=components.ClassIdBatch._converter, # type: ignore[misc] ) # Optional class Ids for the vertices. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/pinhole.py b/rerun_py/rerun_sdk/rerun/archetypes/pinhole.py index b32c37db390a..b175a4173cc4 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/pinhole.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/pinhole.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .pinhole_ext import PinholeExt __all__ = ["Pinhole"] @@ -75,10 +76,10 @@ class Pinhole(PinholeExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - image_from_camera=None, # type: ignore[arg-type] - resolution=None, # type: ignore[arg-type] - camera_xyz=None, # type: ignore[arg-type] - image_plane_distance=None, # type: ignore[arg-type] + image_from_camera=None, + resolution=None, + camera_xyz=None, + image_plane_distance=None, ) @classmethod @@ -88,18 +89,112 @@ def _clear(cls) -> Pinhole: inst.__attrs_clear__() return inst - image_from_camera: components.PinholeProjectionBatch = field( - metadata={"component": "required"}, - converter=components.PinholeProjectionBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + image_from_camera: datatypes.Mat3x3Like | None = None, + resolution: datatypes.Vec2DLike | None = None, + camera_xyz: datatypes.ViewCoordinatesLike | None = None, + image_plane_distance: datatypes.Float32Like | None = None, + ) -> Pinhole: + """ + Update only some specific fields of a `Pinhole`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + image_from_camera: + Camera projection, from image coordinates to view coordinates. + resolution: + Pixel resolution (usually integers) of child image space. Width and height. + + Example: + ```text + [1920.0, 1440.0] + ``` + + `image_from_camera` project onto the space spanned by `(0,0)` and `resolution - 1`. + camera_xyz: + Sets the view coordinates for the camera. + + All common values are available as constants on the [`components.ViewCoordinates`][rerun.components.ViewCoordinates] class. + + The default is `ViewCoordinates::RDF`, i.e. X=Right, Y=Down, Z=Forward, and this is also the recommended setting. + This means that the camera frustum will point along the positive Z axis of the parent space, + and the cameras "up" direction will be along the negative Y axis of the parent space. + + The camera frustum will point whichever axis is set to `F` (or the opposite of `B`). + When logging a depth image under this entity, this is the direction the point cloud will be projected. + With `RDF`, the default forward is +Z. + + The frustum's "up" direction will be whichever axis is set to `U` (or the opposite of `D`). + This will match the negative Y direction of pixel space (all images are assumed to have xyz=RDF). + With `RDF`, the default is up is -Y. + + The frustum's "right" direction will be whichever axis is set to `R` (or the opposite of `L`). + This will match the positive X direction of pixel space (all images are assumed to have xyz=RDF). + With `RDF`, the default right is +x. + + Other common formats are `RUB` (X=Right, Y=Up, Z=Back) and `FLU` (X=Forward, Y=Left, Z=Up). + + NOTE: setting this to something else than `RDF` (the default) will change the orientation of the camera frustum, + and make the pinhole matrix not match up with the coordinate system of the pinhole entity. + + The pinhole matrix (the `image_from_camera` argument) always project along the third (Z) axis, + but will be re-oriented to project along the forward axis of the `camera_xyz` argument. + image_plane_distance: + The distance from the camera origin to the image plane when the projection is shown in a 3D viewer. + + This is only used for visualization purposes, and does not affect the projection itself. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "image_from_camera": image_from_camera, + "resolution": resolution, + "camera_xyz": camera_xyz, + "image_plane_distance": image_plane_distance, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Pinhole: + """Clear all the fields of a `Pinhole`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + image_from_camera=[], + resolution=[], + camera_xyz=[], + image_plane_distance=[], + ) + return inst + + image_from_camera: components.PinholeProjectionBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.PinholeProjectionBatch._converter, # type: ignore[misc] ) # Camera projection, from image coordinates to view coordinates. # # (Docstring intentionally commented out to hide this field from the docs) resolution: components.ResolutionBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ResolutionBatch._optional, # type: ignore[misc] + converter=components.ResolutionBatch._converter, # type: ignore[misc] ) # Pixel resolution (usually integers) of child image space. Width and height. # @@ -113,9 +208,9 @@ def _clear(cls) -> Pinhole: # (Docstring intentionally commented out to hide this field from the docs) camera_xyz: components.ViewCoordinatesBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ViewCoordinatesBatch._optional, # type: ignore[misc] + converter=components.ViewCoordinatesBatch._converter, # type: ignore[misc] ) # Sets the view coordinates for the camera. # @@ -148,9 +243,9 @@ def _clear(cls) -> Pinhole: # (Docstring intentionally commented out to hide this field from the docs) image_plane_distance: components.ImagePlaneDistanceBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ImagePlaneDistanceBatch._optional, # type: ignore[misc] + converter=components.ImagePlaneDistanceBatch._converter, # type: ignore[misc] ) # The distance from the camera origin to the image plane when the projection is shown in a 3D viewer. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/points2d.py b/rerun_py/rerun_sdk/rerun/archetypes/points2d.py index 82efdc7e7a7c..2a4c8f88b8d1 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/points2d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/points2d.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .points2d_ext import Points2DExt __all__ = ["Points2D"] @@ -102,14 +103,14 @@ class Points2D(Points2DExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - positions=None, # type: ignore[arg-type] - radii=None, # type: ignore[arg-type] - colors=None, # type: ignore[arg-type] - labels=None, # type: ignore[arg-type] - show_labels=None, # type: ignore[arg-type] - draw_order=None, # type: ignore[arg-type] - class_ids=None, # type: ignore[arg-type] - keypoint_ids=None, # type: ignore[arg-type] + positions=None, + radii=None, + colors=None, + labels=None, + show_labels=None, + draw_order=None, + class_ids=None, + keypoint_ids=None, ) @classmethod @@ -119,27 +120,123 @@ def _clear(cls) -> Points2D: inst.__attrs_clear__() return inst - positions: components.Position2DBatch = field( - metadata={"component": "required"}, - converter=components.Position2DBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + positions: datatypes.Vec2DArrayLike | None = None, + radii: datatypes.Float32ArrayLike | None = None, + colors: datatypes.Rgba32ArrayLike | None = None, + labels: datatypes.Utf8ArrayLike | None = None, + show_labels: datatypes.BoolLike | None = None, + draw_order: datatypes.Float32Like | None = None, + class_ids: datatypes.ClassIdArrayLike | None = None, + keypoint_ids: datatypes.KeypointIdArrayLike | None = None, + ) -> Points2D: + """ + Update only some specific fields of a `Points2D`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + positions: + All the 2D positions at which the point cloud shows points. + radii: + Optional radii for the points, effectively turning them into circles. + colors: + Optional colors for the points. + + The colors are interpreted as RGB or RGBA in sRGB gamma-space, + As either 0-1 floats or 0-255 integers, with separate alpha. + labels: + Optional text labels for the points. + + If there's a single label present, it will be placed at the center of the entity. + Otherwise, each instance will have its own label. + show_labels: + Optional choice of whether the text labels should be shown by default. + draw_order: + An optional floating point value that specifies the 2D drawing order. + + Objects with higher values are drawn on top of those with lower values. + class_ids: + Optional class Ids for the points. + + The [`components.ClassId`][rerun.components.ClassId] provides colors and labels if not specified explicitly. + keypoint_ids: + Optional keypoint IDs for the points, identifying them within a class. + + If keypoint IDs are passed in but no [`components.ClassId`][rerun.components.ClassId]s were specified, the [`components.ClassId`][rerun.components.ClassId] will + default to 0. + This is useful to identify points within a single classification (which is identified + with `class_id`). + E.g. the classification might be 'Person' and the keypoints refer to joints on a + detected skeleton. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "positions": positions, + "radii": radii, + "colors": colors, + "labels": labels, + "show_labels": show_labels, + "draw_order": draw_order, + "class_ids": class_ids, + "keypoint_ids": keypoint_ids, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Points2D: + """Clear all the fields of a `Points2D`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + positions=[], + radii=[], + colors=[], + labels=[], + show_labels=[], + draw_order=[], + class_ids=[], + keypoint_ids=[], + ) + return inst + + positions: components.Position2DBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.Position2DBatch._converter, # type: ignore[misc] ) # All the 2D positions at which the point cloud shows points. # # (Docstring intentionally commented out to hide this field from the docs) radii: components.RadiusBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.RadiusBatch._optional, # type: ignore[misc] + converter=components.RadiusBatch._converter, # type: ignore[misc] ) # Optional radii for the points, effectively turning them into circles. # # (Docstring intentionally commented out to hide this field from the docs) colors: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Optional colors for the points. # @@ -149,9 +246,9 @@ def _clear(cls) -> Points2D: # (Docstring intentionally commented out to hide this field from the docs) labels: components.TextBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TextBatch._optional, # type: ignore[misc] + converter=components.TextBatch._converter, # type: ignore[misc] ) # Optional text labels for the points. # @@ -161,18 +258,18 @@ def _clear(cls) -> Points2D: # (Docstring intentionally commented out to hide this field from the docs) show_labels: components.ShowLabelsBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ShowLabelsBatch._optional, # type: ignore[misc] + converter=components.ShowLabelsBatch._converter, # type: ignore[misc] ) # Optional choice of whether the text labels should be shown by default. # # (Docstring intentionally commented out to hide this field from the docs) draw_order: components.DrawOrderBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.DrawOrderBatch._optional, # type: ignore[misc] + converter=components.DrawOrderBatch._converter, # type: ignore[misc] ) # An optional floating point value that specifies the 2D drawing order. # @@ -181,9 +278,9 @@ def _clear(cls) -> Points2D: # (Docstring intentionally commented out to hide this field from the docs) class_ids: components.ClassIdBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ClassIdBatch._optional, # type: ignore[misc] + converter=components.ClassIdBatch._converter, # type: ignore[misc] ) # Optional class Ids for the points. # @@ -192,9 +289,9 @@ def _clear(cls) -> Points2D: # (Docstring intentionally commented out to hide this field from the docs) keypoint_ids: components.KeypointIdBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.KeypointIdBatch._optional, # type: ignore[misc] + converter=components.KeypointIdBatch._converter, # type: ignore[misc] ) # Optional keypoint IDs for the points, identifying them within a class. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/points3d.py b/rerun_py/rerun_sdk/rerun/archetypes/points3d.py index d26e51b6cd61..59e04a50f8c3 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/points3d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/points3d.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .points3d_ext import Points3DExt __all__ = ["Points3D"] @@ -137,13 +138,13 @@ class Points3D(Points3DExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - positions=None, # type: ignore[arg-type] - radii=None, # type: ignore[arg-type] - colors=None, # type: ignore[arg-type] - labels=None, # type: ignore[arg-type] - show_labels=None, # type: ignore[arg-type] - class_ids=None, # type: ignore[arg-type] - keypoint_ids=None, # type: ignore[arg-type] + positions=None, + radii=None, + colors=None, + labels=None, + show_labels=None, + class_ids=None, + keypoint_ids=None, ) @classmethod @@ -153,27 +154,116 @@ def _clear(cls) -> Points3D: inst.__attrs_clear__() return inst - positions: components.Position3DBatch = field( - metadata={"component": "required"}, - converter=components.Position3DBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + positions: datatypes.Vec3DArrayLike | None = None, + radii: datatypes.Float32ArrayLike | None = None, + colors: datatypes.Rgba32ArrayLike | None = None, + labels: datatypes.Utf8ArrayLike | None = None, + show_labels: datatypes.BoolLike | None = None, + class_ids: datatypes.ClassIdArrayLike | None = None, + keypoint_ids: datatypes.KeypointIdArrayLike | None = None, + ) -> Points3D: + """ + Update only some specific fields of a `Points3D`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + positions: + All the 3D positions at which the point cloud shows points. + radii: + Optional radii for the points, effectively turning them into circles. + colors: + Optional colors for the points. + + The colors are interpreted as RGB or RGBA in sRGB gamma-space, + As either 0-1 floats or 0-255 integers, with separate alpha. + labels: + Optional text labels for the points. + + If there's a single label present, it will be placed at the center of the entity. + Otherwise, each instance will have its own label. + show_labels: + Optional choice of whether the text labels should be shown by default. + class_ids: + Optional class Ids for the points. + + The [`components.ClassId`][rerun.components.ClassId] provides colors and labels if not specified explicitly. + keypoint_ids: + Optional keypoint IDs for the points, identifying them within a class. + + If keypoint IDs are passed in but no [`components.ClassId`][rerun.components.ClassId]s were specified, the [`components.ClassId`][rerun.components.ClassId] will + default to 0. + This is useful to identify points within a single classification (which is identified + with `class_id`). + E.g. the classification might be 'Person' and the keypoints refer to joints on a + detected skeleton. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "positions": positions, + "radii": radii, + "colors": colors, + "labels": labels, + "show_labels": show_labels, + "class_ids": class_ids, + "keypoint_ids": keypoint_ids, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Points3D: + """Clear all the fields of a `Points3D`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + positions=[], + radii=[], + colors=[], + labels=[], + show_labels=[], + class_ids=[], + keypoint_ids=[], + ) + return inst + + positions: components.Position3DBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.Position3DBatch._converter, # type: ignore[misc] ) # All the 3D positions at which the point cloud shows points. # # (Docstring intentionally commented out to hide this field from the docs) radii: components.RadiusBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.RadiusBatch._optional, # type: ignore[misc] + converter=components.RadiusBatch._converter, # type: ignore[misc] ) # Optional radii for the points, effectively turning them into circles. # # (Docstring intentionally commented out to hide this field from the docs) colors: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Optional colors for the points. # @@ -183,9 +273,9 @@ def _clear(cls) -> Points3D: # (Docstring intentionally commented out to hide this field from the docs) labels: components.TextBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TextBatch._optional, # type: ignore[misc] + converter=components.TextBatch._converter, # type: ignore[misc] ) # Optional text labels for the points. # @@ -195,18 +285,18 @@ def _clear(cls) -> Points3D: # (Docstring intentionally commented out to hide this field from the docs) show_labels: components.ShowLabelsBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ShowLabelsBatch._optional, # type: ignore[misc] + converter=components.ShowLabelsBatch._converter, # type: ignore[misc] ) # Optional choice of whether the text labels should be shown by default. # # (Docstring intentionally commented out to hide this field from the docs) class_ids: components.ClassIdBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ClassIdBatch._optional, # type: ignore[misc] + converter=components.ClassIdBatch._converter, # type: ignore[misc] ) # Optional class Ids for the points. # @@ -215,9 +305,9 @@ def _clear(cls) -> Points3D: # (Docstring intentionally commented out to hide this field from the docs) keypoint_ids: components.KeypointIdBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.KeypointIdBatch._optional, # type: ignore[misc] + converter=components.KeypointIdBatch._converter, # type: ignore[misc] ) # Optional keypoint IDs for the points, identifying them within a class. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/scalar.py b/rerun_py/rerun_sdk/rerun/archetypes/scalar.py index 74490b7546da..903a53043511 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/scalar.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/scalar.py @@ -78,7 +78,7 @@ def __init__(self: Any, scalar: datatypes.Float64Like): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - scalar=None, # type: ignore[arg-type] + scalar=None, ) @classmethod @@ -88,9 +88,53 @@ def _clear(cls) -> Scalar: inst.__attrs_clear__() return inst - scalar: components.ScalarBatch = field( - metadata={"component": "required"}, - converter=components.ScalarBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + scalar: datatypes.Float64Like | None = None, + ) -> Scalar: + """ + Update only some specific fields of a `Scalar`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + scalar: + The scalar value to log. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "scalar": scalar, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Scalar: + """Clear all the fields of a `Scalar`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + scalar=[], + ) + return inst + + scalar: components.ScalarBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.ScalarBatch._converter, # type: ignore[misc] ) # The scalar value to log. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/segmentation_image.py b/rerun_py/rerun_sdk/rerun/archetypes/segmentation_image.py index 109da3576ec8..31daaff19597 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/segmentation_image.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/segmentation_image.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .segmentation_image_ext import SegmentationImageExt __all__ = ["SegmentationImage"] @@ -64,10 +65,10 @@ class SegmentationImage(SegmentationImageExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - buffer=None, # type: ignore[arg-type] - format=None, # type: ignore[arg-type] - opacity=None, # type: ignore[arg-type] - draw_order=None, # type: ignore[arg-type] + buffer=None, + format=None, + opacity=None, + draw_order=None, ) @classmethod @@ -77,26 +78,90 @@ def _clear(cls) -> SegmentationImage: inst.__attrs_clear__() return inst - buffer: components.ImageBufferBatch = field( - metadata={"component": "required"}, - converter=components.ImageBufferBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + buffer: datatypes.BlobLike | None = None, + format: datatypes.ImageFormatLike | None = None, + opacity: datatypes.Float32Like | None = None, + draw_order: datatypes.Float32Like | None = None, + ) -> SegmentationImage: + """ + Update only some specific fields of a `SegmentationImage`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + buffer: + The raw image data. + format: + The format of the image. + opacity: + Opacity of the image, useful for layering the segmentation image on top of another image. + + Defaults to 0.5 if there's any other images in the scene, otherwise 1.0. + draw_order: + An optional floating point value that specifies the 2D drawing order. + + Objects with higher values are drawn on top of those with lower values. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "buffer": buffer, + "format": format, + "opacity": opacity, + "draw_order": draw_order, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> SegmentationImage: + """Clear all the fields of a `SegmentationImage`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + buffer=[], + format=[], + opacity=[], + draw_order=[], + ) + return inst + + buffer: components.ImageBufferBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.ImageBufferBatch._converter, # type: ignore[misc] ) # The raw image data. # # (Docstring intentionally commented out to hide this field from the docs) - format: components.ImageFormatBatch = field( - metadata={"component": "required"}, - converter=components.ImageFormatBatch._required, # type: ignore[misc] + format: components.ImageFormatBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.ImageFormatBatch._converter, # type: ignore[misc] ) # The format of the image. # # (Docstring intentionally commented out to hide this field from the docs) opacity: components.OpacityBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.OpacityBatch._optional, # type: ignore[misc] + converter=components.OpacityBatch._converter, # type: ignore[misc] ) # Opacity of the image, useful for layering the segmentation image on top of another image. # @@ -105,9 +170,9 @@ def _clear(cls) -> SegmentationImage: # (Docstring intentionally commented out to hide this field from the docs) draw_order: components.DrawOrderBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.DrawOrderBatch._optional, # type: ignore[misc] + converter=components.DrawOrderBatch._converter, # type: ignore[misc] ) # An optional floating point value that specifies the 2D drawing order. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/series_line.py b/rerun_py/rerun_sdk/rerun/archetypes/series_line.py index 8abaed3d5e5b..54b907139ec3 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/series_line.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/series_line.py @@ -101,10 +101,10 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - color=None, # type: ignore[arg-type] - width=None, # type: ignore[arg-type] - name=None, # type: ignore[arg-type] - aggregation_policy=None, # type: ignore[arg-type] + color=None, + width=None, + name=None, + aggregation_policy=None, ) @classmethod @@ -114,28 +114,92 @@ def _clear(cls) -> SeriesLine: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + color: datatypes.Rgba32Like | None = None, + width: datatypes.Float32Like | None = None, + name: datatypes.Utf8Like | None = None, + aggregation_policy: components.AggregationPolicyLike | None = None, + ) -> SeriesLine: + """ + Update only some specific fields of a `SeriesLine`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + color: + Color for the corresponding series. + width: + Stroke width for the corresponding series. + name: + Display name of the series. + + Used in the legend. + aggregation_policy: + Configures the zoom-dependent scalar aggregation. + + This is done only if steps on the X axis go below a single pixel, + i.e. a single pixel covers more than one tick worth of data. It can greatly improve performance + (and readability) in such situations as it prevents overdraw. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "color": color, + "width": width, + "name": name, + "aggregation_policy": aggregation_policy, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> SeriesLine: + """Clear all the fields of a `SeriesLine`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + color=[], + width=[], + name=[], + aggregation_policy=[], + ) + return inst + color: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Color for the corresponding series. # # (Docstring intentionally commented out to hide this field from the docs) width: components.StrokeWidthBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.StrokeWidthBatch._optional, # type: ignore[misc] + converter=components.StrokeWidthBatch._converter, # type: ignore[misc] ) # Stroke width for the corresponding series. # # (Docstring intentionally commented out to hide this field from the docs) name: components.NameBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.NameBatch._optional, # type: ignore[misc] + converter=components.NameBatch._converter, # type: ignore[misc] ) # Display name of the series. # @@ -144,9 +208,9 @@ def _clear(cls) -> SeriesLine: # (Docstring intentionally commented out to hide this field from the docs) aggregation_policy: components.AggregationPolicyBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AggregationPolicyBatch._optional, # type: ignore[misc] + converter=components.AggregationPolicyBatch._converter, # type: ignore[misc] ) # Configures the zoom-dependent scalar aggregation. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/series_point.py b/rerun_py/rerun_sdk/rerun/archetypes/series_point.py index b89d0b51d42f..01347718ffc4 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/series_point.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/series_point.py @@ -115,10 +115,10 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - color=None, # type: ignore[arg-type] - marker=None, # type: ignore[arg-type] - name=None, # type: ignore[arg-type] - marker_size=None, # type: ignore[arg-type] + color=None, + marker=None, + name=None, + marker_size=None, ) @classmethod @@ -128,28 +128,88 @@ def _clear(cls) -> SeriesPoint: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + color: datatypes.Rgba32Like | None = None, + marker: components.MarkerShapeLike | None = None, + name: datatypes.Utf8Like | None = None, + marker_size: datatypes.Float32Like | None = None, + ) -> SeriesPoint: + """ + Update only some specific fields of a `SeriesPoint`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + color: + Color for the corresponding series. + marker: + What shape to use to represent the point + name: + Display name of the series. + + Used in the legend. + marker_size: + Size of the marker. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "color": color, + "marker": marker, + "name": name, + "marker_size": marker_size, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> SeriesPoint: + """Clear all the fields of a `SeriesPoint`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + color=[], + marker=[], + name=[], + marker_size=[], + ) + return inst + color: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Color for the corresponding series. # # (Docstring intentionally commented out to hide this field from the docs) marker: components.MarkerShapeBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.MarkerShapeBatch._optional, # type: ignore[misc] + converter=components.MarkerShapeBatch._converter, # type: ignore[misc] ) # What shape to use to represent the point # # (Docstring intentionally commented out to hide this field from the docs) name: components.NameBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.NameBatch._optional, # type: ignore[misc] + converter=components.NameBatch._converter, # type: ignore[misc] ) # Display name of the series. # @@ -158,9 +218,9 @@ def _clear(cls) -> SeriesPoint: # (Docstring intentionally commented out to hide this field from the docs) marker_size: components.MarkerSizeBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.MarkerSizeBatch._optional, # type: ignore[misc] + converter=components.MarkerSizeBatch._converter, # type: ignore[misc] ) # Size of the marker. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/tensor.py b/rerun_py/rerun_sdk/rerun/archetypes/tensor.py index 9c9a90ec5cda..b497dcd44544 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/tensor.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/tensor.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .tensor_ext import TensorExt __all__ = ["Tensor"] @@ -56,8 +57,8 @@ class Tensor(TensorExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - data=None, # type: ignore[arg-type] - value_range=None, # type: ignore[arg-type] + data=None, + value_range=None, ) @classmethod @@ -67,18 +68,77 @@ def _clear(cls) -> Tensor: inst.__attrs_clear__() return inst - data: components.TensorDataBatch = field( - metadata={"component": "required"}, - converter=components.TensorDataBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + data: datatypes.TensorDataLike | None = None, + value_range: datatypes.Range1DLike | None = None, + ) -> Tensor: + """ + Update only some specific fields of a `Tensor`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + data: + The tensor data + value_range: + The expected range of values. + + This is typically the expected range of valid values. + Everything outside of the range is clamped to the range for the purpose of colormpaping. + Any colormap applied for display, will map this range. + + If not specified, the range will be automatically estimated from the data. + Note that the Viewer may try to guess a wider range than the minimum/maximum of values + in the contents of the tensor. + E.g. if all values are positive, some bigger than 1.0 and all smaller than 255.0, + the Viewer will guess that the data likely came from an 8bit image, thus assuming a range of 0-255. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "data": data, + "value_range": value_range, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Tensor: + """Clear all the fields of a `Tensor`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + data=[], + value_range=[], + ) + return inst + + data: components.TensorDataBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.TensorDataBatch._converter, # type: ignore[misc] ) # The tensor data # # (Docstring intentionally commented out to hide this field from the docs) value_range: components.ValueRangeBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ValueRangeBatch._optional, # type: ignore[misc] + converter=components.ValueRangeBatch._converter, # type: ignore[misc] ) # The expected range of values. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/text_document.py b/rerun_py/rerun_sdk/rerun/archetypes/text_document.py index 0b0a3b39581f..1c7b001c386b 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/text_document.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/text_document.py @@ -117,8 +117,8 @@ def __init__(self: Any, text: datatypes.Utf8Like, *, media_type: datatypes.Utf8L def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - text=None, # type: ignore[arg-type] - media_type=None, # type: ignore[arg-type] + text=None, + media_type=None, ) @classmethod @@ -128,18 +128,73 @@ def _clear(cls) -> TextDocument: inst.__attrs_clear__() return inst - text: components.TextBatch = field( - metadata={"component": "required"}, - converter=components.TextBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + text: datatypes.Utf8Like | None = None, + media_type: datatypes.Utf8Like | None = None, + ) -> TextDocument: + """ + Update only some specific fields of a `TextDocument`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + text: + Contents of the text document. + media_type: + The Media Type of the text. + + For instance: + * `text/plain` + * `text/markdown` + + If omitted, `text/plain` is assumed. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "text": text, + "media_type": media_type, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> TextDocument: + """Clear all the fields of a `TextDocument`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + text=[], + media_type=[], + ) + return inst + + text: components.TextBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.TextBatch._converter, # type: ignore[misc] ) # Contents of the text document. # # (Docstring intentionally commented out to hide this field from the docs) media_type: components.MediaTypeBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.MediaTypeBatch._optional, # type: ignore[misc] + converter=components.MediaTypeBatch._converter, # type: ignore[misc] ) # The Media Type of the text. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/text_log.py b/rerun_py/rerun_sdk/rerun/archetypes/text_log.py index 020c070ea9d6..99dc521f3d52 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/text_log.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/text_log.py @@ -85,9 +85,9 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - text=None, # type: ignore[arg-type] - level=None, # type: ignore[arg-type] - color=None, # type: ignore[arg-type] + text=None, + level=None, + color=None, ) @classmethod @@ -97,18 +97,74 @@ def _clear(cls) -> TextLog: inst.__attrs_clear__() return inst - text: components.TextBatch = field( - metadata={"component": "required"}, - converter=components.TextBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + text: datatypes.Utf8Like | None = None, + level: datatypes.Utf8Like | None = None, + color: datatypes.Rgba32Like | None = None, + ) -> TextLog: + """ + Update only some specific fields of a `TextLog`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + text: + The body of the message. + level: + The verbosity level of the message. + + This can be used to filter the log messages in the Rerun Viewer. + color: + Optional color to use for the log line in the Rerun Viewer. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "text": text, + "level": level, + "color": color, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> TextLog: + """Clear all the fields of a `TextLog`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + text=[], + level=[], + color=[], + ) + return inst + + text: components.TextBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.TextBatch._converter, # type: ignore[misc] ) # The body of the message. # # (Docstring intentionally commented out to hide this field from the docs) level: components.TextLogLevelBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TextLogLevelBatch._optional, # type: ignore[misc] + converter=components.TextLogLevelBatch._converter, # type: ignore[misc] ) # The verbosity level of the message. # @@ -117,9 +173,9 @@ def _clear(cls) -> TextLog: # (Docstring intentionally commented out to hide this field from the docs) color: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Optional color to use for the log line in the Rerun Viewer. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/transform3d.py b/rerun_py/rerun_sdk/rerun/archetypes/transform3d.py index b2c8e2daa166..caf4ede5d3b2 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/transform3d.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/transform3d.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .transform3d_ext import Transform3DExt __all__ = ["Transform3D"] @@ -140,13 +141,13 @@ class Transform3D(Transform3DExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - translation=None, # type: ignore[arg-type] - rotation_axis_angle=None, # type: ignore[arg-type] - quaternion=None, # type: ignore[arg-type] - scale=None, # type: ignore[arg-type] - mat3x3=None, # type: ignore[arg-type] - relation=None, # type: ignore[arg-type] - axis_length=None, # type: ignore[arg-type] + translation=None, + rotation_axis_angle=None, + quaternion=None, + scale=None, + mat3x3=None, + relation=None, + axis_length=None, ) @classmethod @@ -156,64 +157,140 @@ def _clear(cls) -> Transform3D: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + translation: datatypes.Vec3DLike | None = None, + rotation_axis_angle: datatypes.RotationAxisAngleLike | None = None, + quaternion: datatypes.QuaternionLike | None = None, + scale: datatypes.Vec3DLike | None = None, + mat3x3: datatypes.Mat3x3Like | None = None, + relation: components.TransformRelationLike | None = None, + axis_length: datatypes.Float32Like | None = None, + ) -> Transform3D: + """ + Update only some specific fields of a `Transform3D`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + translation: + Translation vector. + rotation_axis_angle: + Rotation via axis + angle. + quaternion: + Rotation via quaternion. + scale: + Scaling factor. + mat3x3: + 3x3 transformation matrix. + relation: + Specifies the relation this transform establishes between this entity and its parent. + axis_length: + Visual length of the 3 axes. + + The length is interpreted in the local coordinate system of the transform. + If the transform is scaled, the axes will be scaled accordingly. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "translation": translation, + "rotation_axis_angle": rotation_axis_angle, + "quaternion": quaternion, + "scale": scale, + "mat3x3": mat3x3, + "relation": relation, + "axis_length": axis_length, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Transform3D: + """Clear all the fields of a `Transform3D`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + translation=[], + rotation_axis_angle=[], + quaternion=[], + scale=[], + mat3x3=[], + relation=[], + axis_length=[], + ) + return inst + translation: components.Translation3DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.Translation3DBatch._required, # type: ignore[misc] + converter=components.Translation3DBatch._converter, # type: ignore[misc] ) # Translation vector. # # (Docstring intentionally commented out to hide this field from the docs) rotation_axis_angle: components.RotationAxisAngleBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.RotationAxisAngleBatch._required, # type: ignore[misc] + converter=components.RotationAxisAngleBatch._converter, # type: ignore[misc] ) # Rotation via axis + angle. # # (Docstring intentionally commented out to hide this field from the docs) quaternion: components.RotationQuatBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.RotationQuatBatch._required, # type: ignore[misc] + converter=components.RotationQuatBatch._converter, # type: ignore[misc] ) # Rotation via quaternion. # # (Docstring intentionally commented out to hide this field from the docs) scale: components.Scale3DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.Scale3DBatch._required, # type: ignore[misc] + converter=components.Scale3DBatch._converter, # type: ignore[misc] ) # Scaling factor. # # (Docstring intentionally commented out to hide this field from the docs) mat3x3: components.TransformMat3x3Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TransformMat3x3Batch._required, # type: ignore[misc] + converter=components.TransformMat3x3Batch._converter, # type: ignore[misc] ) # 3x3 transformation matrix. # # (Docstring intentionally commented out to hide this field from the docs) relation: components.TransformRelationBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TransformRelationBatch._required, # type: ignore[misc] + converter=components.TransformRelationBatch._converter, # type: ignore[misc] ) # Specifies the relation this transform establishes between this entity and its parent. # # (Docstring intentionally commented out to hide this field from the docs) axis_length: components.AxisLengthBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AxisLengthBatch._required, # type: ignore[misc] + converter=components.AxisLengthBatch._converter, # type: ignore[misc] ) # Visual length of the 3 axes. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/transform3d_ext.py b/rerun_py/rerun_sdk/rerun/archetypes/transform3d_ext.py index 7e59ca375224..feddf6276ae2 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/transform3d_ext.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/transform3d_ext.py @@ -22,6 +22,7 @@ class Transform3DExt: def __init__( self: Any, *, + clear: bool = True, translation: Vec3DLike | None = None, rotation: QuaternionLike | RotationAxisAngleLike | None = None, rotation_axis_angle: RotationAxisAngleLike | None = None, @@ -37,6 +38,8 @@ def __init__( Parameters ---------- + clear: + If true (the default), all unspecified fields will be explicitly cleared. translation: 3D translation vector. rotation: @@ -124,14 +127,25 @@ def __init__( if from_parent: relation = TransformRelation.ChildFromParent - self.__attrs_init__( - translation=translation, - rotation_axis_angle=rotation_axis_angle, - quaternion=quaternion, - scale=scale, - mat3x3=mat3x3, - relation=relation, - axis_length=axis_length, - ) + if clear: + self.__attrs_init__( + translation=translation if translation is not None else [], + rotation_axis_angle=rotation_axis_angle if rotation_axis_angle is not None else [], + quaternion=quaternion if quaternion is not None else [], + scale=scale if scale is not None else [], + mat3x3=mat3x3 if mat3x3 is not None else [], + relation=relation if relation is not None else [], + axis_length=axis_length if axis_length is not None else [], + ) + else: + self.__attrs_init__( + translation=translation, + rotation_axis_angle=rotation_axis_angle, + quaternion=quaternion, + scale=scale, + mat3x3=mat3x3, + relation=relation, + axis_length=axis_length, + ) return self.__attrs_clear__() diff --git a/rerun_py/rerun_sdk/rerun/archetypes/video_frame_reference.py b/rerun_py/rerun_sdk/rerun/archetypes/video_frame_reference.py index dfb627b0ba33..6ecc7ddac2ff 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/video_frame_reference.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/video_frame_reference.py @@ -7,10 +7,11 @@ from attrs import define, field -from .. import components +from .. import components, datatypes from .._baseclasses import ( Archetype, ) +from ..error_utils import catch_and_log_exceptions from .video_frame_reference_ext import VideoFrameReferenceExt __all__ = ["VideoFrameReference"] @@ -115,8 +116,8 @@ class VideoFrameReference(VideoFrameReferenceExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - timestamp=None, # type: ignore[arg-type] - video_reference=None, # type: ignore[arg-type] + timestamp=None, + video_reference=None, ) @classmethod @@ -126,9 +127,73 @@ def _clear(cls) -> VideoFrameReference: inst.__attrs_clear__() return inst - timestamp: components.VideoTimestampBatch = field( - metadata={"component": "required"}, - converter=components.VideoTimestampBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + timestamp: datatypes.VideoTimestampLike | None = None, + video_reference: datatypes.EntityPathLike | None = None, + ) -> VideoFrameReference: + """ + Update only some specific fields of a `VideoFrameReference`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + timestamp: + References the closest video frame to this timestamp. + + Note that this uses the closest video frame instead of the latest at this timestamp + in order to be more forgiving of rounding errors for inprecise timestamp types. + + Timestamps are relative to the start of the video, i.e. a timestamp of 0 always corresponds to the first frame. + This is oftentimes equivalent to presentation timestamps (known as PTS), but in the presence of B-frames + (bidirectionally predicted frames) there may be an offset on the first presentation timestamp in the video. + video_reference: + Optional reference to an entity with a [`archetypes.AssetVideo`][rerun.archetypes.AssetVideo]. + + If none is specified, the video is assumed to be at the same entity. + Note that blueprint overrides on the referenced video will be ignored regardless, + as this is always interpreted as a reference to the data store. + + For a series of video frame references, it is recommended to specify this path only once + at the beginning of the series and then rely on latest-at query semantics to + keep the video reference active. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "timestamp": timestamp, + "video_reference": video_reference, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> VideoFrameReference: + """Clear all the fields of a `VideoFrameReference`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + timestamp=[], + video_reference=[], + ) + return inst + + timestamp: components.VideoTimestampBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.VideoTimestampBatch._converter, # type: ignore[misc] ) # References the closest video frame to this timestamp. # @@ -142,9 +207,9 @@ def _clear(cls) -> VideoFrameReference: # (Docstring intentionally commented out to hide this field from the docs) video_reference: components.EntityPathBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.EntityPathBatch._optional, # type: ignore[misc] + converter=components.EntityPathBatch._converter, # type: ignore[misc] ) # Optional reference to an entity with a [`archetypes.AssetVideo`][rerun.archetypes.AssetVideo]. # diff --git a/rerun_py/rerun_sdk/rerun/archetypes/view_coordinates.py b/rerun_py/rerun_sdk/rerun/archetypes/view_coordinates.py index ada329cf25a9..413bc403160d 100644 --- a/rerun_py/rerun_sdk/rerun/archetypes/view_coordinates.py +++ b/rerun_py/rerun_sdk/rerun/archetypes/view_coordinates.py @@ -84,7 +84,7 @@ def __init__(self: Any, xyz: datatypes.ViewCoordinatesLike): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - xyz=None, # type: ignore[arg-type] + xyz=None, ) @classmethod @@ -94,9 +94,53 @@ def _clear(cls) -> ViewCoordinates: inst.__attrs_clear__() return inst - xyz: components.ViewCoordinatesBatch = field( - metadata={"component": "required"}, - converter=components.ViewCoordinatesBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + xyz: datatypes.ViewCoordinatesLike | None = None, + ) -> ViewCoordinates: + """ + Update only some specific fields of a `ViewCoordinates`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + xyz: + The directions of the [x, y, z] axes. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "xyz": xyz, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> ViewCoordinates: + """Clear all the fields of a `ViewCoordinates`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + xyz=[], + ) + return inst + + xyz: components.ViewCoordinatesBatch | None = field( + metadata={"component": True}, + default=None, + converter=components.ViewCoordinatesBatch._converter, # type: ignore[misc] ) # The directions of the [x, y, z] axes. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/background.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/background.py index cbe9178d7911..f2595b02b7e1 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/background.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/background.py @@ -7,11 +7,12 @@ from attrs import define, field -from ... import components +from ... import components, datatypes from ..._baseclasses import ( Archetype, ) from ...blueprint import components as blueprint_components +from ...error_utils import catch_and_log_exceptions from .background_ext import BackgroundExt __all__ = ["Background"] @@ -26,8 +27,8 @@ class Background(BackgroundExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - kind=None, # type: ignore[arg-type] - color=None, # type: ignore[arg-type] + kind=None, + color=None, ) @classmethod @@ -37,18 +38,67 @@ def _clear(cls) -> Background: inst.__attrs_clear__() return inst - kind: blueprint_components.BackgroundKindBatch = field( - metadata={"component": "required"}, - converter=blueprint_components.BackgroundKindBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + kind: blueprint_components.BackgroundKindLike | None = None, + color: datatypes.Rgba32Like | None = None, + ) -> Background: + """ + Update only some specific fields of a `Background`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + kind: + The type of the background. + color: + Color used for the solid background type. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "kind": kind, + "color": color, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> Background: + """Clear all the fields of a `Background`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + kind=[], + color=[], + ) + return inst + + kind: blueprint_components.BackgroundKindBatch | None = field( + metadata={"component": True}, + default=None, + converter=blueprint_components.BackgroundKindBatch._converter, # type: ignore[misc] ) # The type of the background. # # (Docstring intentionally commented out to hide this field from the docs) color: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Color used for the solid background type. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/container_blueprint.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/container_blueprint.py index 9f225bd61254..e5970123ebae 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/container_blueprint.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/container_blueprint.py @@ -93,14 +93,14 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - container_kind=None, # type: ignore[arg-type] - display_name=None, # type: ignore[arg-type] - contents=None, # type: ignore[arg-type] - col_shares=None, # type: ignore[arg-type] - row_shares=None, # type: ignore[arg-type] - active_tab=None, # type: ignore[arg-type] - visible=None, # type: ignore[arg-type] - grid_columns=None, # type: ignore[arg-type] + container_kind=None, + display_name=None, + contents=None, + col_shares=None, + row_shares=None, + active_tab=None, + visible=None, + grid_columns=None, ) @classmethod @@ -110,36 +110,131 @@ def _clear(cls) -> ContainerBlueprint: inst.__attrs_clear__() return inst - container_kind: blueprint_components.ContainerKindBatch = field( - metadata={"component": "required"}, - converter=blueprint_components.ContainerKindBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + container_kind: blueprint_components.ContainerKindLike | None = None, + display_name: datatypes.Utf8Like | None = None, + contents: datatypes.EntityPathArrayLike | None = None, + col_shares: datatypes.Float32ArrayLike | None = None, + row_shares: datatypes.Float32ArrayLike | None = None, + active_tab: datatypes.EntityPathLike | None = None, + visible: datatypes.BoolLike | None = None, + grid_columns: datatypes.UInt32Like | None = None, + ) -> ContainerBlueprint: + """ + Update only some specific fields of a `ContainerBlueprint`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + container_kind: + The class of the view. + display_name: + The name of the container. + contents: + `ContainerId`s or `ViewId`s that are children of this container. + col_shares: + The layout shares of each column in the container. + + For [`components.ContainerKind.Horizontal`][rerun.blueprint.components.ContainerKind.Horizontal] containers, the length of this list should always match the number of contents. + + Ignored for [`components.ContainerKind.Vertical`][rerun.blueprint.components.ContainerKind.Vertical] containers. + row_shares: + The layout shares of each row of the container. + + For [`components.ContainerKind.Vertical`][rerun.blueprint.components.ContainerKind.Vertical] containers, the length of this list should always match the number of contents. + + Ignored for [`components.ContainerKind.Horizontal`][rerun.blueprint.components.ContainerKind.Horizontal] containers. + active_tab: + Which tab is active. + + Only applies to `Tabs` containers. + visible: + Whether this container is visible. + + Defaults to true if not specified. + grid_columns: + How many columns this grid should have. + + If unset, the grid layout will be auto. + + Ignored for [`components.ContainerKind.Horizontal`][rerun.blueprint.components.ContainerKind.Horizontal]/[`components.ContainerKind.Vertical`][rerun.blueprint.components.ContainerKind.Vertical] containers. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "container_kind": container_kind, + "display_name": display_name, + "contents": contents, + "col_shares": col_shares, + "row_shares": row_shares, + "active_tab": active_tab, + "visible": visible, + "grid_columns": grid_columns, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> ContainerBlueprint: + """Clear all the fields of a `ContainerBlueprint`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + container_kind=[], + display_name=[], + contents=[], + col_shares=[], + row_shares=[], + active_tab=[], + visible=[], + grid_columns=[], + ) + return inst + + container_kind: blueprint_components.ContainerKindBatch | None = field( + metadata={"component": True}, + default=None, + converter=blueprint_components.ContainerKindBatch._converter, # type: ignore[misc] ) # The class of the view. # # (Docstring intentionally commented out to hide this field from the docs) display_name: components.NameBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.NameBatch._optional, # type: ignore[misc] + converter=components.NameBatch._converter, # type: ignore[misc] ) # The name of the container. # # (Docstring intentionally commented out to hide this field from the docs) contents: blueprint_components.IncludedContentBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.IncludedContentBatch._optional, # type: ignore[misc] + converter=blueprint_components.IncludedContentBatch._converter, # type: ignore[misc] ) # `ContainerId`s or `ViewId`s that are children of this container. # # (Docstring intentionally commented out to hide this field from the docs) col_shares: blueprint_components.ColumnShareBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.ColumnShareBatch._optional, # type: ignore[misc] + converter=blueprint_components.ColumnShareBatch._converter, # type: ignore[misc] ) # The layout shares of each column in the container. # @@ -150,9 +245,9 @@ def _clear(cls) -> ContainerBlueprint: # (Docstring intentionally commented out to hide this field from the docs) row_shares: blueprint_components.RowShareBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.RowShareBatch._optional, # type: ignore[misc] + converter=blueprint_components.RowShareBatch._converter, # type: ignore[misc] ) # The layout shares of each row of the container. # @@ -163,9 +258,9 @@ def _clear(cls) -> ContainerBlueprint: # (Docstring intentionally commented out to hide this field from the docs) active_tab: blueprint_components.ActiveTabBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.ActiveTabBatch._optional, # type: ignore[misc] + converter=blueprint_components.ActiveTabBatch._converter, # type: ignore[misc] ) # Which tab is active. # @@ -174,9 +269,9 @@ def _clear(cls) -> ContainerBlueprint: # (Docstring intentionally commented out to hide this field from the docs) visible: blueprint_components.VisibleBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.VisibleBatch._optional, # type: ignore[misc] + converter=blueprint_components.VisibleBatch._converter, # type: ignore[misc] ) # Whether this container is visible. # @@ -185,9 +280,9 @@ def _clear(cls) -> ContainerBlueprint: # (Docstring intentionally commented out to hide this field from the docs) grid_columns: blueprint_components.GridColumnsBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.GridColumnsBatch._optional, # type: ignore[misc] + converter=blueprint_components.GridColumnsBatch._converter, # type: ignore[misc] ) # How many columns this grid should have. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/dataframe_query.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/dataframe_query.py index 3bc64d3dda93..5e41b02d27af 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/dataframe_query.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/dataframe_query.py @@ -7,10 +7,12 @@ from attrs import define, field +from ... import datatypes from ..._baseclasses import ( Archetype, ) -from ...blueprint import components as blueprint_components +from ...blueprint import components as blueprint_components, datatypes as blueprint_datatypes +from ...error_utils import catch_and_log_exceptions from .dataframe_query_ext import DataframeQueryExt __all__ = ["DataframeQuery"] @@ -25,11 +27,11 @@ class DataframeQuery(DataframeQueryExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - timeline=None, # type: ignore[arg-type] - filter_by_range=None, # type: ignore[arg-type] - filter_is_not_null=None, # type: ignore[arg-type] - apply_latest_at=None, # type: ignore[arg-type] - select=None, # type: ignore[arg-type] + timeline=None, + filter_by_range=None, + filter_is_not_null=None, + apply_latest_at=None, + select=None, ) @classmethod @@ -39,10 +41,77 @@ def _clear(cls) -> DataframeQuery: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + timeline: datatypes.Utf8Like | None = None, + filter_by_range: blueprint_datatypes.FilterByRangeLike | None = None, + filter_is_not_null: blueprint_datatypes.FilterIsNotNullLike | None = None, + apply_latest_at: datatypes.BoolLike | None = None, + select: blueprint_datatypes.SelectedColumnsLike | None = None, + ) -> DataframeQuery: + """ + Update only some specific fields of a `DataframeQuery`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + timeline: + The timeline for this query. + + If unset, the timeline currently active on the time panel is used. + filter_by_range: + If provided, only rows whose timestamp is within this range will be shown. + + Note: will be unset as soon as `timeline` is changed. + filter_is_not_null: + If provided, only show rows which contains a logged event for the specified component. + apply_latest_at: + Should empty cells be filled with latest-at queries? + select: + Selected columns. If unset, all columns are selected. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "timeline": timeline, + "filter_by_range": filter_by_range, + "filter_is_not_null": filter_is_not_null, + "apply_latest_at": apply_latest_at, + "select": select, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> DataframeQuery: + """Clear all the fields of a `DataframeQuery`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + timeline=[], + filter_by_range=[], + filter_is_not_null=[], + apply_latest_at=[], + select=[], + ) + return inst + timeline: blueprint_components.TimelineNameBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.TimelineNameBatch._optional, # type: ignore[misc] + converter=blueprint_components.TimelineNameBatch._converter, # type: ignore[misc] ) # The timeline for this query. # @@ -51,9 +120,9 @@ def _clear(cls) -> DataframeQuery: # (Docstring intentionally commented out to hide this field from the docs) filter_by_range: blueprint_components.FilterByRangeBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.FilterByRangeBatch._optional, # type: ignore[misc] + converter=blueprint_components.FilterByRangeBatch._converter, # type: ignore[misc] ) # If provided, only rows whose timestamp is within this range will be shown. # @@ -62,27 +131,27 @@ def _clear(cls) -> DataframeQuery: # (Docstring intentionally commented out to hide this field from the docs) filter_is_not_null: blueprint_components.FilterIsNotNullBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.FilterIsNotNullBatch._optional, # type: ignore[misc] + converter=blueprint_components.FilterIsNotNullBatch._converter, # type: ignore[misc] ) # If provided, only show rows which contains a logged event for the specified component. # # (Docstring intentionally commented out to hide this field from the docs) apply_latest_at: blueprint_components.ApplyLatestAtBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.ApplyLatestAtBatch._optional, # type: ignore[misc] + converter=blueprint_components.ApplyLatestAtBatch._converter, # type: ignore[misc] ) # Should empty cells be filled with latest-at queries? # # (Docstring intentionally commented out to hide this field from the docs) select: blueprint_components.SelectedColumnsBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.SelectedColumnsBatch._optional, # type: ignore[misc] + converter=blueprint_components.SelectedColumnsBatch._converter, # type: ignore[misc] ) # Selected columns. If unset, all columns are selected. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_center.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_center.py index 5804b3c0db7f..f708724dbaa1 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_center.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_center.py @@ -49,8 +49,8 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - enabled=None, # type: ignore[arg-type] - strength=None, # type: ignore[arg-type] + enabled=None, + strength=None, ) @classmethod @@ -60,10 +60,60 @@ def _clear(cls) -> ForceCenter: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + enabled: datatypes.BoolLike | None = None, + strength: datatypes.Float64Like | None = None, + ) -> ForceCenter: + """ + Update only some specific fields of a `ForceCenter`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + enabled: + Whether the center force is enabled. + + The center force tries to move the center of mass of the graph towards the origin. + strength: + The strength of the force. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "enabled": enabled, + "strength": strength, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> ForceCenter: + """Clear all the fields of a `ForceCenter`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + enabled=[], + strength=[], + ) + return inst + enabled: blueprint_components.EnabledBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.EnabledBatch._optional, # type: ignore[misc] + converter=blueprint_components.EnabledBatch._converter, # type: ignore[misc] ) # Whether the center force is enabled. # @@ -72,9 +122,9 @@ def _clear(cls) -> ForceCenter: # (Docstring intentionally commented out to hide this field from the docs) strength: blueprint_components.ForceStrengthBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.ForceStrengthBatch._optional, # type: ignore[misc] + converter=blueprint_components.ForceStrengthBatch._converter, # type: ignore[misc] ) # The strength of the force. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_collision_radius.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_collision_radius.py index 169c8f5e7ba0..5c2e3f83d7e2 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_collision_radius.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_collision_radius.py @@ -57,9 +57,9 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - enabled=None, # type: ignore[arg-type] - strength=None, # type: ignore[arg-type] - iterations=None, # type: ignore[arg-type] + enabled=None, + strength=None, + iterations=None, ) @classmethod @@ -69,10 +69,67 @@ def _clear(cls) -> ForceCollisionRadius: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + enabled: datatypes.BoolLike | None = None, + strength: datatypes.Float64Like | None = None, + iterations: datatypes.UInt64Like | None = None, + ) -> ForceCollisionRadius: + """ + Update only some specific fields of a `ForceCollisionRadius`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + enabled: + Whether the collision force is enabled. + + The collision force resolves collisions between nodes based on the bounding circle defined by their radius. + strength: + The strength of the force. + iterations: + Specifies how often this force should be applied per iteration. + + Increasing this parameter can lead to better results at the cost of longer computation time. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "enabled": enabled, + "strength": strength, + "iterations": iterations, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> ForceCollisionRadius: + """Clear all the fields of a `ForceCollisionRadius`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + enabled=[], + strength=[], + iterations=[], + ) + return inst + enabled: blueprint_components.EnabledBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.EnabledBatch._optional, # type: ignore[misc] + converter=blueprint_components.EnabledBatch._converter, # type: ignore[misc] ) # Whether the collision force is enabled. # @@ -81,18 +138,18 @@ def _clear(cls) -> ForceCollisionRadius: # (Docstring intentionally commented out to hide this field from the docs) strength: blueprint_components.ForceStrengthBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.ForceStrengthBatch._optional, # type: ignore[misc] + converter=blueprint_components.ForceStrengthBatch._converter, # type: ignore[misc] ) # The strength of the force. # # (Docstring intentionally commented out to hide this field from the docs) iterations: blueprint_components.ForceIterationsBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.ForceIterationsBatch._optional, # type: ignore[misc] + converter=blueprint_components.ForceIterationsBatch._converter, # type: ignore[misc] ) # Specifies how often this force should be applied per iteration. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_link.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_link.py index f3c179715a0a..f93e9c6fcf46 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_link.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_link.py @@ -57,9 +57,9 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - enabled=None, # type: ignore[arg-type] - distance=None, # type: ignore[arg-type] - iterations=None, # type: ignore[arg-type] + enabled=None, + distance=None, + iterations=None, ) @classmethod @@ -69,10 +69,67 @@ def _clear(cls) -> ForceLink: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + enabled: datatypes.BoolLike | None = None, + distance: datatypes.Float64Like | None = None, + iterations: datatypes.UInt64Like | None = None, + ) -> ForceLink: + """ + Update only some specific fields of a `ForceLink`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + enabled: + Whether the link force is enabled. + + The link force aims to achieve a target distance between two nodes that are connected by one ore more edges. + distance: + The target distance between two nodes. + iterations: + Specifies how often this force should be applied per iteration. + + Increasing this parameter can lead to better results at the cost of longer computation time. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "enabled": enabled, + "distance": distance, + "iterations": iterations, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> ForceLink: + """Clear all the fields of a `ForceLink`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + enabled=[], + distance=[], + iterations=[], + ) + return inst + enabled: blueprint_components.EnabledBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.EnabledBatch._optional, # type: ignore[misc] + converter=blueprint_components.EnabledBatch._converter, # type: ignore[misc] ) # Whether the link force is enabled. # @@ -81,18 +138,18 @@ def _clear(cls) -> ForceLink: # (Docstring intentionally commented out to hide this field from the docs) distance: blueprint_components.ForceDistanceBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.ForceDistanceBatch._optional, # type: ignore[misc] + converter=blueprint_components.ForceDistanceBatch._converter, # type: ignore[misc] ) # The target distance between two nodes. # # (Docstring intentionally commented out to hide this field from the docs) iterations: blueprint_components.ForceIterationsBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.ForceIterationsBatch._optional, # type: ignore[misc] + converter=blueprint_components.ForceIterationsBatch._converter, # type: ignore[misc] ) # Specifies how often this force should be applied per iteration. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_many_body.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_many_body.py index 1881af385409..34592296ee55 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_many_body.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_many_body.py @@ -56,8 +56,8 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - enabled=None, # type: ignore[arg-type] - strength=None, # type: ignore[arg-type] + enabled=None, + strength=None, ) @classmethod @@ -67,10 +67,63 @@ def _clear(cls) -> ForceManyBody: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + enabled: datatypes.BoolLike | None = None, + strength: datatypes.Float64Like | None = None, + ) -> ForceManyBody: + """ + Update only some specific fields of a `ForceManyBody`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + enabled: + Whether the many body force is enabled. + + The many body force is applied on each pair of nodes in a way that ressembles an electrical charge. If the + strength is smaller than 0, it pushes nodes apart; if it is larger than 0, it pulls them together. + strength: + The strength of the force. + + If `strength` is smaller than 0, it pushes nodes apart, if it is larger than 0 it pulls them together. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "enabled": enabled, + "strength": strength, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> ForceManyBody: + """Clear all the fields of a `ForceManyBody`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + enabled=[], + strength=[], + ) + return inst + enabled: blueprint_components.EnabledBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.EnabledBatch._optional, # type: ignore[misc] + converter=blueprint_components.EnabledBatch._converter, # type: ignore[misc] ) # Whether the many body force is enabled. # @@ -80,9 +133,9 @@ def _clear(cls) -> ForceManyBody: # (Docstring intentionally commented out to hide this field from the docs) strength: blueprint_components.ForceStrengthBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.ForceStrengthBatch._optional, # type: ignore[misc] + converter=blueprint_components.ForceStrengthBatch._converter, # type: ignore[misc] ) # The strength of the force. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_position.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_position.py index aa83eb92516d..e717533ffafe 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_position.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/force_position.py @@ -55,9 +55,9 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - enabled=None, # type: ignore[arg-type] - strength=None, # type: ignore[arg-type] - position=None, # type: ignore[arg-type] + enabled=None, + strength=None, + position=None, ) @classmethod @@ -67,10 +67,65 @@ def _clear(cls) -> ForcePosition: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + enabled: datatypes.BoolLike | None = None, + strength: datatypes.Float64Like | None = None, + position: datatypes.Vec2DLike | None = None, + ) -> ForcePosition: + """ + Update only some specific fields of a `ForcePosition`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + enabled: + Whether the position force is enabled. + + The position force pulls nodes towards a specific position, similar to gravity. + strength: + The strength of the force. + position: + The position where the nodes should be pulled towards. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "enabled": enabled, + "strength": strength, + "position": position, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> ForcePosition: + """Clear all the fields of a `ForcePosition`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + enabled=[], + strength=[], + position=[], + ) + return inst + enabled: blueprint_components.EnabledBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.EnabledBatch._optional, # type: ignore[misc] + converter=blueprint_components.EnabledBatch._converter, # type: ignore[misc] ) # Whether the position force is enabled. # @@ -79,18 +134,18 @@ def _clear(cls) -> ForcePosition: # (Docstring intentionally commented out to hide this field from the docs) strength: blueprint_components.ForceStrengthBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.ForceStrengthBatch._optional, # type: ignore[misc] + converter=blueprint_components.ForceStrengthBatch._converter, # type: ignore[misc] ) # The strength of the force. # # (Docstring intentionally commented out to hide this field from the docs) position: components.Position2DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.Position2DBatch._optional, # type: ignore[misc] + converter=components.Position2DBatch._converter, # type: ignore[misc] ) # The position where the nodes should be pulled towards. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py index a34c8f217b9c..185931a38ed3 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/line_grid3d.py @@ -71,11 +71,11 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - visible=None, # type: ignore[arg-type] - spacing=None, # type: ignore[arg-type] - plane=None, # type: ignore[arg-type] - stroke_width=None, # type: ignore[arg-type] - color=None, # type: ignore[arg-type] + visible=None, + spacing=None, + plane=None, + stroke_width=None, + color=None, ) @classmethod @@ -85,10 +85,85 @@ def _clear(cls) -> LineGrid3D: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + visible: datatypes.BoolLike | None = None, + spacing: datatypes.Float32Like | None = None, + plane: datatypes.Plane3DLike | None = None, + stroke_width: datatypes.Float32Like | None = None, + color: datatypes.Rgba32Like | None = None, + ) -> LineGrid3D: + """ + Update only some specific fields of a `LineGrid3D`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + visible: + Whether the grid is visible. + + Defaults to true. + spacing: + Space between grid lines spacing of one line to the next in scene units. + + As you zoom out, successively only every tenth line is shown. + This controls the closest zoom level. + plane: + In what plane the grid is drawn. + + Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`components.ViewCoordinates`][rerun.components.ViewCoordinates] if present. + stroke_width: + How thick the lines should be in ui units. + + Default is 1.0 ui unit. + color: + Color used for the grid. + + Transparency via alpha channel is supported. + Defaults to a slightly transparent light gray. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "visible": visible, + "spacing": spacing, + "plane": plane, + "stroke_width": stroke_width, + "color": color, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> LineGrid3D: + """Clear all the fields of a `LineGrid3D`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + visible=[], + spacing=[], + plane=[], + stroke_width=[], + color=[], + ) + return inst + visible: blueprint_components.VisibleBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.VisibleBatch._optional, # type: ignore[misc] + converter=blueprint_components.VisibleBatch._converter, # type: ignore[misc] ) # Whether the grid is visible. # @@ -97,9 +172,9 @@ def _clear(cls) -> LineGrid3D: # (Docstring intentionally commented out to hide this field from the docs) spacing: blueprint_components.GridSpacingBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.GridSpacingBatch._optional, # type: ignore[misc] + converter=blueprint_components.GridSpacingBatch._converter, # type: ignore[misc] ) # Space between grid lines spacing of one line to the next in scene units. # @@ -109,9 +184,9 @@ def _clear(cls) -> LineGrid3D: # (Docstring intentionally commented out to hide this field from the docs) plane: components.Plane3DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.Plane3DBatch._optional, # type: ignore[misc] + converter=components.Plane3DBatch._converter, # type: ignore[misc] ) # In what plane the grid is drawn. # @@ -120,9 +195,9 @@ def _clear(cls) -> LineGrid3D: # (Docstring intentionally commented out to hide this field from the docs) stroke_width: components.StrokeWidthBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.StrokeWidthBatch._optional, # type: ignore[misc] + converter=components.StrokeWidthBatch._converter, # type: ignore[misc] ) # How thick the lines should be in ui units. # @@ -131,9 +206,9 @@ def _clear(cls) -> LineGrid3D: # (Docstring intentionally commented out to hide this field from the docs) color: components.ColorBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColorBatch._optional, # type: ignore[misc] + converter=components.ColorBatch._converter, # type: ignore[misc] ) # Color used for the grid. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/map_background.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/map_background.py index bd32323fc481..a769a61eccce 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/map_background.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/map_background.py @@ -44,7 +44,7 @@ def __init__(self: Any, provider: blueprint_components.MapProviderLike): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - provider=None, # type: ignore[arg-type] + provider=None, ) @classmethod @@ -54,9 +54,55 @@ def _clear(cls) -> MapBackground: inst.__attrs_clear__() return inst - provider: blueprint_components.MapProviderBatch = field( - metadata={"component": "required"}, - converter=blueprint_components.MapProviderBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + provider: blueprint_components.MapProviderLike | None = None, + ) -> MapBackground: + """ + Update only some specific fields of a `MapBackground`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + provider: + Map provider and style to use. + + **Note**: Requires a Mapbox API key in the `RERUN_MAPBOX_ACCESS_TOKEN` environment variable. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "provider": provider, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> MapBackground: + """Clear all the fields of a `MapBackground`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + provider=[], + ) + return inst + + provider: blueprint_components.MapProviderBatch | None = field( + metadata={"component": True}, + default=None, + converter=blueprint_components.MapProviderBatch._converter, # type: ignore[misc] ) # Map provider and style to use. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/map_zoom.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/map_zoom.py index 95bb17027799..c299108f602f 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/map_zoom.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/map_zoom.py @@ -45,7 +45,7 @@ def __init__(self: Any, zoom: datatypes.Float64Like): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - zoom=None, # type: ignore[arg-type] + zoom=None, ) @classmethod @@ -55,9 +55,55 @@ def _clear(cls) -> MapZoom: inst.__attrs_clear__() return inst - zoom: blueprint_components.ZoomLevelBatch = field( - metadata={"component": "required"}, - converter=blueprint_components.ZoomLevelBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + zoom: datatypes.Float64Like | None = None, + ) -> MapZoom: + """ + Update only some specific fields of a `MapZoom`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + zoom: + Zoom level for the map. + + Zoom level follow the [`OpenStreetMap` definition](https://wiki.openstreetmap.org/wiki/Zoom_levels). + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "zoom": zoom, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> MapZoom: + """Clear all the fields of a `MapZoom`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + zoom=[], + ) + return inst + + zoom: blueprint_components.ZoomLevelBatch | None = field( + metadata={"component": True}, + default=None, + converter=blueprint_components.ZoomLevelBatch._converter, # type: ignore[misc] ) # Zoom level for the map. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/near_clip_plane.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/near_clip_plane.py index dee3bdaccadb..dd4bf470bc5e 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/near_clip_plane.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/near_clip_plane.py @@ -45,7 +45,7 @@ def __init__(self: Any, near_clip_plane: datatypes.Float32Like): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - near_clip_plane=None, # type: ignore[arg-type] + near_clip_plane=None, ) @classmethod @@ -55,9 +55,55 @@ def _clear(cls) -> NearClipPlane: inst.__attrs_clear__() return inst - near_clip_plane: blueprint_components.NearClipPlaneBatch = field( - metadata={"component": "required"}, - converter=blueprint_components.NearClipPlaneBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + near_clip_plane: datatypes.Float32Like | None = None, + ) -> NearClipPlane: + """ + Update only some specific fields of a `NearClipPlane`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + near_clip_plane: + Controls the distance to the near clip plane in 3D scene units. + + Content closer than this distance will not be visible. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "near_clip_plane": near_clip_plane, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> NearClipPlane: + """Clear all the fields of a `NearClipPlane`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + near_clip_plane=[], + ) + return inst + + near_clip_plane: blueprint_components.NearClipPlaneBatch | None = field( + metadata={"component": True}, + default=None, + converter=blueprint_components.NearClipPlaneBatch._converter, # type: ignore[misc] ) # Controls the distance to the near clip plane in 3D scene units. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/panel_blueprint.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/panel_blueprint.py index e9554a2d2053..12ac91c7680b 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/panel_blueprint.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/panel_blueprint.py @@ -42,7 +42,7 @@ def __init__(self: Any, *, state: blueprint_components.PanelStateLike | None = N def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - state=None, # type: ignore[arg-type] + state=None, ) @classmethod @@ -52,10 +52,53 @@ def _clear(cls) -> PanelBlueprint: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + state: blueprint_components.PanelStateLike | None = None, + ) -> PanelBlueprint: + """ + Update only some specific fields of a `PanelBlueprint`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + state: + Current state of the panels. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "state": state, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> PanelBlueprint: + """Clear all the fields of a `PanelBlueprint`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + state=[], + ) + return inst + state: blueprint_components.PanelStateBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.PanelStateBatch._optional, # type: ignore[misc] + converter=blueprint_components.PanelStateBatch._converter, # type: ignore[misc] ) # Current state of the panels. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/plot_legend.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/plot_legend.py index 22a64b7aeb1f..c035b1ba751a 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/plot_legend.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/plot_legend.py @@ -7,10 +7,12 @@ from attrs import define, field +from ... import datatypes from ..._baseclasses import ( Archetype, ) from ...blueprint import components as blueprint_components +from ...error_utils import catch_and_log_exceptions from .plot_legend_ext import PlotLegendExt __all__ = ["PlotLegend"] @@ -25,8 +27,8 @@ class PlotLegend(PlotLegendExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - corner=None, # type: ignore[arg-type] - visible=None, # type: ignore[arg-type] + corner=None, + visible=None, ) @classmethod @@ -36,10 +38,62 @@ def _clear(cls) -> PlotLegend: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + corner: blueprint_components.Corner2DLike | None = None, + visible: datatypes.BoolLike | None = None, + ) -> PlotLegend: + """ + Update only some specific fields of a `PlotLegend`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + corner: + To what corner the legend is aligned. + + Defaults to the right bottom corner. + visible: + Whether the legend is shown at all. + + True by default. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "corner": corner, + "visible": visible, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> PlotLegend: + """Clear all the fields of a `PlotLegend`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + corner=[], + visible=[], + ) + return inst + corner: blueprint_components.Corner2DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.Corner2DBatch._optional, # type: ignore[misc] + converter=blueprint_components.Corner2DBatch._converter, # type: ignore[misc] ) # To what corner the legend is aligned. # @@ -48,9 +102,9 @@ def _clear(cls) -> PlotLegend: # (Docstring intentionally commented out to hide this field from the docs) visible: blueprint_components.VisibleBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.VisibleBatch._optional, # type: ignore[misc] + converter=blueprint_components.VisibleBatch._converter, # type: ignore[misc] ) # Whether the legend is shown at all. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/scalar_axis.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/scalar_axis.py index 3228f024591b..72ebe55abf4d 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/scalar_axis.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/scalar_axis.py @@ -47,8 +47,8 @@ def __init__(self: Any, *, range: datatypes.Range1DLike | None = None, zoom_lock def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - range=None, # type: ignore[arg-type] - zoom_lock=None, # type: ignore[arg-type] + range=None, + zoom_lock=None, ) @classmethod @@ -58,10 +58,60 @@ def _clear(cls) -> ScalarAxis: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + range: datatypes.Range1DLike | None = None, + zoom_lock: datatypes.BoolLike | None = None, + ) -> ScalarAxis: + """ + Update only some specific fields of a `ScalarAxis`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + range: + The range of the axis. + + If unset, the range well be automatically determined based on the queried data. + zoom_lock: + If enabled, the Y axis range will remain locked to the specified range when zooming. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "range": range, + "zoom_lock": zoom_lock, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> ScalarAxis: + """Clear all the fields of a `ScalarAxis`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + range=[], + zoom_lock=[], + ) + return inst + range: components.Range1DBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.Range1DBatch._optional, # type: ignore[misc] + converter=components.Range1DBatch._converter, # type: ignore[misc] ) # The range of the axis. # @@ -70,9 +120,9 @@ def _clear(cls) -> ScalarAxis: # (Docstring intentionally commented out to hide this field from the docs) zoom_lock: blueprint_components.LockRangeDuringZoomBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.LockRangeDuringZoomBatch._optional, # type: ignore[misc] + converter=blueprint_components.LockRangeDuringZoomBatch._converter, # type: ignore[misc] ) # If enabled, the Y axis range will remain locked to the specified range when zooming. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/tensor_scalar_mapping.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/tensor_scalar_mapping.py index f0a1157f5462..3ac46c4cd514 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/tensor_scalar_mapping.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/tensor_scalar_mapping.py @@ -60,9 +60,9 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - mag_filter=None, # type: ignore[arg-type] - colormap=None, # type: ignore[arg-type] - gamma=None, # type: ignore[arg-type] + mag_filter=None, + colormap=None, + gamma=None, ) @classmethod @@ -72,10 +72,71 @@ def _clear(cls) -> TensorScalarMapping: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + mag_filter: components.MagnificationFilterLike | None = None, + colormap: components.ColormapLike | None = None, + gamma: datatypes.Float32Like | None = None, + ) -> TensorScalarMapping: + """ + Update only some specific fields of a `TensorScalarMapping`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + mag_filter: + Filter used when zooming in on the tensor. + + Note that the filter is applied to the scalar values *before* they are mapped to color. + colormap: + How scalar values map to colors. + gamma: + Gamma exponent applied to normalized values before mapping to color. + + Raises the normalized values to the power of this value before mapping to color. + Acts like an inverse brightness. Defaults to 1.0. + + The final value for display is set as: + `colormap( ((value - data_display_range.min) / (data_display_range.max - data_display_range.min)) ** gamma )` + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "mag_filter": mag_filter, + "colormap": colormap, + "gamma": gamma, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> TensorScalarMapping: + """Clear all the fields of a `TensorScalarMapping`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + mag_filter=[], + colormap=[], + gamma=[], + ) + return inst + mag_filter: components.MagnificationFilterBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.MagnificationFilterBatch._optional, # type: ignore[misc] + converter=components.MagnificationFilterBatch._converter, # type: ignore[misc] ) # Filter used when zooming in on the tensor. # @@ -84,18 +145,18 @@ def _clear(cls) -> TensorScalarMapping: # (Docstring intentionally commented out to hide this field from the docs) colormap: components.ColormapBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.ColormapBatch._optional, # type: ignore[misc] + converter=components.ColormapBatch._converter, # type: ignore[misc] ) # How scalar values map to colors. # # (Docstring intentionally commented out to hide this field from the docs) gamma: components.GammaCorrectionBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.GammaCorrectionBatch._optional, # type: ignore[misc] + converter=components.GammaCorrectionBatch._converter, # type: ignore[misc] ) # Gamma exponent applied to normalized values before mapping to color. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/tensor_slice_selection.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/tensor_slice_selection.py index 419acbb84323..8f940ff38a27 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/tensor_slice_selection.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/tensor_slice_selection.py @@ -66,10 +66,10 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - width=None, # type: ignore[arg-type] - height=None, # type: ignore[arg-type] - indices=None, # type: ignore[arg-type] - slider=None, # type: ignore[arg-type] + width=None, + height=None, + indices=None, + slider=None, ) @classmethod @@ -79,10 +79,78 @@ def _clear(cls) -> TensorSliceSelection: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + width: datatypes.TensorDimensionSelectionLike | None = None, + height: datatypes.TensorDimensionSelectionLike | None = None, + indices: datatypes.TensorDimensionIndexSelectionArrayLike | None = None, + slider: blueprint_datatypes.TensorDimensionIndexSliderArrayLike | None = None, + ) -> TensorSliceSelection: + """ + Update only some specific fields of a `TensorSliceSelection`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + width: + Which dimension to map to width. + + If not specified, the height will be determined automatically based on the name and index of the dimension. + height: + Which dimension to map to height. + + If not specified, the height will be determined automatically based on the name and index of the dimension. + indices: + Selected indices for all other dimensions. + + If any of the here listed dimensions is equal to `width` or `height`, it will be ignored. + slider: + Any dimension listed here will have a slider for the index. + + Edits to the sliders will directly manipulate dimensions on the `indices` list. + If any of the here listed dimensions is equal to `width` or `height`, it will be ignored. + If not specified, adds slides for any dimension in `indices`. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "width": width, + "height": height, + "indices": indices, + "slider": slider, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> TensorSliceSelection: + """Clear all the fields of a `TensorSliceSelection`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + width=[], + height=[], + indices=[], + slider=[], + ) + return inst + width: components.TensorWidthDimensionBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TensorWidthDimensionBatch._optional, # type: ignore[misc] + converter=components.TensorWidthDimensionBatch._converter, # type: ignore[misc] ) # Which dimension to map to width. # @@ -91,9 +159,9 @@ def _clear(cls) -> TensorSliceSelection: # (Docstring intentionally commented out to hide this field from the docs) height: components.TensorHeightDimensionBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TensorHeightDimensionBatch._optional, # type: ignore[misc] + converter=components.TensorHeightDimensionBatch._converter, # type: ignore[misc] ) # Which dimension to map to height. # @@ -102,9 +170,9 @@ def _clear(cls) -> TensorSliceSelection: # (Docstring intentionally commented out to hide this field from the docs) indices: components.TensorDimensionIndexSelectionBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.TensorDimensionIndexSelectionBatch._optional, # type: ignore[misc] + converter=components.TensorDimensionIndexSelectionBatch._converter, # type: ignore[misc] ) # Selected indices for all other dimensions. # @@ -113,9 +181,9 @@ def _clear(cls) -> TensorSliceSelection: # (Docstring intentionally commented out to hide this field from the docs) slider: blueprint_components.TensorDimensionIndexSliderBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.TensorDimensionIndexSliderBatch._optional, # type: ignore[misc] + converter=blueprint_components.TensorDimensionIndexSliderBatch._converter, # type: ignore[misc] ) # Any dimension listed here will have a slider for the index. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/tensor_view_fit.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/tensor_view_fit.py index 7aa1c63ae1fa..17497eca5fd7 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/tensor_view_fit.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/tensor_view_fit.py @@ -11,6 +11,7 @@ Archetype, ) from ...blueprint import components as blueprint_components +from ...error_utils import catch_and_log_exceptions from .tensor_view_fit_ext import TensorViewFitExt __all__ = ["TensorViewFit"] @@ -25,7 +26,7 @@ class TensorViewFit(TensorViewFitExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - scaling=None, # type: ignore[arg-type] + scaling=None, ) @classmethod @@ -35,10 +36,53 @@ def _clear(cls) -> TensorViewFit: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + scaling: blueprint_components.ViewFitLike | None = None, + ) -> TensorViewFit: + """ + Update only some specific fields of a `TensorViewFit`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + scaling: + How the image is scaled to fit the view. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "scaling": scaling, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> TensorViewFit: + """Clear all the fields of a `TensorViewFit`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + scaling=[], + ) + return inst + scaling: blueprint_components.ViewFitBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.ViewFitBatch._optional, # type: ignore[misc] + converter=blueprint_components.ViewFitBatch._converter, # type: ignore[misc] ) # How the image is scaled to fit the view. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/view_blueprint.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/view_blueprint.py index 70ef957a1617..013cb30bd5fd 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/view_blueprint.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/view_blueprint.py @@ -66,10 +66,10 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - class_identifier=None, # type: ignore[arg-type] - display_name=None, # type: ignore[arg-type] - space_origin=None, # type: ignore[arg-type] - visible=None, # type: ignore[arg-type] + class_identifier=None, + display_name=None, + space_origin=None, + visible=None, ) @classmethod @@ -79,27 +79,94 @@ def _clear(cls) -> ViewBlueprint: inst.__attrs_clear__() return inst - class_identifier: blueprint_components.ViewClassBatch = field( - metadata={"component": "required"}, - converter=blueprint_components.ViewClassBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + class_identifier: datatypes.Utf8Like | None = None, + display_name: datatypes.Utf8Like | None = None, + space_origin: datatypes.EntityPathLike | None = None, + visible: datatypes.BoolLike | None = None, + ) -> ViewBlueprint: + """ + Update only some specific fields of a `ViewBlueprint`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + class_identifier: + The class of the view. + display_name: + The name of the view. + space_origin: + The "anchor point" of this view. + + Defaults to the root path '/' if not specified. + + The transform at this path forms the reference point for all scene->world transforms in this view. + I.e. the position of this entity path in space forms the origin of the coordinate system in this view. + Furthermore, this is the primary indicator for heuristics on what entities we show in this view. + visible: + Whether this view is visible. + + Defaults to true if not specified. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "class_identifier": class_identifier, + "display_name": display_name, + "space_origin": space_origin, + "visible": visible, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> ViewBlueprint: + """Clear all the fields of a `ViewBlueprint`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + class_identifier=[], + display_name=[], + space_origin=[], + visible=[], + ) + return inst + + class_identifier: blueprint_components.ViewClassBatch | None = field( + metadata={"component": True}, + default=None, + converter=blueprint_components.ViewClassBatch._converter, # type: ignore[misc] ) # The class of the view. # # (Docstring intentionally commented out to hide this field from the docs) display_name: components.NameBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.NameBatch._optional, # type: ignore[misc] + converter=components.NameBatch._converter, # type: ignore[misc] ) # The name of the view. # # (Docstring intentionally commented out to hide this field from the docs) space_origin: blueprint_components.ViewOriginBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.ViewOriginBatch._optional, # type: ignore[misc] + converter=blueprint_components.ViewOriginBatch._converter, # type: ignore[misc] ) # The "anchor point" of this view. # @@ -112,9 +179,9 @@ def _clear(cls) -> ViewBlueprint: # (Docstring intentionally commented out to hide this field from the docs) visible: blueprint_components.VisibleBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.VisibleBatch._optional, # type: ignore[misc] + converter=blueprint_components.VisibleBatch._converter, # type: ignore[misc] ) # Whether this view is visible. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/view_contents.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/view_contents.py index 8708444a715a..2f9d6b2184fa 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/view_contents.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/view_contents.py @@ -84,7 +84,7 @@ def __init__(self: Any, query: datatypes.Utf8ArrayLike): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - query=None, # type: ignore[arg-type] + query=None, ) @classmethod @@ -94,9 +94,55 @@ def _clear(cls) -> ViewContents: inst.__attrs_clear__() return inst - query: blueprint_components.QueryExpressionBatch = field( - metadata={"component": "required"}, - converter=blueprint_components.QueryExpressionBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + query: datatypes.Utf8ArrayLike | None = None, + ) -> ViewContents: + """ + Update only some specific fields of a `ViewContents`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + query: + The `QueryExpression` that populates the contents for the view. + + They determine which entities are part of the view. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "query": query, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> ViewContents: + """Clear all the fields of a `ViewContents`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + query=[], + ) + return inst + + query: blueprint_components.QueryExpressionBatch | None = field( + metadata={"component": True}, + default=None, + converter=blueprint_components.QueryExpressionBatch._converter, # type: ignore[misc] ) # The `QueryExpression` that populates the contents for the view. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/viewport_blueprint.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/viewport_blueprint.py index 3c8e85ce7139..3fe08aea0b65 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/viewport_blueprint.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/viewport_blueprint.py @@ -77,11 +77,11 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - root_container=None, # type: ignore[arg-type] - maximized=None, # type: ignore[arg-type] - auto_layout=None, # type: ignore[arg-type] - auto_views=None, # type: ignore[arg-type] - past_viewer_recommendations=None, # type: ignore[arg-type] + root_container=None, + maximized=None, + auto_layout=None, + auto_views=None, + past_viewer_recommendations=None, ) @classmethod @@ -91,28 +91,103 @@ def _clear(cls) -> ViewportBlueprint: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + root_container: datatypes.UuidLike | None = None, + maximized: datatypes.UuidLike | None = None, + auto_layout: datatypes.BoolLike | None = None, + auto_views: datatypes.BoolLike | None = None, + past_viewer_recommendations: datatypes.UInt64ArrayLike | None = None, + ) -> ViewportBlueprint: + """ + Update only some specific fields of a `ViewportBlueprint`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + root_container: + The layout of the views + maximized: + Show one tab as maximized? + auto_layout: + Whether the viewport layout is determined automatically. + + If `true`, the container layout will be reset whenever a new view is added or removed. + This defaults to `false` and is automatically set to `false` when there is user determined layout. + auto_views: + Whether or not views should be created automatically. + + If `true`, the viewer will only add views that it hasn't considered previously (as identified by `past_viewer_recommendations`) + and which aren't deemed redundant to existing views. + This defaults to `false` and is automatically set to `false` when the user adds views manually in the viewer. + past_viewer_recommendations: + Hashes of all recommended views the viewer has already added and that should not be added again. + + This is an internal field and should not be set usually. + If you want the viewer from stopping to add views, you should set `auto_views` to `false`. + + The viewer uses this to determine whether it should keep adding views. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "root_container": root_container, + "maximized": maximized, + "auto_layout": auto_layout, + "auto_views": auto_views, + "past_viewer_recommendations": past_viewer_recommendations, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> ViewportBlueprint: + """Clear all the fields of a `ViewportBlueprint`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + root_container=[], + maximized=[], + auto_layout=[], + auto_views=[], + past_viewer_recommendations=[], + ) + return inst + root_container: blueprint_components.RootContainerBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.RootContainerBatch._optional, # type: ignore[misc] + converter=blueprint_components.RootContainerBatch._converter, # type: ignore[misc] ) # The layout of the views # # (Docstring intentionally commented out to hide this field from the docs) maximized: blueprint_components.ViewMaximizedBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.ViewMaximizedBatch._optional, # type: ignore[misc] + converter=blueprint_components.ViewMaximizedBatch._converter, # type: ignore[misc] ) # Show one tab as maximized? # # (Docstring intentionally commented out to hide this field from the docs) auto_layout: blueprint_components.AutoLayoutBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.AutoLayoutBatch._optional, # type: ignore[misc] + converter=blueprint_components.AutoLayoutBatch._converter, # type: ignore[misc] ) # Whether the viewport layout is determined automatically. # @@ -122,9 +197,9 @@ def _clear(cls) -> ViewportBlueprint: # (Docstring intentionally commented out to hide this field from the docs) auto_views: blueprint_components.AutoViewsBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.AutoViewsBatch._optional, # type: ignore[misc] + converter=blueprint_components.AutoViewsBatch._converter, # type: ignore[misc] ) # Whether or not views should be created automatically. # @@ -135,9 +210,9 @@ def _clear(cls) -> ViewportBlueprint: # (Docstring intentionally commented out to hide this field from the docs) past_viewer_recommendations: blueprint_components.ViewerRecommendationHashBatch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=blueprint_components.ViewerRecommendationHashBatch._optional, # type: ignore[misc] + converter=blueprint_components.ViewerRecommendationHashBatch._converter, # type: ignore[misc] ) # Hashes of all recommended views the viewer has already added and that should not be added again. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/visible_time_ranges.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/visible_time_ranges.py index 6554b67d55e4..3101d9f5dfb5 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/visible_time_ranges.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/visible_time_ranges.py @@ -7,10 +7,12 @@ from attrs import define, field +from ... import datatypes from ..._baseclasses import ( Archetype, ) from ...blueprint import components as blueprint_components +from ...error_utils import catch_and_log_exceptions from .visible_time_ranges_ext import VisibleTimeRangesExt __all__ = ["VisibleTimeRanges"] @@ -35,7 +37,7 @@ class VisibleTimeRanges(VisibleTimeRangesExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - ranges=None, # type: ignore[arg-type] + ranges=None, ) @classmethod @@ -45,9 +47,55 @@ def _clear(cls) -> VisibleTimeRanges: inst.__attrs_clear__() return inst - ranges: blueprint_components.VisibleTimeRangeBatch = field( - metadata={"component": "required"}, - converter=blueprint_components.VisibleTimeRangeBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + ranges: datatypes.VisibleTimeRangeArrayLike | None = None, + ) -> VisibleTimeRanges: + """ + Update only some specific fields of a `VisibleTimeRanges`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + ranges: + The time ranges to show for each timeline unless specified otherwise on a per-entity basis. + + If a timeline is specified more than once, the first entry will be used. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "ranges": ranges, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> VisibleTimeRanges: + """Clear all the fields of a `VisibleTimeRanges`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + ranges=[], + ) + return inst + + ranges: blueprint_components.VisibleTimeRangeBatch | None = field( + metadata={"component": True}, + default=None, + converter=blueprint_components.VisibleTimeRangeBatch._converter, # type: ignore[misc] ) # The time ranges to show for each timeline unless specified otherwise on a per-entity basis. # diff --git a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/visual_bounds2d.py b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/visual_bounds2d.py index 7a6a5159dc0b..16444fb54aa1 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/archetypes/visual_bounds2d.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/archetypes/visual_bounds2d.py @@ -7,10 +7,12 @@ from attrs import define, field +from ... import datatypes from ..._baseclasses import ( Archetype, ) from ...blueprint import components as blueprint_components +from ...error_utils import catch_and_log_exceptions from .visual_bounds2d_ext import VisualBounds2DExt __all__ = ["VisualBounds2D"] @@ -33,7 +35,7 @@ class VisualBounds2D(VisualBounds2DExt, Archetype): def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - range=None, # type: ignore[arg-type] + range=None, ) @classmethod @@ -43,9 +45,55 @@ def _clear(cls) -> VisualBounds2D: inst.__attrs_clear__() return inst - range: blueprint_components.VisualBounds2DBatch = field( - metadata={"component": "required"}, - converter=blueprint_components.VisualBounds2DBatch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + range: datatypes.Range2DLike | None = None, + ) -> VisualBounds2D: + """ + Update only some specific fields of a `VisualBounds2D`. + + Parameters + ---------- + clear: + If true, all unspecified fields will be explicitly cleared. + range: + Controls the visible range of a 2D view. + + Use this to control pan & zoom of the view. + + """ + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "range": range, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> VisualBounds2D: + """Clear all the fields of a `VisualBounds2D`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + range=[], + ) + return inst + + range: blueprint_components.VisualBounds2DBatch | None = field( + metadata={"component": True}, + default=None, + converter=blueprint_components.VisualBounds2DBatch._converter, # type: ignore[misc] ) # Controls the visible range of a 2D view. # diff --git a/rerun_py/tests/test_types/archetypes/affix_fuzzer1.py b/rerun_py/tests/test_types/archetypes/affix_fuzzer1.py index 15a00291dbec..2b53b0966924 100644 --- a/rerun_py/tests/test_types/archetypes/affix_fuzzer1.py +++ b/rerun_py/tests/test_types/archetypes/affix_fuzzer1.py @@ -79,28 +79,28 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - fuzz1001=None, # type: ignore[arg-type] - fuzz1002=None, # type: ignore[arg-type] - fuzz1003=None, # type: ignore[arg-type] - fuzz1004=None, # type: ignore[arg-type] - fuzz1005=None, # type: ignore[arg-type] - fuzz1006=None, # type: ignore[arg-type] - fuzz1007=None, # type: ignore[arg-type] - fuzz1008=None, # type: ignore[arg-type] - fuzz1009=None, # type: ignore[arg-type] - fuzz1010=None, # type: ignore[arg-type] - fuzz1011=None, # type: ignore[arg-type] - fuzz1012=None, # type: ignore[arg-type] - fuzz1013=None, # type: ignore[arg-type] - fuzz1014=None, # type: ignore[arg-type] - fuzz1015=None, # type: ignore[arg-type] - fuzz1016=None, # type: ignore[arg-type] - fuzz1017=None, # type: ignore[arg-type] - fuzz1018=None, # type: ignore[arg-type] - fuzz1019=None, # type: ignore[arg-type] - fuzz1020=None, # type: ignore[arg-type] - fuzz1021=None, # type: ignore[arg-type] - fuzz1022=None, # type: ignore[arg-type] + fuzz1001=None, + fuzz1002=None, + fuzz1003=None, + fuzz1004=None, + fuzz1005=None, + fuzz1006=None, + fuzz1007=None, + fuzz1008=None, + fuzz1009=None, + fuzz1010=None, + fuzz1011=None, + fuzz1012=None, + fuzz1013=None, + fuzz1014=None, + fuzz1015=None, + fuzz1016=None, + fuzz1017=None, + fuzz1018=None, + fuzz1019=None, + fuzz1020=None, + fuzz1021=None, + fuzz1022=None, ) @classmethod @@ -110,93 +110,211 @@ def _clear(cls) -> AffixFuzzer1: inst.__attrs_clear__() return inst - fuzz1001: components.AffixFuzzer1Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer1Batch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + fuzz1001: datatypes.AffixFuzzer1Like | None = None, + fuzz1002: datatypes.AffixFuzzer1Like | None = None, + fuzz1003: datatypes.AffixFuzzer1Like | None = None, + fuzz1004: datatypes.AffixFuzzer1Like | None = None, + fuzz1005: datatypes.AffixFuzzer1Like | None = None, + fuzz1006: datatypes.AffixFuzzer1Like | None = None, + fuzz1007: components.AffixFuzzer7Like | None = None, + fuzz1008: components.AffixFuzzer8Like | None = None, + fuzz1009: components.AffixFuzzer9Like | None = None, + fuzz1010: components.AffixFuzzer10Like | None = None, + fuzz1011: components.AffixFuzzer11Like | None = None, + fuzz1012: components.AffixFuzzer12Like | None = None, + fuzz1013: components.AffixFuzzer13Like | None = None, + fuzz1014: datatypes.AffixFuzzer3Like | None = None, + fuzz1015: datatypes.AffixFuzzer3Like | None = None, + fuzz1016: components.AffixFuzzer16Like | None = None, + fuzz1017: components.AffixFuzzer17Like | None = None, + fuzz1018: components.AffixFuzzer18Like | None = None, + fuzz1019: datatypes.AffixFuzzer5Like | None = None, + fuzz1020: datatypes.AffixFuzzer20Like | None = None, + fuzz1021: datatypes.AffixFuzzer21Like | None = None, + fuzz1022: datatypes.AffixFuzzer22Like | None = None, + ) -> AffixFuzzer1: + """Update only some specific fields of a `AffixFuzzer1`.""" + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "fuzz1001": fuzz1001, + "fuzz1002": fuzz1002, + "fuzz1003": fuzz1003, + "fuzz1004": fuzz1004, + "fuzz1005": fuzz1005, + "fuzz1006": fuzz1006, + "fuzz1007": fuzz1007, + "fuzz1008": fuzz1008, + "fuzz1009": fuzz1009, + "fuzz1010": fuzz1010, + "fuzz1011": fuzz1011, + "fuzz1012": fuzz1012, + "fuzz1013": fuzz1013, + "fuzz1014": fuzz1014, + "fuzz1015": fuzz1015, + "fuzz1016": fuzz1016, + "fuzz1017": fuzz1017, + "fuzz1018": fuzz1018, + "fuzz1019": fuzz1019, + "fuzz1020": fuzz1020, + "fuzz1021": fuzz1021, + "fuzz1022": fuzz1022, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> AffixFuzzer1: + """Clear all the fields of a `AffixFuzzer1`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + fuzz1001=[], + fuzz1002=[], + fuzz1003=[], + fuzz1004=[], + fuzz1005=[], + fuzz1006=[], + fuzz1007=[], + fuzz1008=[], + fuzz1009=[], + fuzz1010=[], + fuzz1011=[], + fuzz1012=[], + fuzz1013=[], + fuzz1014=[], + fuzz1015=[], + fuzz1016=[], + fuzz1017=[], + fuzz1018=[], + fuzz1019=[], + fuzz1020=[], + fuzz1021=[], + fuzz1022=[], + ) + return inst + + fuzz1001: components.AffixFuzzer1Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer1Batch._converter, # type: ignore[misc] ) - fuzz1002: components.AffixFuzzer2Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer2Batch._required, # type: ignore[misc] + fuzz1002: components.AffixFuzzer2Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer2Batch._converter, # type: ignore[misc] ) - fuzz1003: components.AffixFuzzer3Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer3Batch._required, # type: ignore[misc] + fuzz1003: components.AffixFuzzer3Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer3Batch._converter, # type: ignore[misc] ) - fuzz1004: components.AffixFuzzer4Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer4Batch._required, # type: ignore[misc] + fuzz1004: components.AffixFuzzer4Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer4Batch._converter, # type: ignore[misc] ) - fuzz1005: components.AffixFuzzer5Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer5Batch._required, # type: ignore[misc] + fuzz1005: components.AffixFuzzer5Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer5Batch._converter, # type: ignore[misc] ) - fuzz1006: components.AffixFuzzer6Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer6Batch._required, # type: ignore[misc] + fuzz1006: components.AffixFuzzer6Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer6Batch._converter, # type: ignore[misc] ) - fuzz1007: components.AffixFuzzer7Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer7Batch._required, # type: ignore[misc] + fuzz1007: components.AffixFuzzer7Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer7Batch._converter, # type: ignore[misc] ) - fuzz1008: components.AffixFuzzer8Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer8Batch._required, # type: ignore[misc] + fuzz1008: components.AffixFuzzer8Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer8Batch._converter, # type: ignore[misc] ) - fuzz1009: components.AffixFuzzer9Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer9Batch._required, # type: ignore[misc] + fuzz1009: components.AffixFuzzer9Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer9Batch._converter, # type: ignore[misc] ) - fuzz1010: components.AffixFuzzer10Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer10Batch._required, # type: ignore[misc] + fuzz1010: components.AffixFuzzer10Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer10Batch._converter, # type: ignore[misc] ) - fuzz1011: components.AffixFuzzer11Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer11Batch._required, # type: ignore[misc] + fuzz1011: components.AffixFuzzer11Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer11Batch._converter, # type: ignore[misc] ) - fuzz1012: components.AffixFuzzer12Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer12Batch._required, # type: ignore[misc] + fuzz1012: components.AffixFuzzer12Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer12Batch._converter, # type: ignore[misc] ) - fuzz1013: components.AffixFuzzer13Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer13Batch._required, # type: ignore[misc] + fuzz1013: components.AffixFuzzer13Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer13Batch._converter, # type: ignore[misc] ) - fuzz1014: components.AffixFuzzer14Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer14Batch._required, # type: ignore[misc] + fuzz1014: components.AffixFuzzer14Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer14Batch._converter, # type: ignore[misc] ) - fuzz1015: components.AffixFuzzer15Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer15Batch._required, # type: ignore[misc] + fuzz1015: components.AffixFuzzer15Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer15Batch._converter, # type: ignore[misc] ) - fuzz1016: components.AffixFuzzer16Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer16Batch._required, # type: ignore[misc] + fuzz1016: components.AffixFuzzer16Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer16Batch._converter, # type: ignore[misc] ) - fuzz1017: components.AffixFuzzer17Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer17Batch._required, # type: ignore[misc] + fuzz1017: components.AffixFuzzer17Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer17Batch._converter, # type: ignore[misc] ) - fuzz1018: components.AffixFuzzer18Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer18Batch._required, # type: ignore[misc] + fuzz1018: components.AffixFuzzer18Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer18Batch._converter, # type: ignore[misc] ) - fuzz1019: components.AffixFuzzer19Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer19Batch._required, # type: ignore[misc] + fuzz1019: components.AffixFuzzer19Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer19Batch._converter, # type: ignore[misc] ) - fuzz1020: components.AffixFuzzer20Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer20Batch._required, # type: ignore[misc] + fuzz1020: components.AffixFuzzer20Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer20Batch._converter, # type: ignore[misc] ) - fuzz1021: components.AffixFuzzer21Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer21Batch._required, # type: ignore[misc] + fuzz1021: components.AffixFuzzer21Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer21Batch._converter, # type: ignore[misc] ) - fuzz1022: components.AffixFuzzer22Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer22Batch._required, # type: ignore[misc] + fuzz1022: components.AffixFuzzer22Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer22Batch._converter, # type: ignore[misc] ) __str__ = Archetype.__str__ __repr__ = Archetype.__repr__ # type: ignore[assignment] diff --git a/rerun_py/tests/test_types/archetypes/affix_fuzzer2.py b/rerun_py/tests/test_types/archetypes/affix_fuzzer2.py index cdfbb6005b05..6d1c623d2ec2 100644 --- a/rerun_py/tests/test_types/archetypes/affix_fuzzer2.py +++ b/rerun_py/tests/test_types/archetypes/affix_fuzzer2.py @@ -73,25 +73,25 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - fuzz1101=None, # type: ignore[arg-type] - fuzz1102=None, # type: ignore[arg-type] - fuzz1103=None, # type: ignore[arg-type] - fuzz1104=None, # type: ignore[arg-type] - fuzz1105=None, # type: ignore[arg-type] - fuzz1106=None, # type: ignore[arg-type] - fuzz1107=None, # type: ignore[arg-type] - fuzz1108=None, # type: ignore[arg-type] - fuzz1109=None, # type: ignore[arg-type] - fuzz1110=None, # type: ignore[arg-type] - fuzz1111=None, # type: ignore[arg-type] - fuzz1112=None, # type: ignore[arg-type] - fuzz1113=None, # type: ignore[arg-type] - fuzz1114=None, # type: ignore[arg-type] - fuzz1115=None, # type: ignore[arg-type] - fuzz1116=None, # type: ignore[arg-type] - fuzz1117=None, # type: ignore[arg-type] - fuzz1118=None, # type: ignore[arg-type] - fuzz1122=None, # type: ignore[arg-type] + fuzz1101=None, + fuzz1102=None, + fuzz1103=None, + fuzz1104=None, + fuzz1105=None, + fuzz1106=None, + fuzz1107=None, + fuzz1108=None, + fuzz1109=None, + fuzz1110=None, + fuzz1111=None, + fuzz1112=None, + fuzz1113=None, + fuzz1114=None, + fuzz1115=None, + fuzz1116=None, + fuzz1117=None, + fuzz1118=None, + fuzz1122=None, ) @classmethod @@ -101,81 +101,187 @@ def _clear(cls) -> AffixFuzzer2: inst.__attrs_clear__() return inst - fuzz1101: components.AffixFuzzer1Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer1Batch._required, # type: ignore[misc] + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + fuzz1101: datatypes.AffixFuzzer1ArrayLike | None = None, + fuzz1102: datatypes.AffixFuzzer1ArrayLike | None = None, + fuzz1103: datatypes.AffixFuzzer1ArrayLike | None = None, + fuzz1104: datatypes.AffixFuzzer1ArrayLike | None = None, + fuzz1105: datatypes.AffixFuzzer1ArrayLike | None = None, + fuzz1106: datatypes.AffixFuzzer1ArrayLike | None = None, + fuzz1107: components.AffixFuzzer7ArrayLike | None = None, + fuzz1108: components.AffixFuzzer8ArrayLike | None = None, + fuzz1109: components.AffixFuzzer9ArrayLike | None = None, + fuzz1110: components.AffixFuzzer10ArrayLike | None = None, + fuzz1111: components.AffixFuzzer11ArrayLike | None = None, + fuzz1112: components.AffixFuzzer12ArrayLike | None = None, + fuzz1113: components.AffixFuzzer13ArrayLike | None = None, + fuzz1114: datatypes.AffixFuzzer3ArrayLike | None = None, + fuzz1115: datatypes.AffixFuzzer3ArrayLike | None = None, + fuzz1116: components.AffixFuzzer16ArrayLike | None = None, + fuzz1117: components.AffixFuzzer17ArrayLike | None = None, + fuzz1118: components.AffixFuzzer18ArrayLike | None = None, + fuzz1122: datatypes.AffixFuzzer22ArrayLike | None = None, + ) -> AffixFuzzer2: + """Update only some specific fields of a `AffixFuzzer2`.""" + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "fuzz1101": fuzz1101, + "fuzz1102": fuzz1102, + "fuzz1103": fuzz1103, + "fuzz1104": fuzz1104, + "fuzz1105": fuzz1105, + "fuzz1106": fuzz1106, + "fuzz1107": fuzz1107, + "fuzz1108": fuzz1108, + "fuzz1109": fuzz1109, + "fuzz1110": fuzz1110, + "fuzz1111": fuzz1111, + "fuzz1112": fuzz1112, + "fuzz1113": fuzz1113, + "fuzz1114": fuzz1114, + "fuzz1115": fuzz1115, + "fuzz1116": fuzz1116, + "fuzz1117": fuzz1117, + "fuzz1118": fuzz1118, + "fuzz1122": fuzz1122, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> AffixFuzzer2: + """Clear all the fields of a `AffixFuzzer2`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + fuzz1101=[], + fuzz1102=[], + fuzz1103=[], + fuzz1104=[], + fuzz1105=[], + fuzz1106=[], + fuzz1107=[], + fuzz1108=[], + fuzz1109=[], + fuzz1110=[], + fuzz1111=[], + fuzz1112=[], + fuzz1113=[], + fuzz1114=[], + fuzz1115=[], + fuzz1116=[], + fuzz1117=[], + fuzz1118=[], + fuzz1122=[], + ) + return inst + + fuzz1101: components.AffixFuzzer1Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer1Batch._converter, # type: ignore[misc] ) - fuzz1102: components.AffixFuzzer2Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer2Batch._required, # type: ignore[misc] + fuzz1102: components.AffixFuzzer2Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer2Batch._converter, # type: ignore[misc] ) - fuzz1103: components.AffixFuzzer3Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer3Batch._required, # type: ignore[misc] + fuzz1103: components.AffixFuzzer3Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer3Batch._converter, # type: ignore[misc] ) - fuzz1104: components.AffixFuzzer4Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer4Batch._required, # type: ignore[misc] + fuzz1104: components.AffixFuzzer4Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer4Batch._converter, # type: ignore[misc] ) - fuzz1105: components.AffixFuzzer5Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer5Batch._required, # type: ignore[misc] + fuzz1105: components.AffixFuzzer5Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer5Batch._converter, # type: ignore[misc] ) - fuzz1106: components.AffixFuzzer6Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer6Batch._required, # type: ignore[misc] + fuzz1106: components.AffixFuzzer6Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer6Batch._converter, # type: ignore[misc] ) - fuzz1107: components.AffixFuzzer7Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer7Batch._required, # type: ignore[misc] + fuzz1107: components.AffixFuzzer7Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer7Batch._converter, # type: ignore[misc] ) - fuzz1108: components.AffixFuzzer8Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer8Batch._required, # type: ignore[misc] + fuzz1108: components.AffixFuzzer8Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer8Batch._converter, # type: ignore[misc] ) - fuzz1109: components.AffixFuzzer9Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer9Batch._required, # type: ignore[misc] + fuzz1109: components.AffixFuzzer9Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer9Batch._converter, # type: ignore[misc] ) - fuzz1110: components.AffixFuzzer10Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer10Batch._required, # type: ignore[misc] + fuzz1110: components.AffixFuzzer10Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer10Batch._converter, # type: ignore[misc] ) - fuzz1111: components.AffixFuzzer11Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer11Batch._required, # type: ignore[misc] + fuzz1111: components.AffixFuzzer11Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer11Batch._converter, # type: ignore[misc] ) - fuzz1112: components.AffixFuzzer12Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer12Batch._required, # type: ignore[misc] + fuzz1112: components.AffixFuzzer12Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer12Batch._converter, # type: ignore[misc] ) - fuzz1113: components.AffixFuzzer13Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer13Batch._required, # type: ignore[misc] + fuzz1113: components.AffixFuzzer13Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer13Batch._converter, # type: ignore[misc] ) - fuzz1114: components.AffixFuzzer14Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer14Batch._required, # type: ignore[misc] + fuzz1114: components.AffixFuzzer14Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer14Batch._converter, # type: ignore[misc] ) - fuzz1115: components.AffixFuzzer15Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer15Batch._required, # type: ignore[misc] + fuzz1115: components.AffixFuzzer15Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer15Batch._converter, # type: ignore[misc] ) - fuzz1116: components.AffixFuzzer16Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer16Batch._required, # type: ignore[misc] + fuzz1116: components.AffixFuzzer16Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer16Batch._converter, # type: ignore[misc] ) - fuzz1117: components.AffixFuzzer17Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer17Batch._required, # type: ignore[misc] + fuzz1117: components.AffixFuzzer17Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer17Batch._converter, # type: ignore[misc] ) - fuzz1118: components.AffixFuzzer18Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer18Batch._required, # type: ignore[misc] + fuzz1118: components.AffixFuzzer18Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer18Batch._converter, # type: ignore[misc] ) - fuzz1122: components.AffixFuzzer22Batch = field( - metadata={"component": "required"}, - converter=components.AffixFuzzer22Batch._required, # type: ignore[misc] + fuzz1122: components.AffixFuzzer22Batch | None = field( + metadata={"component": True}, + default=None, + converter=components.AffixFuzzer22Batch._converter, # type: ignore[misc] ) __str__ = Archetype.__str__ __repr__ = Archetype.__repr__ # type: ignore[assignment] diff --git a/rerun_py/tests/test_types/archetypes/affix_fuzzer3.py b/rerun_py/tests/test_types/archetypes/affix_fuzzer3.py index d1f7dfd6ade7..a78d6215b144 100644 --- a/rerun_py/tests/test_types/archetypes/affix_fuzzer3.py +++ b/rerun_py/tests/test_types/archetypes/affix_fuzzer3.py @@ -72,24 +72,24 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - fuzz2001=None, # type: ignore[arg-type] - fuzz2002=None, # type: ignore[arg-type] - fuzz2003=None, # type: ignore[arg-type] - fuzz2004=None, # type: ignore[arg-type] - fuzz2005=None, # type: ignore[arg-type] - fuzz2006=None, # type: ignore[arg-type] - fuzz2007=None, # type: ignore[arg-type] - fuzz2008=None, # type: ignore[arg-type] - fuzz2009=None, # type: ignore[arg-type] - fuzz2010=None, # type: ignore[arg-type] - fuzz2011=None, # type: ignore[arg-type] - fuzz2012=None, # type: ignore[arg-type] - fuzz2013=None, # type: ignore[arg-type] - fuzz2014=None, # type: ignore[arg-type] - fuzz2015=None, # type: ignore[arg-type] - fuzz2016=None, # type: ignore[arg-type] - fuzz2017=None, # type: ignore[arg-type] - fuzz2018=None, # type: ignore[arg-type] + fuzz2001=None, + fuzz2002=None, + fuzz2003=None, + fuzz2004=None, + fuzz2005=None, + fuzz2006=None, + fuzz2007=None, + fuzz2008=None, + fuzz2009=None, + fuzz2010=None, + fuzz2011=None, + fuzz2012=None, + fuzz2013=None, + fuzz2014=None, + fuzz2015=None, + fuzz2016=None, + fuzz2017=None, + fuzz2018=None, ) @classmethod @@ -99,95 +99,179 @@ def _clear(cls) -> AffixFuzzer3: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + fuzz2001: datatypes.AffixFuzzer1Like | None = None, + fuzz2002: datatypes.AffixFuzzer1Like | None = None, + fuzz2003: datatypes.AffixFuzzer1Like | None = None, + fuzz2004: datatypes.AffixFuzzer1Like | None = None, + fuzz2005: datatypes.AffixFuzzer1Like | None = None, + fuzz2006: datatypes.AffixFuzzer1Like | None = None, + fuzz2007: components.AffixFuzzer7Like | None = None, + fuzz2008: components.AffixFuzzer8Like | None = None, + fuzz2009: components.AffixFuzzer9Like | None = None, + fuzz2010: components.AffixFuzzer10Like | None = None, + fuzz2011: components.AffixFuzzer11Like | None = None, + fuzz2012: components.AffixFuzzer12Like | None = None, + fuzz2013: components.AffixFuzzer13Like | None = None, + fuzz2014: datatypes.AffixFuzzer3Like | None = None, + fuzz2015: datatypes.AffixFuzzer3Like | None = None, + fuzz2016: components.AffixFuzzer16Like | None = None, + fuzz2017: components.AffixFuzzer17Like | None = None, + fuzz2018: components.AffixFuzzer18Like | None = None, + ) -> AffixFuzzer3: + """Update only some specific fields of a `AffixFuzzer3`.""" + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "fuzz2001": fuzz2001, + "fuzz2002": fuzz2002, + "fuzz2003": fuzz2003, + "fuzz2004": fuzz2004, + "fuzz2005": fuzz2005, + "fuzz2006": fuzz2006, + "fuzz2007": fuzz2007, + "fuzz2008": fuzz2008, + "fuzz2009": fuzz2009, + "fuzz2010": fuzz2010, + "fuzz2011": fuzz2011, + "fuzz2012": fuzz2012, + "fuzz2013": fuzz2013, + "fuzz2014": fuzz2014, + "fuzz2015": fuzz2015, + "fuzz2016": fuzz2016, + "fuzz2017": fuzz2017, + "fuzz2018": fuzz2018, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> AffixFuzzer3: + """Clear all the fields of a `AffixFuzzer3`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + fuzz2001=[], + fuzz2002=[], + fuzz2003=[], + fuzz2004=[], + fuzz2005=[], + fuzz2006=[], + fuzz2007=[], + fuzz2008=[], + fuzz2009=[], + fuzz2010=[], + fuzz2011=[], + fuzz2012=[], + fuzz2013=[], + fuzz2014=[], + fuzz2015=[], + fuzz2016=[], + fuzz2017=[], + fuzz2018=[], + ) + return inst + fuzz2001: components.AffixFuzzer1Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer1Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer1Batch._converter, # type: ignore[misc] ) fuzz2002: components.AffixFuzzer2Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer2Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer2Batch._converter, # type: ignore[misc] ) fuzz2003: components.AffixFuzzer3Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer3Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer3Batch._converter, # type: ignore[misc] ) fuzz2004: components.AffixFuzzer4Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer4Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer4Batch._converter, # type: ignore[misc] ) fuzz2005: components.AffixFuzzer5Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer5Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer5Batch._converter, # type: ignore[misc] ) fuzz2006: components.AffixFuzzer6Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer6Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer6Batch._converter, # type: ignore[misc] ) fuzz2007: components.AffixFuzzer7Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer7Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer7Batch._converter, # type: ignore[misc] ) fuzz2008: components.AffixFuzzer8Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer8Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer8Batch._converter, # type: ignore[misc] ) fuzz2009: components.AffixFuzzer9Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer9Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer9Batch._converter, # type: ignore[misc] ) fuzz2010: components.AffixFuzzer10Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer10Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer10Batch._converter, # type: ignore[misc] ) fuzz2011: components.AffixFuzzer11Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer11Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer11Batch._converter, # type: ignore[misc] ) fuzz2012: components.AffixFuzzer12Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer12Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer12Batch._converter, # type: ignore[misc] ) fuzz2013: components.AffixFuzzer13Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer13Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer13Batch._converter, # type: ignore[misc] ) fuzz2014: components.AffixFuzzer14Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer14Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer14Batch._converter, # type: ignore[misc] ) fuzz2015: components.AffixFuzzer15Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer15Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer15Batch._converter, # type: ignore[misc] ) fuzz2016: components.AffixFuzzer16Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer16Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer16Batch._converter, # type: ignore[misc] ) fuzz2017: components.AffixFuzzer17Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer17Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer17Batch._converter, # type: ignore[misc] ) fuzz2018: components.AffixFuzzer18Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer18Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer18Batch._converter, # type: ignore[misc] ) __str__ = Archetype.__str__ __repr__ = Archetype.__repr__ # type: ignore[assignment] diff --git a/rerun_py/tests/test_types/archetypes/affix_fuzzer4.py b/rerun_py/tests/test_types/archetypes/affix_fuzzer4.py index eab5407e1cf7..0dd2c12241f0 100644 --- a/rerun_py/tests/test_types/archetypes/affix_fuzzer4.py +++ b/rerun_py/tests/test_types/archetypes/affix_fuzzer4.py @@ -72,24 +72,24 @@ def __init__( def __attrs_clear__(self) -> None: """Convenience method for calling `__attrs_init__` with all `None`s.""" self.__attrs_init__( - fuzz2101=None, # type: ignore[arg-type] - fuzz2102=None, # type: ignore[arg-type] - fuzz2103=None, # type: ignore[arg-type] - fuzz2104=None, # type: ignore[arg-type] - fuzz2105=None, # type: ignore[arg-type] - fuzz2106=None, # type: ignore[arg-type] - fuzz2107=None, # type: ignore[arg-type] - fuzz2108=None, # type: ignore[arg-type] - fuzz2109=None, # type: ignore[arg-type] - fuzz2110=None, # type: ignore[arg-type] - fuzz2111=None, # type: ignore[arg-type] - fuzz2112=None, # type: ignore[arg-type] - fuzz2113=None, # type: ignore[arg-type] - fuzz2114=None, # type: ignore[arg-type] - fuzz2115=None, # type: ignore[arg-type] - fuzz2116=None, # type: ignore[arg-type] - fuzz2117=None, # type: ignore[arg-type] - fuzz2118=None, # type: ignore[arg-type] + fuzz2101=None, + fuzz2102=None, + fuzz2103=None, + fuzz2104=None, + fuzz2105=None, + fuzz2106=None, + fuzz2107=None, + fuzz2108=None, + fuzz2109=None, + fuzz2110=None, + fuzz2111=None, + fuzz2112=None, + fuzz2113=None, + fuzz2114=None, + fuzz2115=None, + fuzz2116=None, + fuzz2117=None, + fuzz2118=None, ) @classmethod @@ -99,95 +99,179 @@ def _clear(cls) -> AffixFuzzer4: inst.__attrs_clear__() return inst + @classmethod + def update_fields( + cls, + *, + clear: bool = False, + fuzz2101: datatypes.AffixFuzzer1ArrayLike | None = None, + fuzz2102: datatypes.AffixFuzzer1ArrayLike | None = None, + fuzz2103: datatypes.AffixFuzzer1ArrayLike | None = None, + fuzz2104: datatypes.AffixFuzzer1ArrayLike | None = None, + fuzz2105: datatypes.AffixFuzzer1ArrayLike | None = None, + fuzz2106: datatypes.AffixFuzzer1ArrayLike | None = None, + fuzz2107: components.AffixFuzzer7ArrayLike | None = None, + fuzz2108: components.AffixFuzzer8ArrayLike | None = None, + fuzz2109: components.AffixFuzzer9ArrayLike | None = None, + fuzz2110: components.AffixFuzzer10ArrayLike | None = None, + fuzz2111: components.AffixFuzzer11ArrayLike | None = None, + fuzz2112: components.AffixFuzzer12ArrayLike | None = None, + fuzz2113: components.AffixFuzzer13ArrayLike | None = None, + fuzz2114: datatypes.AffixFuzzer3ArrayLike | None = None, + fuzz2115: datatypes.AffixFuzzer3ArrayLike | None = None, + fuzz2116: components.AffixFuzzer16ArrayLike | None = None, + fuzz2117: components.AffixFuzzer17ArrayLike | None = None, + fuzz2118: components.AffixFuzzer18ArrayLike | None = None, + ) -> AffixFuzzer4: + """Update only some specific fields of a `AffixFuzzer4`.""" + + inst = cls.__new__(cls) + with catch_and_log_exceptions(context=cls.__name__): + kwargs = { + "fuzz2101": fuzz2101, + "fuzz2102": fuzz2102, + "fuzz2103": fuzz2103, + "fuzz2104": fuzz2104, + "fuzz2105": fuzz2105, + "fuzz2106": fuzz2106, + "fuzz2107": fuzz2107, + "fuzz2108": fuzz2108, + "fuzz2109": fuzz2109, + "fuzz2110": fuzz2110, + "fuzz2111": fuzz2111, + "fuzz2112": fuzz2112, + "fuzz2113": fuzz2113, + "fuzz2114": fuzz2114, + "fuzz2115": fuzz2115, + "fuzz2116": fuzz2116, + "fuzz2117": fuzz2117, + "fuzz2118": fuzz2118, + } + + if clear: + kwargs = {k: v if v is not None else [] for k, v in kwargs.items()} # type: ignore[misc] + + inst.__attrs_init__(**kwargs) + return inst + + inst.__attrs_clear__() + return inst + + @classmethod + def clear_fields(cls) -> AffixFuzzer4: + """Clear all the fields of a `AffixFuzzer4`.""" + inst = cls.__new__(cls) + inst.__attrs_init__( + fuzz2101=[], + fuzz2102=[], + fuzz2103=[], + fuzz2104=[], + fuzz2105=[], + fuzz2106=[], + fuzz2107=[], + fuzz2108=[], + fuzz2109=[], + fuzz2110=[], + fuzz2111=[], + fuzz2112=[], + fuzz2113=[], + fuzz2114=[], + fuzz2115=[], + fuzz2116=[], + fuzz2117=[], + fuzz2118=[], + ) + return inst + fuzz2101: components.AffixFuzzer1Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer1Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer1Batch._converter, # type: ignore[misc] ) fuzz2102: components.AffixFuzzer2Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer2Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer2Batch._converter, # type: ignore[misc] ) fuzz2103: components.AffixFuzzer3Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer3Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer3Batch._converter, # type: ignore[misc] ) fuzz2104: components.AffixFuzzer4Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer4Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer4Batch._converter, # type: ignore[misc] ) fuzz2105: components.AffixFuzzer5Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer5Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer5Batch._converter, # type: ignore[misc] ) fuzz2106: components.AffixFuzzer6Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer6Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer6Batch._converter, # type: ignore[misc] ) fuzz2107: components.AffixFuzzer7Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer7Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer7Batch._converter, # type: ignore[misc] ) fuzz2108: components.AffixFuzzer8Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer8Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer8Batch._converter, # type: ignore[misc] ) fuzz2109: components.AffixFuzzer9Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer9Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer9Batch._converter, # type: ignore[misc] ) fuzz2110: components.AffixFuzzer10Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer10Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer10Batch._converter, # type: ignore[misc] ) fuzz2111: components.AffixFuzzer11Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer11Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer11Batch._converter, # type: ignore[misc] ) fuzz2112: components.AffixFuzzer12Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer12Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer12Batch._converter, # type: ignore[misc] ) fuzz2113: components.AffixFuzzer13Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer13Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer13Batch._converter, # type: ignore[misc] ) fuzz2114: components.AffixFuzzer14Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer14Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer14Batch._converter, # type: ignore[misc] ) fuzz2115: components.AffixFuzzer15Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer15Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer15Batch._converter, # type: ignore[misc] ) fuzz2116: components.AffixFuzzer16Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer16Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer16Batch._converter, # type: ignore[misc] ) fuzz2117: components.AffixFuzzer17Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer17Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer17Batch._converter, # type: ignore[misc] ) fuzz2118: components.AffixFuzzer18Batch | None = field( - metadata={"component": "optional"}, + metadata={"component": True}, default=None, - converter=components.AffixFuzzer18Batch._optional, # type: ignore[misc] + converter=components.AffixFuzzer18Batch._converter, # type: ignore[misc] ) __str__ = Archetype.__str__ __repr__ = Archetype.__repr__ # type: ignore[assignment] diff --git a/rerun_py/tests/unit/common_arrays.py b/rerun_py/tests/unit/common_arrays.py index 7edb7235632f..a5e19fd21dcb 100644 --- a/rerun_py/tests/unit/common_arrays.py +++ b/rerun_py/tests/unit/common_arrays.py @@ -102,7 +102,7 @@ def dvec2ds_expected(obj: Any, type_: Any | None = None) -> Any: expected = none_empty_or_value(obj, [[1.0, 2.0], [3.0, 4.0]]) - return type_._optional(expected) + return type_._converter(expected) vec2ds_arrays: list[Vec2DArrayLike] = [ @@ -141,7 +141,7 @@ def vec2ds_expected(obj: Any, type_: Any | None = None) -> Any: expected = none_empty_or_value(obj, [[1.0, 2.0], [3.0, 4.0]]) - return type_._optional(expected) + return type_._converter(expected) vec3ds_arrays: list[Vec3DArrayLike] = [ @@ -180,7 +180,7 @@ def vec3ds_expected(obj: Any, type_: Any | None = None) -> Any: expected = none_empty_or_value(obj, [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) - return type_._optional(expected) + return type_._converter(expected) vec4ds_arrays: list[Vec4DArrayLike] = [ @@ -219,7 +219,7 @@ def vec4ds_expected(obj: Any, type_: Any | None = None) -> Any: expected = none_empty_or_value(obj, [[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0]]) - return type_._optional(expected) + return type_._converter(expected) uvec3ds_arrays: list[UVec3DArrayLike] = [ @@ -254,7 +254,7 @@ def uvec3ds_expected(obj: Any, type_: Any | None = None) -> Any: expected = none_empty_or_value(obj, [[1, 2, 3], [4, 5, 6]]) - return type_._optional(expected) + return type_._converter(expected) quaternions_arrays: list[QuaternionArrayLike] = [ @@ -274,13 +274,13 @@ def uvec3ds_expected(obj: Any, type_: Any | None = None) -> Any: def quaternions_expected(rotations: QuaternionArrayLike, type_: Any) -> Any: if rotations is None: - return type_._optional(None) + return type_._converter(None) elif hasattr(rotations, "__len__") and len(rotations) == 0: # type: ignore[arg-type] - return type_._optional(rotations) + return type_._converter(rotations) elif isinstance(rotations, Quaternion): - return type_._optional(Quaternion(xyzw=[1, 2, 3, 4])) + return type_._converter(Quaternion(xyzw=[1, 2, 3, 4])) else: # sequence of Rotation3DLike - return type_._optional([Quaternion(xyzw=[1, 2, 3, 4])] * 2) + return type_._converter([Quaternion(xyzw=[1, 2, 3, 4])] * 2) rotation_axis_angle_arrays: list[RotationAxisAngleArrayLike] = [ @@ -299,15 +299,15 @@ def quaternions_expected(rotations: QuaternionArrayLike, type_: Any) -> Any: def expected_rotation_axis_angles(rotations: RotationAxisAngleArrayLike, type_: Any) -> Any: if rotations is None: - return type_._optional(None) + return type_._converter(None) elif hasattr(rotations, "__len__") and len(rotations) == 0: - return type_._optional(rotations) + return type_._converter(rotations) elif isinstance(rotations, RotationAxisAngle): - return type_._optional(RotationAxisAngle([1, 2, 3], 4)) + return type_._converter(RotationAxisAngle([1, 2, 3], 4)) elif isinstance(rotations, Quaternion): - return type_._optional(Quaternion(xyzw=[1, 2, 3, 4])) + return type_._converter(Quaternion(xyzw=[1, 2, 3, 4])) else: # sequence of Rotation3DLike - return type_._optional([RotationAxisAngle([1, 2, 3], 4)] * 2) + return type_._converter([RotationAxisAngle([1, 2, 3], 4)] * 2) radii_arrays: list[Float32ArrayLike | None] = [ @@ -329,7 +329,7 @@ def expected_rotation_axis_angles(rotations: RotationAxisAngleArrayLike, type_: def radii_expected(obj: Any) -> Any: expected = none_empty_or_value(obj, [1, 10]) - return RadiusBatch._optional(expected) + return RadiusBatch._converter(expected) colors_arrays: list[Rgba32ArrayLike | None] = [ @@ -441,7 +441,7 @@ def radii_expected(obj: Any) -> Any: def colors_expected(obj: Any) -> Any: expected = none_empty_or_value(obj, [0xAA0000CC, 0x00BB00DD]) - return ColorBatch._optional(expected) + return ColorBatch._converter(expected) labels_arrays: list[Utf8ArrayLike | None] = [ @@ -459,7 +459,7 @@ def colors_expected(obj: Any) -> Any: def labels_expected(obj: Any) -> Any: expected = none_empty_or_value(obj, ["hello", "friend"]) - return TextBatch._optional(expected) + return TextBatch._converter(expected) draw_orders: list[Float32ArrayLike | None] = [ @@ -473,7 +473,7 @@ def labels_expected(obj: Any) -> Any: def draw_order_expected(obj: Any) -> Any: expected = none_empty_or_value(obj, [300]) - return DrawOrderBatch._optional(expected) + return DrawOrderBatch._converter(expected) class_ids_arrays = [ @@ -498,7 +498,7 @@ def draw_order_expected(obj: Any) -> Any: def class_ids_expected(obj: Any) -> Any: expected = none_empty_or_value(obj, [126, 127]) - return ClassIdBatch._optional(expected) + return ClassIdBatch._converter(expected) keypoint_ids_arrays = [ @@ -523,7 +523,7 @@ def class_ids_expected(obj: Any) -> Any: def keypoint_ids_expected(obj: Any) -> Any: expected = none_empty_or_value(obj, [2, 3]) - return KeypointIdBatch._optional(expected) + return KeypointIdBatch._converter(expected) uuid_bytes0 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] diff --git a/rerun_py/tests/unit/test_asset3d.py b/rerun_py/tests/unit/test_asset3d.py index b132c5a1547d..70a1f5959eb7 100644 --- a/rerun_py/tests/unit/test_asset3d.py +++ b/rerun_py/tests/unit/test_asset3d.py @@ -24,5 +24,8 @@ def test_asset3d() -> None: ] for asset in assets: - assert asset.blob.as_arrow_array() == rr.components.BlobBatch(blob_comp).as_arrow_array() + assert ( + asset.blob is not None + and asset.blob.as_arrow_array() == rr.components.BlobBatch(blob_comp).as_arrow_array() + ) assert asset.media_type == rr.components.MediaTypeBatch(rr.components.MediaType.GLB) diff --git a/rerun_py/tests/unit/test_box3d.py b/rerun_py/tests/unit/test_box3d.py index e78537829796..3f78c52c13be 100644 --- a/rerun_py/tests/unit/test_box3d.py +++ b/rerun_py/tests/unit/test_box3d.py @@ -113,7 +113,7 @@ def test_boxes3d() -> None: assert arch.quaternions == quaternions_expected(quaternions, PoseRotationQuatBatch) assert arch.colors == colors_expected(colors) assert arch.radii == radii_expected(radii) - assert arch.fill_mode == rr.components.FillModeBatch._optional(fill_mode) + assert arch.fill_mode == rr.components.FillModeBatch._converter(fill_mode) assert arch.labels == labels_expected(labels) assert arch.class_ids == class_ids_expected(class_ids) diff --git a/rerun_py/tests/unit/test_container_blueprint.py b/rerun_py/tests/unit/test_container_blueprint.py index 494644d7e970..90be9ab2ee2a 100644 --- a/rerun_py/tests/unit/test_container_blueprint.py +++ b/rerun_py/tests/unit/test_container_blueprint.py @@ -127,15 +127,15 @@ def test_container_blueprint() -> None: ) print(f"{arch}\n") - assert arch.container_kind == ContainerKindBatch._required( + assert arch.container_kind == ContainerKindBatch._converter( none_empty_or_value(container_kind, ContainerKind.Tabs) ) - assert arch.display_name == NameBatch._optional(none_empty_or_value(display_name, Name("my container"))) - assert arch.contents == IncludedContentBatch._optional(none_empty_or_value(contents, contents_arrays[-1])) - assert arch.col_shares == ColumnShareBatch._optional(none_empty_or_value(col_shares, col_shares_arrays[-1])) - assert arch.row_shares == RowShareBatch._optional(none_empty_or_value(row_shares, row_shares_arrays[-1])) - assert arch.active_tab == ActiveTabBatch._optional(none_empty_or_value(active_tab, active_tab_arrays[-1])) - assert arch.visible == VisibleBatch._optional(none_empty_or_value(visible, visible_arrays[-1])) - assert arch.grid_columns == GridColumnsBatch._optional( + assert arch.display_name == NameBatch._converter(none_empty_or_value(display_name, Name("my container"))) + assert arch.contents == IncludedContentBatch._converter(none_empty_or_value(contents, contents_arrays[-1])) + assert arch.col_shares == ColumnShareBatch._converter(none_empty_or_value(col_shares, col_shares_arrays[-1])) + assert arch.row_shares == RowShareBatch._converter(none_empty_or_value(row_shares, row_shares_arrays[-1])) + assert arch.active_tab == ActiveTabBatch._converter(none_empty_or_value(active_tab, active_tab_arrays[-1])) + assert arch.visible == VisibleBatch._converter(none_empty_or_value(visible, visible_arrays[-1])) + assert arch.grid_columns == GridColumnsBatch._converter( none_empty_or_value(grid_columns, grid_columns_arrays[-1]) ) diff --git a/rerun_py/tests/unit/test_depth_image.py b/rerun_py/tests/unit/test_depth_image.py index 3413901fc401..d6f58a02d590 100644 --- a/rerun_py/tests/unit/test_depth_image.py +++ b/rerun_py/tests/unit/test_depth_image.py @@ -13,7 +13,6 @@ rng = np.random.default_rng(12345) RANDOM_IMAGE_SOURCE = rng.uniform(0.0, 1.0, (10, 20)) - IMAGE_INPUTS: list[Any] = [ RANDOM_IMAGE_SOURCE, RANDOM_IMAGE_SOURCE, @@ -42,16 +41,16 @@ def test_depth_image() -> None: ) arch = rr.DepthImage(img, meter=meter, depth_range=depth_range) - assert arch.buffer == rr.components.ImageBufferBatch._optional(img.tobytes()) - assert arch.format == rr.components.ImageFormatBatch._optional( + assert arch.buffer == rr.components.ImageBufferBatch._converter(img.tobytes()) + assert arch.format == rr.components.ImageFormatBatch._converter( ImageFormat( width=img.shape[1], height=img.shape[0], channel_datatype=ChannelDatatype.from_np_dtype(img.dtype), ) ) - assert arch.meter == rr.components.DepthMeterBatch._optional(meter) - assert arch.depth_range == rr.components.ValueRangeBatch._optional(depth_range) + assert arch.meter == rr.components.DepthMeterBatch._converter(meter) + assert arch.depth_range == rr.components.ValueRangeBatch._converter(depth_range) GOOD_IMAGE_INPUTS: list[Any] = [ diff --git a/rerun_py/tests/unit/test_ellipsoids3d.py b/rerun_py/tests/unit/test_ellipsoids3d.py index d500b3ea5c26..b7542a852248 100644 --- a/rerun_py/tests/unit/test_ellipsoids3d.py +++ b/rerun_py/tests/unit/test_ellipsoids3d.py @@ -113,6 +113,6 @@ def test_ellipsoids() -> None: assert arch.quaternions == quaternions_expected(quaternions, PoseRotationQuatBatch) assert arch.colors == colors_expected(colors) assert arch.line_radii == radii_expected(line_radii) - assert arch.fill_mode == rr.components.FillModeBatch._optional(fill_mode) + assert arch.fill_mode == rr.components.FillModeBatch._converter(fill_mode) assert arch.labels == labels_expected(labels) assert arch.class_ids == class_ids_expected(class_ids) diff --git a/rerun_py/tests/unit/test_exceptions.py b/rerun_py/tests/unit/test_exceptions.py index 3ffd72d896c8..e0d607825454 100644 --- a/rerun_py/tests/unit/test_exceptions.py +++ b/rerun_py/tests/unit/test_exceptions.py @@ -143,8 +143,8 @@ def test_bad_components() -> None: with pytest.warns(RerunWarning) as warnings: points = rr.Points3D(positions=[1, 2, 3], colors="RED") assert len(warnings) == 1 - assert len(points.positions) == 1 - assert len(points.colors) == 0 # type: ignore[arg-type] + assert points.positions is not None and len(points.positions) == 1 + assert points.colors is not None and len(points.colors) == 0 rr.set_strict_mode(True) with pytest.raises(ValueError): diff --git a/rerun_py/tests/unit/test_geo_line_strings.py b/rerun_py/tests/unit/test_geo_line_strings.py index bd755aeca8f9..be2c728fa590 100644 --- a/rerun_py/tests/unit/test_geo_line_strings.py +++ b/rerun_py/tests/unit/test_geo_line_strings.py @@ -108,7 +108,7 @@ def test_geo_line_strings_single_line() -> None: # Regression test for #3643 # Single line string can be passed and is not interpreted as a batch of zero-sized line strings. reference = rr.GeoLineStrings(lat_lon=[rr.components.GeoLineString(lat_lon=[[0, 0], [1, 1]])]) - assert len(reference.line_strings) == 1 + assert reference.line_strings is not None and len(reference.line_strings) == 1 assert reference == rr.GeoLineStrings(lat_lon=rr.components.GeoLineString(lat_lon=[[0, 0], [1, 1]])) assert reference == rr.GeoLineStrings(lat_lon=[[[0, 0], [1, 1]]]) assert reference == rr.GeoLineStrings(lat_lon=[[0, 0], [1, 1]]) diff --git a/rerun_py/tests/unit/test_image_encoded.py b/rerun_py/tests/unit/test_image_encoded.py index d74212f46211..9da3cd1fb6a4 100644 --- a/rerun_py/tests/unit/test_image_encoded.py +++ b/rerun_py/tests/unit/test_image_encoded.py @@ -153,6 +153,7 @@ def bgr2nv12(bgr: cv2.typing.MatLike) -> cv2.typing.MatLike: assert len(warnings) == 1 assert type(img) is rr.Image + assert img.format is not None image_format_arrow = img.format.as_arrow_array()[0].as_py() diff --git a/rerun_py/tests/unit/test_instance_pose3d.py b/rerun_py/tests/unit/test_instance_pose3d.py index 8e2ed1c32ee6..0334c48b8653 100644 --- a/rerun_py/tests/unit/test_instance_pose3d.py +++ b/rerun_py/tests/unit/test_instance_pose3d.py @@ -77,8 +77,8 @@ def test_instance_poses3d() -> None: ) print(f"{arch}\n") - assert arch.translations == rr.components.PoseTranslation3DBatch._optional(translations) - assert arch.rotation_axis_angles == rr.components.PoseRotationAxisAngleBatch._optional(rotation_axis_angles) - assert arch.quaternions == rr.components.PoseRotationQuatBatch._optional(quaternions) - assert arch.scales == rr.components.PoseScale3DBatch._optional(scales) - assert arch.mat3x3 == rr.components.PoseTransformMat3x3Batch._optional(mat3x3) + assert arch.translations == rr.components.PoseTranslation3DBatch._converter(translations) + assert arch.rotation_axis_angles == rr.components.PoseRotationAxisAngleBatch._converter(rotation_axis_angles) + assert arch.quaternions == rr.components.PoseRotationQuatBatch._converter(quaternions) + assert arch.scales == rr.components.PoseScale3DBatch._converter(scales) + assert arch.mat3x3 == rr.components.PoseTransformMat3x3Batch._converter(mat3x3) diff --git a/rerun_py/tests/unit/test_line_strips2d.py b/rerun_py/tests/unit/test_line_strips2d.py index 6dab70773765..1747c0d35551 100644 --- a/rerun_py/tests/unit/test_line_strips2d.py +++ b/rerun_py/tests/unit/test_line_strips2d.py @@ -135,7 +135,7 @@ def test_single_line_strip2d() -> None: # Regression test for #3643 # Single linestrip can be passed and is not interpreted as batch of zero sized line strips. reference = rr.LineStrips2D([rr.components.LineStrip2D([[0, 0], [1, 1]])]) - assert len(reference.strips) == 1 + assert reference.strips is not None and len(reference.strips) == 1 assert reference == rr.LineStrips2D(rr.components.LineStrip2D([[0, 0], [1, 1]])) assert reference == rr.LineStrips2D([[[0, 0], [1, 1]]]) assert reference == rr.LineStrips2D([[0, 0], [1, 1]]) diff --git a/rerun_py/tests/unit/test_line_strips3d.py b/rerun_py/tests/unit/test_line_strips3d.py index 97d82cd6c8c5..8e7ab6bd510a 100644 --- a/rerun_py/tests/unit/test_line_strips3d.py +++ b/rerun_py/tests/unit/test_line_strips3d.py @@ -30,22 +30,24 @@ [], np.array([]), [ - [[0, 0, 2], [1, 0, 2], [1, 1, 2], (0, 1, 2)], # type: ignore[list-item] + [[0, 0, 2], [1, 0, 2], [1, 1, 2], (0, 1, 2)], # type: ignore[list-item] [[0, 0, 0], [0, 0, 1], [1, 0, 0], (1, 0, 1), - [1, 1, 0], (1, 1, 1), [0, 1, 0], (0, 1, 1)], # type: ignore[list-item] + [1, 1, 0], (1, 1, 1), [0, 1, 0], (0, 1, 1)], # type: ignore[list-item] ], [ - [Vec3D([0, 0, 2]), (1, 0, 2), [1, 1, 2], (0, 1, 2)], # type: ignore[list-item] + [Vec3D([0, 0, 2]), (1, 0, 2), [1, 1, 2], (0, 1, 2)], # type: ignore[list-item] [Vec3D([0, 0, 0]), (0, 0, 1), [1, 0, 0], (1, 0, 1), - [1, 1, 0], (1, 1, 1), [0, 1, 0], (0, 1, 1)], # type: ignore[list-item] + [1, 1, 0], (1, 1, 1), [0, 1, 0], (0, 1, 1)], # type: ignore[list-item] ], [ np.array([([0, 0, 2]), (1, 0, 2), [1, 1, 2], (0, 1, 2)], dtype=np.float32), - np.array([([0, 0, 0]), (0, 0, 1), [1, 0, 0], (1, 0, 1), [1, 1, 0], (1, 1, 1), [0, 1, 0], (0, 1, 1)], dtype=np.float32), # noqa + np.array([([0, 0, 0]), (0, 0, 1), [1, 0, 0], (1, 0, 1), [1, 1, 0], (1, 1, 1), [0, 1, 0], (0, 1, 1)], + dtype=np.float32), # noqa ], [ torch.tensor([([0, 0, 2]), (1, 0, 2), [1, 1, 2], (0, 1, 2)], dtype=torch.float32), - torch.tensor([([0, 0, 0]), (0, 0, 1), [1, 0, 0], (1, 0, 1), [1, 1, 0], (1, 1, 1), [0, 1, 0], (0, 1, 1)], dtype=torch.float32), # noqa + torch.tensor([([0, 0, 0]), (0, 0, 1), [1, 0, 0], (1, 0, 1), [1, 1, 0], (1, 1, 1), [0, 1, 0], (0, 1, 1)], + dtype=torch.float32), # noqa ], # NOTE: Not legal -- non-homogeneous. # np.array([ @@ -53,6 +55,8 @@ # [([0, 0, 0]), [0, 0, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1], [0, 1, 0], [0, 1, 1]], # ]), ] + + # fmt: on @@ -141,7 +145,7 @@ def test_single_line_strip2d() -> None: # Regression test for #3643 # Single linestrip can be passed and is not interpreted as batch of zero sized line strips. reference = rr.LineStrips3D([rr.components.LineStrip3D([[0, 0, 0], [1, 1, 1]])]) - assert len(reference.strips) == 1 + assert reference.strips is not None and len(reference.strips) == 1 assert reference == rr.LineStrips3D(rr.components.LineStrip3D([[0, 0, 0], [1, 1, 1]])) assert reference == rr.LineStrips3D([[[0, 0, 0], [1, 1, 1]]]) assert reference == rr.LineStrips3D([[0, 0, 0], [1, 1, 1]]) diff --git a/rerun_py/tests/unit/test_mesh3d.py b/rerun_py/tests/unit/test_mesh3d.py index 475b0739b193..9bcad5c0307d 100644 --- a/rerun_py/tests/unit/test_mesh3d.py +++ b/rerun_py/tests/unit/test_mesh3d.py @@ -39,7 +39,7 @@ def albedo_factor_expected(obj: Any) -> Any: expected = none_empty_or_value(obj, Rgba32(0xAA0000CC)) - return AlbedoFactorBatch._optional(expected) + return AlbedoFactorBatch._converter(expected) def test_mesh3d() -> None: diff --git a/rerun_py/tests/unit/test_pinhole.py b/rerun_py/tests/unit/test_pinhole.py index 94a29ecdc074..cc85bb49d54d 100644 --- a/rerun_py/tests/unit/test_pinhole.py +++ b/rerun_py/tests/unit/test_pinhole.py @@ -37,9 +37,9 @@ def test_pinhole() -> None: arch = rr.Pinhole(image_from_camera=image_from_camera, resolution=resolution, camera_xyz=camera_xyz) print(f"{arch}\n") - assert arch.image_from_camera == PinholeProjectionBatch._optional([1, 2, 3, 4, 5, 6, 7, 8, 9]) - assert arch.resolution == ResolutionBatch._optional([1, 2] if resolution is not None else None) - assert arch.camera_xyz == ViewCoordinatesBatch._optional( + assert arch.image_from_camera == PinholeProjectionBatch._converter([1, 2, 3, 4, 5, 6, 7, 8, 9]) + assert arch.resolution == ResolutionBatch._converter([1, 2] if resolution is not None else None) + assert arch.camera_xyz == ViewCoordinatesBatch._converter( rr.components.ViewCoordinates.RDF if camera_xyz is not None else None ) diff --git a/rerun_py/tests/unit/test_plot_legend.py b/rerun_py/tests/unit/test_plot_legend.py index 13ea87868abb..3e0563068e1d 100644 --- a/rerun_py/tests/unit/test_plot_legend.py +++ b/rerun_py/tests/unit/test_plot_legend.py @@ -45,7 +45,7 @@ def test_scalar_axis() -> None: ) print(f"{arch}\n") - assert arch.corner == blueprint_components.Corner2DBatch._optional( + assert arch.corner == blueprint_components.Corner2DBatch._converter( none_empty_or_value(corner, rrb.Corner2D.LeftTop) ) - assert arch.visible == blueprint_components.VisibleBatch._optional(none_empty_or_value(visible, True)) + assert arch.visible == blueprint_components.VisibleBatch._converter(none_empty_or_value(visible, True)) diff --git a/rerun_py/tests/unit/test_scalar_axis.py b/rerun_py/tests/unit/test_scalar_axis.py index 7f14ba43d94e..a3ff7dad6f69 100644 --- a/rerun_py/tests/unit/test_scalar_axis.py +++ b/rerun_py/tests/unit/test_scalar_axis.py @@ -47,5 +47,5 @@ def test_scalar_axis() -> None: ) print(f"{arch}\n") - assert arch.range == rr.components.Range1DBatch._optional(none_empty_or_value(range, [42.1337, 1337.42])) - assert arch.zoom_lock == rrb.components.LockRangeDuringZoomBatch._optional(zoom_lock) + assert arch.range == rr.components.Range1DBatch._converter(none_empty_or_value(range, [42.1337, 1337.42])) + assert arch.zoom_lock == rrb.components.LockRangeDuringZoomBatch._converter(zoom_lock) diff --git a/rerun_py/tests/unit/test_series_styles.py b/rerun_py/tests/unit/test_series_styles.py index 99239587f291..0ed54b7394e2 100644 --- a/rerun_py/tests/unit/test_series_styles.py +++ b/rerun_py/tests/unit/test_series_styles.py @@ -28,11 +28,11 @@ def test_line_series() -> None: for input in inputs: if input.color is not None: - assert input.color == ColorBatch._optional([Color([255, 0, 0])]) + assert input.color == ColorBatch._converter([Color([255, 0, 0])]) if input.width is not None: - assert input.width == StrokeWidthBatch._optional([StrokeWidth(2.0)]) + assert input.width == StrokeWidthBatch._converter([StrokeWidth(2.0)]) if input.name is not None: - assert input.name == NameBatch._optional([Name("my plot")]) + assert input.name == NameBatch._converter([Name("my plot")]) def test_point_series() -> None: @@ -49,13 +49,13 @@ def test_point_series() -> None: for input in inputs: if input.color is not None: - assert input.color == ColorBatch._optional([Color([255, 0, 0])]) + assert input.color == ColorBatch._converter([Color([255, 0, 0])]) if input.marker_size is not None: - assert input.marker_size == MarkerSizeBatch._optional([MarkerSize(2.0)]) + assert input.marker_size == MarkerSizeBatch._converter([MarkerSize(2.0)]) if input.marker is not None: - assert input.marker == MarkerShapeBatch._optional([MarkerShape.Diamond]) + assert input.marker == MarkerShapeBatch._converter([MarkerShape.Diamond]) if input.name is not None: - assert input.name == NameBatch._optional([Name("my plot")]) + assert input.name == NameBatch._converter([Name("my plot")]) if __name__ == "__main__": diff --git a/rerun_py/tests/unit/test_tensor_slice_selection.py b/rerun_py/tests/unit/test_tensor_slice_selection.py index 3b0cff29f2e1..b18e06713547 100644 --- a/rerun_py/tests/unit/test_tensor_slice_selection.py +++ b/rerun_py/tests/unit/test_tensor_slice_selection.py @@ -71,15 +71,15 @@ def test_tensor_slice_selection() -> None: ) print(f"{arch}\n") - assert arch.width == rr.components.TensorWidthDimensionBatch._optional( + assert arch.width == rr.components.TensorWidthDimensionBatch._converter( none_empty_or_value(width, rr.components.TensorWidthDimension(dimension=2, invert=False)) ) - assert arch.height == rr.components.TensorHeightDimensionBatch._optional( + assert arch.height == rr.components.TensorHeightDimensionBatch._converter( none_empty_or_value(height, rr.components.TensorHeightDimension(dimension=3, invert=False)) ) - assert arch.indices == rr.components.TensorDimensionIndexSelectionBatch._optional( + assert arch.indices == rr.components.TensorDimensionIndexSelectionBatch._converter( none_empty_or_value(indices, indices_arrays[0]) ) - assert arch.slider == rrb.components.TensorDimensionIndexSliderBatch._optional( + assert arch.slider == rrb.components.TensorDimensionIndexSliderBatch._converter( none_empty_or_value(slider, [1, 2, 3]) ) diff --git a/rerun_py/tests/unit/test_transform3d.py b/rerun_py/tests/unit/test_transform3d.py index bebdf2e4ad34..4afa024102a3 100644 --- a/rerun_py/tests/unit/test_transform3d.py +++ b/rerun_py/tests/unit/test_transform3d.py @@ -125,25 +125,25 @@ def test_transform3d() -> None: ) print(f"{arch}\n") - assert arch.scale == rr.components.Scale3DBatch._required( + assert arch.scale == rr.components.Scale3DBatch( none_empty_or_value(scale, rr.components.Scale3D(scale)) # type: ignore[arg-type] ) - assert arch.rotation_axis_angle == rr.components.RotationAxisAngleBatch._required( + assert arch.rotation_axis_angle == rr.components.RotationAxisAngleBatch( none_empty_or_value(rotation_axis_angle, rr.components.RotationAxisAngle([1, 2, 3], Angle(deg=10))) ) - assert arch.quaternion == rr.components.RotationQuatBatch._required( + assert arch.quaternion == rr.components.RotationQuatBatch( none_empty_or_value(quaternion, rr.components.RotationQuat(xyzw=[1, 2, 3, 4])) ) - assert arch.translation == rr.components.Translation3DBatch._required( + assert arch.translation == rr.components.Translation3DBatch( none_empty_or_value(translation, rr.components.Translation3D([1, 2, 3])) ) - assert arch.mat3x3 == rr.components.TransformMat3x3Batch._required( + assert arch.mat3x3 == rr.components.TransformMat3x3Batch( none_empty_or_value(mat3x3, rr.components.TransformMat3x3([[1, 2, 3], [4, 5, 6], [7, 8, 9]])) ) - assert arch.axis_length == rr.components.AxisLengthBatch._required( + assert arch.axis_length == rr.components.AxisLengthBatch( none_empty_or_value(axis_length, rr.components.AxisLength(1.0)) ) - assert arch.relation == rr.components.TransformRelationBatch._required(relation) + assert arch.relation == rr.components.TransformRelationBatch(relation) def test_transform_mat3x3_snippets() -> None: diff --git a/rerun_py/tests/unit/test_uuid.py b/rerun_py/tests/unit/test_uuid.py index 61166704b1b2..f4a9fc98a9a8 100644 --- a/rerun_py/tests/unit/test_uuid.py +++ b/rerun_py/tests/unit/test_uuid.py @@ -11,7 +11,7 @@ def uuids_expected(obj: Any) -> Any: expected = none_empty_or_value(obj, uuids_arrays[-1]) - return UuidBatch._optional(expected) + return UuidBatch._converter(expected) def test_uuid() -> None: diff --git a/rerun_py/tests/unit/test_view_blueprint.py b/rerun_py/tests/unit/test_view_blueprint.py index ae517f6b3240..cd97eb2bcfa1 100644 --- a/rerun_py/tests/unit/test_view_blueprint.py +++ b/rerun_py/tests/unit/test_view_blueprint.py @@ -55,6 +55,6 @@ def test_view_blueprint() -> None: # Equality checks on some of these are a bit silly, but at least they test out that the serialization code runs without problems. assert arch.class_identifier == ViewClassBatch("3D") - assert arch.display_name == NameBatch._optional(none_empty_or_value(display_name, "3D view")) - assert arch.space_origin == ViewOriginBatch._optional(none_empty_or_value(space_origin, "/robot/arm")) - assert arch.visible == VisibleBatch._optional(none_empty_or_value(visible, False)) + assert arch.display_name == NameBatch._converter(none_empty_or_value(display_name, "3D view")) + assert arch.space_origin == ViewOriginBatch._converter(none_empty_or_value(space_origin, "/robot/arm")) + assert arch.visible == VisibleBatch._converter(none_empty_or_value(visible, False)) diff --git a/rerun_py/tests/unit/test_view_coordinates.py b/rerun_py/tests/unit/test_view_coordinates.py index d8788276c4a3..86d71a95fc13 100644 --- a/rerun_py/tests/unit/test_view_coordinates.py +++ b/rerun_py/tests/unit/test_view_coordinates.py @@ -17,8 +17,7 @@ def view_coordinates_expected(obj: Any) -> rrc.ViewCoordinatesBatch: return rrc.ViewCoordinatesBatch(expected) -VIEW_COORDINATES_INPUTS: list[ViewCoordinatesArrayLike | None] = [ - None, +VIEW_COORDINATES_INPUTS: list[ViewCoordinatesArrayLike] = [ rrc.ViewCoordinates([ rrc.ViewCoordinates.ViewDir.Right, rrc.ViewCoordinates.ViewDir.Down, diff --git a/rerun_py/tests/unit/test_viewport_blueprint.py b/rerun_py/tests/unit/test_viewport_blueprint.py index bd05fdfac912..84d0fe4b4d14 100644 --- a/rerun_py/tests/unit/test_viewport_blueprint.py +++ b/rerun_py/tests/unit/test_viewport_blueprint.py @@ -76,10 +76,10 @@ def test_viewport_blueprint() -> None: ) print(f"{arch}\n") - assert arch.root_container == RootContainerBatch._optional(none_empty_or_value(root_container, uuid_bytes0)) - assert arch.maximized == ViewMaximizedBatch._optional(none_empty_or_value(maximized, uuid_bytes1)) - assert arch.auto_layout == AutoLayoutBatch._optional(none_empty_or_value(auto_layout, True)) - assert arch.auto_views == AutoViewsBatch._optional(none_empty_or_value(auto_views, False)) - assert arch.past_viewer_recommendations == ViewerRecommendationHashBatch._optional( + assert arch.root_container == RootContainerBatch._converter(none_empty_or_value(root_container, uuid_bytes0)) + assert arch.maximized == ViewMaximizedBatch._converter(none_empty_or_value(maximized, uuid_bytes1)) + assert arch.auto_layout == AutoLayoutBatch._converter(none_empty_or_value(auto_layout, True)) + assert arch.auto_views == AutoViewsBatch._converter(none_empty_or_value(auto_views, False)) + assert arch.past_viewer_recommendations == ViewerRecommendationHashBatch._converter( none_empty_or_value(past_viewer_recommendations, [123, 321]) ) From 6e84980518f6f2a5f01907c65cd1dbdda7d8cae7 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 16 Jan 2025 09:15:07 +0100 Subject: [PATCH 45/57] Port all rust blueprint archetypes to eager serialization & update API (#8697) ### Related * Part of https://github.com/rerun-io/rerun/issues/7245 ### What What it says on the tin! Commit by commit - first commit does all the easy ones, followed by the trickier ones (just two) Tested by... * mess with tensor * mess with time series in plots example * run `docs/snippets/all/views/timeseries.py` snippet (uses explicit time series) * [x] full check passed --- .../blueprint/archetypes/dataframe_query.fbs | 1 + .../blueprint/archetypes/force_center.fbs | 1 + .../archetypes/force_collision_radius.fbs | 1 + .../rerun/blueprint/archetypes/force_link.fbs | 1 + .../blueprint/archetypes/force_many_body.fbs | 1 + .../blueprint/archetypes/force_position.fbs | 1 + .../blueprint/archetypes/line_grid3d.fbs | 1 + .../blueprint/archetypes/map_background.fbs | 1 + .../rerun/blueprint/archetypes/map_zoom.fbs | 1 + .../blueprint/archetypes/near_clip_plane.fbs | 4 +- .../blueprint/archetypes/panel_blueprint.fbs | 1 + .../blueprint/archetypes/plot_legend.fbs | 1 + .../blueprint/archetypes/scalar_axis.fbs | 1 + .../archetypes/tensor_scalar_mapping.fbs | 1 + .../archetypes/tensor_slice_selection.fbs | 4 +- .../blueprint/archetypes/tensor_view_fit.fbs | 1 + .../blueprint/archetypes/view_blueprint.fbs | 1 + .../blueprint/archetypes/view_contents.fbs | 1 + .../archetypes/viewport_blueprint.fbs | 1 + .../archetypes/visible_time_ranges.fbs | 1 + .../blueprint/archetypes/visual_bounds2d.fbs | 4 +- .../blueprint/archetypes/dataframe_query.rs | 188 +++++++--------- .../src/blueprint/archetypes/force_center.rs | 86 ++++---- .../archetypes/force_collision_radius.rs | 118 +++++----- .../src/blueprint/archetypes/force_link.rs | 118 +++++----- .../blueprint/archetypes/force_many_body.rs | 86 ++++---- .../blueprint/archetypes/force_position.rs | 116 ++++------ .../src/blueprint/archetypes/line_grid3d.rs | 179 ++++++--------- .../blueprint/archetypes/map_background.rs | 77 ++++--- .../src/blueprint/archetypes/map_zoom.rs | 76 ++++--- .../re_types/src/blueprint/archetypes/mod.rs | 1 - .../blueprint/archetypes/near_clip_plane.rs | 83 ++++--- .../blueprint/archetypes/panel_blueprint.rs | 61 +++--- .../src/blueprint/archetypes/plot_legend.rs | 84 ++++--- .../src/blueprint/archetypes/scalar_axis.rs | 86 ++++---- .../archetypes/tensor_scalar_mapping.rs | 116 +++++----- .../archetypes/tensor_slice_selection.rs | 152 +++++-------- .../blueprint/archetypes/tensor_view_fit.rs | 61 +++--- .../blueprint/archetypes/view_blueprint.rs | 170 +++++++-------- .../src/blueprint/archetypes/view_contents.rs | 74 ++++--- .../archetypes/viewport_blueprint.rs | 206 +++++++----------- .../archetypes/visible_time_ranges.rs | 74 ++++--- .../archetypes/visible_time_ranges_ext.rs | 38 ---- .../src/visible_time_range_ui.rs | 29 ++- .../re_view_tensor/src/dimension_mapping.rs | 77 ++++--- .../src/tensor_dimension_mapper.rs | 20 +- .../re_view_tensor/src/tensor_slice_to_gpu.rs | 3 +- .../viewer/re_view_tensor/src/view_class.rs | 29 +-- .../viewer/re_viewport_blueprint/src/view.rs | 26 +-- .../src/viewport_blueprint.rs | 18 +- 50 files changed, 1108 insertions(+), 1374 deletions(-) delete mode 100644 crates/store/re_types/src/blueprint/archetypes/visible_time_ranges_ext.rs diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/dataframe_query.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/dataframe_query.fbs index 5cdda33c14a4..03cd66ec9a49 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/dataframe_query.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/dataframe_query.fbs @@ -3,6 +3,7 @@ namespace rerun.blueprint.archetypes; /// The query for the dataframe view. table DataframeQuery ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint" ) { // --- Optional --- diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_center.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_center.fbs index a574b9c696c0..a84cb467afa4 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_center.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_center.fbs @@ -2,6 +2,7 @@ namespace rerun.blueprint.archetypes; /// Tries to move the center of mass of the graph to the origin. struct ForceCenter ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint" ) { /// Whether the center force is enabled. diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_collision_radius.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_collision_radius.fbs index f4a4e760b59a..e234cd05b08a 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_collision_radius.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_collision_radius.fbs @@ -2,6 +2,7 @@ namespace rerun.blueprint.archetypes; /// Resolves collisions between the bounding circles, according to the radius of the nodes. struct ForceCollisionRadius ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint" ) { /// Whether the collision force is enabled. diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_link.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_link.fbs index 2d34b1c936ae..addd9d3a2632 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_link.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_link.fbs @@ -2,6 +2,7 @@ namespace rerun.blueprint.archetypes; /// Aims to achieve a target distance between two nodes that are connected by an edge. struct ForceLink ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint" ) { /// Whether the link force is enabled. diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_many_body.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_many_body.fbs index abc576912fca..3507c736c588 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_many_body.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_many_body.fbs @@ -4,6 +4,7 @@ namespace rerun.blueprint.archetypes; /// /// If `strength` is smaller than 0, it pushes nodes apart, if it is larger than 0 it pulls them together. struct ForceManyBody ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint" ) { /// Whether the many body force is enabled. diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_position.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_position.fbs index 6689b95b48d7..2456ba44e5a7 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_position.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/force_position.fbs @@ -2,6 +2,7 @@ namespace rerun.blueprint.archetypes; /// Similar to gravity, this force pulls nodes towards a specific position. struct ForcePosition ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint" ) { /// Whether the position force is enabled. diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid3d.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid3d.fbs index 3143471766f1..e974d87430b7 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid3d.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/line_grid3d.fbs @@ -2,6 +2,7 @@ namespace rerun.blueprint.archetypes; /// Configuration for the 3D line grid. table LineGrid3D ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint" ) { /// Whether the grid is visible. diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/map_background.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/map_background.fbs index 1a8184ff6b13..0a2b93e965b8 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/map_background.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/map_background.fbs @@ -3,6 +3,7 @@ namespace rerun.blueprint.archetypes; /// Configuration for the background map of the map view. table MapBackground ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint", "attr.python.aliases": "blueprint_components.MapProviderLike" ) { diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/map_zoom.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/map_zoom.fbs index 28acc6252c32..40cba26edf83 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/map_zoom.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/map_zoom.fbs @@ -4,6 +4,7 @@ namespace rerun.blueprint.archetypes; /// Configuration of the map view zoom level. //TODO(ab): Turn this archetype into `MapArea` and include a `center: LatLon` componnent or similar table MapZoom ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint", "attr.python.aliases": "datatypes.Float64Like" ) { diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/near_clip_plane.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/near_clip_plane.fbs index 9875dfde1004..5e77fc9006d5 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/near_clip_plane.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/near_clip_plane.fbs @@ -2,8 +2,8 @@ namespace rerun.blueprint.archetypes; /// Controls the distance to the near clip plane in 3D scene units. table NearClipPlane ( - "attr.rerun.scope": "blueprint", - "attr.rust.derive": "Copy" + "attr.rust.archetype_eager", + "attr.rerun.scope": "blueprint" ) { /// Controls the distance to the near clip plane in 3D scene units. /// diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/panel_blueprint.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/panel_blueprint.fbs index 28660dc25330..fe6ba781aebb 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/panel_blueprint.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/panel_blueprint.fbs @@ -4,6 +4,7 @@ namespace rerun.blueprint.archetypes; /// Shared state for the 3 collapsible panels. table PanelBlueprint ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint", "attr.rust.derive": "Default" ) { diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/plot_legend.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/plot_legend.fbs index e9f409e1fd31..30c60b3c07ee 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/plot_legend.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/plot_legend.fbs @@ -5,6 +5,7 @@ namespace rerun.blueprint.archetypes; /// Configuration for the legend of a plot. table PlotLegend ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint", "attr.rust.derive": "Default", "attr.python.aliases": "blueprint_components.Corner2D" diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/scalar_axis.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/scalar_axis.fbs index 0d3f5e645978..d7a3657ed9c4 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/scalar_axis.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/scalar_axis.fbs @@ -5,6 +5,7 @@ namespace rerun.blueprint.archetypes; /// Configuration for the scalar axis of a plot. table ScalarAxis ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint", "attr.rust.derive": "Default" ) { diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/tensor_scalar_mapping.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/tensor_scalar_mapping.fbs index ff772e6abdfc..0195e2b9bc2c 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/tensor_scalar_mapping.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/tensor_scalar_mapping.fbs @@ -2,6 +2,7 @@ namespace rerun.blueprint.archetypes; /// Configures how tensor scalars are mapped to color. table TensorScalarMapping ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint", "attr.rust.derive": "Default" ) { diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/tensor_slice_selection.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/tensor_slice_selection.fbs index 0928b5fe28fb..8619811df846 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/tensor_slice_selection.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/tensor_slice_selection.fbs @@ -2,8 +2,8 @@ namespace rerun.blueprint.archetypes; /// Specifies a 2D slice of a tensor. table TensorSliceSelection ( - "attr.rerun.scope": "blueprint", - "attr.rust.derive": "Default, Hash, PartialEq, Eq" + "attr.rust.archetype_eager", + "attr.rerun.scope": "blueprint" ) { /// Which dimension to map to width. /// diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/tensor_view_fit.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/tensor_view_fit.fbs index 1848284ee426..ca2591d487a6 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/tensor_view_fit.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/tensor_view_fit.fbs @@ -2,6 +2,7 @@ namespace rerun.blueprint.archetypes; /// Configures how a selected tensor slice is shown on screen. table TensorViewFit ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint", "attr.rust.derive": "Default", "attr.python.aliases": "blueprint_components.ViewFitLike" diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/view_blueprint.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/view_blueprint.fbs index 87b258633e94..6eba591e3fc6 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/view_blueprint.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/view_blueprint.fbs @@ -4,6 +4,7 @@ namespace rerun.blueprint.archetypes; /// The description of a single view. table ViewBlueprint ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint" ) { // --- Required --- diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/view_contents.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/view_contents.fbs index 2c9509dee26b..091bb68798b0 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/view_contents.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/view_contents.fbs @@ -41,6 +41,7 @@ namespace rerun.blueprint.archetypes; /// The last rule matching `/world` is `- /world`, so it is excluded. /// The last rule matching `/world/house` is `+ /world/**`, so it is included. table ViewContents ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint", "attr.rust.derive": "Default" ) { diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/viewport_blueprint.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/viewport_blueprint.fbs index dc0cfff65e0f..e8a1f9753906 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/viewport_blueprint.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/viewport_blueprint.fbs @@ -4,6 +4,7 @@ namespace rerun.blueprint.archetypes; /// The top-level description of the viewport. table ViewportBlueprint ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint", "attr.rust.derive": "Default" ) { diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/visible_time_ranges.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/visible_time_ranges.fbs index afc050fadae1..3706c4b5d9fe 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/visible_time_ranges.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/visible_time_ranges.fbs @@ -12,6 +12,7 @@ namespace rerun.blueprint.archetypes; /// - For time series views, the default is to show the entire timeline. /// - For any other view, the default is to apply latest-at semantics. table VisibleTimeRanges ( + "attr.rust.archetype_eager", "attr.rerun.scope": "blueprint", "attr.rust.derive": "Default", "attr.python.aliases": "datatypes.VisibleTimeRangeLike, Sequence[datatypes.VisibleTimeRangeLike]" diff --git a/crates/store/re_types/definitions/rerun/blueprint/archetypes/visual_bounds2d.fbs b/crates/store/re_types/definitions/rerun/blueprint/archetypes/visual_bounds2d.fbs index ea210ab47b96..b9ba3e9e5d7b 100644 --- a/crates/store/re_types/definitions/rerun/blueprint/archetypes/visual_bounds2d.fbs +++ b/crates/store/re_types/definitions/rerun/blueprint/archetypes/visual_bounds2d.fbs @@ -8,8 +8,8 @@ namespace rerun.blueprint.archetypes; /// If no visual bounds are set, it will be determined automatically, /// based on the bounding-box of the data or other camera information present in the view. table VisualBounds2D ( - "attr.rerun.scope": "blueprint", - "attr.rust.archetype_eager": "" + "attr.rust.archetype_eager", + "attr.rerun.scope": "blueprint" ) { /// Controls the visible range of a 2D view. /// diff --git a/crates/store/re_types/src/blueprint/archetypes/dataframe_query.rs b/crates/store/re_types/src/blueprint/archetypes/dataframe_query.rs index 271e7e0e7936..ec77a32087d3 100644 --- a/crates/store/re_types/src/blueprint/archetypes/dataframe_query.rs +++ b/crates/store/re_types/src/blueprint/archetypes/dataframe_query.rs @@ -19,26 +19,26 @@ use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: The query for the dataframe view. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct DataframeQuery { /// The timeline for this query. /// /// If unset, the timeline currently active on the time panel is used. - pub timeline: Option, + pub timeline: Option, /// If provided, only rows whose timestamp is within this range will be shown. /// /// Note: will be unset as soon as `timeline` is changed. - pub filter_by_range: Option, + pub filter_by_range: Option, /// If provided, only show rows which contains a logged event for the specified component. - pub filter_is_not_null: Option, + pub filter_is_not_null: Option, /// Should empty cells be filled with latest-at queries? - pub apply_latest_at: Option, + pub apply_latest_at: Option, /// Selected columns. If unset, all columns are selected. - pub select: Option, + pub select: Option, } impl DataframeQuery { @@ -186,54 +186,27 @@ impl ::re_types_core::Archetype for DataframeQuery { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let timeline = if let Some(array) = arrays_by_descr.get(&Self::descriptor_timeline()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.DataframeQuery#timeline")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let filter_by_range = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_filter_by_range()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.DataframeQuery#filter_by_range")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let filter_is_not_null = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_filter_is_not_null()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.DataframeQuery#filter_is_not_null")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let apply_latest_at = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_apply_latest_at()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.DataframeQuery#apply_latest_at")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let select = if let Some(array) = arrays_by_descr.get(&Self::descriptor_select()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.DataframeQuery#select")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let timeline = arrays_by_descr + .get(&Self::descriptor_timeline()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_timeline())); + let filter_by_range = arrays_by_descr + .get(&Self::descriptor_filter_by_range()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_filter_by_range()) + }); + let filter_is_not_null = arrays_by_descr + .get(&Self::descriptor_filter_is_not_null()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_filter_is_not_null()) + }); + let apply_latest_at = arrays_by_descr + .get(&Self::descriptor_apply_latest_at()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_apply_latest_at()) + }); + let select = arrays_by_descr + .get(&Self::descriptor_select()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_select())); Ok(Self { timeline, filter_by_range, @@ -245,51 +218,16 @@ impl ::re_types_core::Archetype for DataframeQuery { } impl ::re_types_core::AsComponents for DataframeQuery { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (self - .timeline - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_timeline()), - }), - (self - .filter_by_range - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_filter_by_range()), - }), - (self - .filter_is_not_null - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_filter_is_not_null()), - }), - (self - .apply_latest_at - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_apply_latest_at()), - }), - (self - .select - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_select()), - }), + Self::indicator().serialized(), + self.timeline.clone(), + self.filter_by_range.clone(), + self.filter_is_not_null.clone(), + self.apply_latest_at.clone(), + self.select.clone(), ] .into_iter() .flatten() @@ -312,6 +250,40 @@ impl DataframeQuery { } } + /// Update only some specific fields of a `DataframeQuery`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `DataframeQuery`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + timeline: Some(SerializedComponentBatch::new( + crate::blueprint::components::TimelineName::arrow_empty(), + Self::descriptor_timeline(), + )), + filter_by_range: Some(SerializedComponentBatch::new( + crate::blueprint::components::FilterByRange::arrow_empty(), + Self::descriptor_filter_by_range(), + )), + filter_is_not_null: Some(SerializedComponentBatch::new( + crate::blueprint::components::FilterIsNotNull::arrow_empty(), + Self::descriptor_filter_is_not_null(), + )), + apply_latest_at: Some(SerializedComponentBatch::new( + crate::blueprint::components::ApplyLatestAt::arrow_empty(), + Self::descriptor_apply_latest_at(), + )), + select: Some(SerializedComponentBatch::new( + crate::blueprint::components::SelectedColumns::arrow_empty(), + Self::descriptor_select(), + )), + } + } + /// The timeline for this query. /// /// If unset, the timeline currently active on the time panel is used. @@ -320,7 +292,7 @@ impl DataframeQuery { mut self, timeline: impl Into, ) -> Self { - self.timeline = Some(timeline.into()); + self.timeline = try_serialize_field(Self::descriptor_timeline(), [timeline]); self } @@ -332,7 +304,8 @@ impl DataframeQuery { mut self, filter_by_range: impl Into, ) -> Self { - self.filter_by_range = Some(filter_by_range.into()); + self.filter_by_range = + try_serialize_field(Self::descriptor_filter_by_range(), [filter_by_range]); self } @@ -342,7 +315,8 @@ impl DataframeQuery { mut self, filter_is_not_null: impl Into, ) -> Self { - self.filter_is_not_null = Some(filter_is_not_null.into()); + self.filter_is_not_null = + try_serialize_field(Self::descriptor_filter_is_not_null(), [filter_is_not_null]); self } @@ -352,7 +326,8 @@ impl DataframeQuery { mut self, apply_latest_at: impl Into, ) -> Self { - self.apply_latest_at = Some(apply_latest_at.into()); + self.apply_latest_at = + try_serialize_field(Self::descriptor_apply_latest_at(), [apply_latest_at]); self } @@ -362,7 +337,7 @@ impl DataframeQuery { mut self, select: impl Into, ) -> Self { - self.select = Some(select.into()); + self.select = try_serialize_field(Self::descriptor_select(), [select]); self } } @@ -376,13 +351,4 @@ impl ::re_byte_size::SizeBytes for DataframeQuery { + self.apply_latest_at.heap_size_bytes() + self.select.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/force_center.rs b/crates/store/re_types/src/blueprint/archetypes/force_center.rs index 79a0bbbe17bb..7b59245112c9 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_center.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_center.rs @@ -19,15 +19,15 @@ use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: Tries to move the center of mass of the graph to the origin. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct ForceCenter { /// Whether the center force is enabled. /// /// The center force tries to move the center of mass of the graph towards the origin. - pub enabled: Option, + pub enabled: Option, /// The strength of the force. - pub strength: Option, + pub strength: Option, } impl ForceCenter { @@ -139,50 +139,24 @@ impl ::re_types_core::Archetype for ForceCenter { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let enabled = if let Some(array) = arrays_by_descr.get(&Self::descriptor_enabled()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForceCenter#enabled")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let strength = if let Some(array) = arrays_by_descr.get(&Self::descriptor_strength()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForceCenter#strength")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let enabled = arrays_by_descr + .get(&Self::descriptor_enabled()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_enabled())); + let strength = arrays_by_descr + .get(&Self::descriptor_strength()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_strength())); Ok(Self { enabled, strength }) } } impl ::re_types_core::AsComponents for ForceCenter { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (self - .enabled - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_enabled()), - }), - (self - .strength - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_strength()), - }), + Self::indicator().serialized(), + self.enabled.clone(), + self.strength.clone(), ] .into_iter() .flatten() @@ -202,6 +176,28 @@ impl ForceCenter { } } + /// Update only some specific fields of a `ForceCenter`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `ForceCenter`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + enabled: Some(SerializedComponentBatch::new( + crate::blueprint::components::Enabled::arrow_empty(), + Self::descriptor_enabled(), + )), + strength: Some(SerializedComponentBatch::new( + crate::blueprint::components::ForceStrength::arrow_empty(), + Self::descriptor_strength(), + )), + } + } + /// Whether the center force is enabled. /// /// The center force tries to move the center of mass of the graph towards the origin. @@ -210,7 +206,7 @@ impl ForceCenter { mut self, enabled: impl Into, ) -> Self { - self.enabled = Some(enabled.into()); + self.enabled = try_serialize_field(Self::descriptor_enabled(), [enabled]); self } @@ -220,7 +216,7 @@ impl ForceCenter { mut self, strength: impl Into, ) -> Self { - self.strength = Some(strength.into()); + self.strength = try_serialize_field(Self::descriptor_strength(), [strength]); self } } @@ -230,10 +226,4 @@ impl ::re_byte_size::SizeBytes for ForceCenter { fn heap_size_bytes(&self) -> u64 { self.enabled.heap_size_bytes() + self.strength.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs b/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs index 809f2c4ab50b..227da89c2eca 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_collision_radius.rs @@ -19,20 +19,20 @@ use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: Resolves collisions between the bounding circles, according to the radius of the nodes. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct ForceCollisionRadius { /// Whether the collision force is enabled. /// /// The collision force resolves collisions between nodes based on the bounding circle defined by their radius. - pub enabled: Option, + pub enabled: Option, /// The strength of the force. - pub strength: Option, + pub strength: Option, /// Specifies how often this force should be applied per iteration. /// /// Increasing this parameter can lead to better results at the cost of longer computation time. - pub iterations: Option, + pub iterations: Option, } impl ForceCollisionRadius { @@ -157,33 +157,17 @@ impl ::re_types_core::Archetype for ForceCollisionRadius { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let enabled = if let Some(array) = arrays_by_descr.get(&Self::descriptor_enabled()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForceCollisionRadius#enabled")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let strength = if let Some(array) = arrays_by_descr.get(&Self::descriptor_strength()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForceCollisionRadius#strength")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let iterations = if let Some(array) = arrays_by_descr.get(&Self::descriptor_iterations()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForceCollisionRadius#iterations")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let enabled = arrays_by_descr + .get(&Self::descriptor_enabled()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_enabled())); + let strength = arrays_by_descr + .get(&Self::descriptor_strength()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_strength())); + let iterations = arrays_by_descr + .get(&Self::descriptor_iterations()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_iterations()) + }); Ok(Self { enabled, strength, @@ -193,35 +177,14 @@ impl ::re_types_core::Archetype for ForceCollisionRadius { } impl ::re_types_core::AsComponents for ForceCollisionRadius { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (self - .enabled - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_enabled()), - }), - (self - .strength - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_strength()), - }), - (self - .iterations - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_iterations()), - }), + Self::indicator().serialized(), + self.enabled.clone(), + self.strength.clone(), + self.iterations.clone(), ] .into_iter() .flatten() @@ -242,6 +205,32 @@ impl ForceCollisionRadius { } } + /// Update only some specific fields of a `ForceCollisionRadius`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `ForceCollisionRadius`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + enabled: Some(SerializedComponentBatch::new( + crate::blueprint::components::Enabled::arrow_empty(), + Self::descriptor_enabled(), + )), + strength: Some(SerializedComponentBatch::new( + crate::blueprint::components::ForceStrength::arrow_empty(), + Self::descriptor_strength(), + )), + iterations: Some(SerializedComponentBatch::new( + crate::blueprint::components::ForceIterations::arrow_empty(), + Self::descriptor_iterations(), + )), + } + } + /// Whether the collision force is enabled. /// /// The collision force resolves collisions between nodes based on the bounding circle defined by their radius. @@ -250,7 +239,7 @@ impl ForceCollisionRadius { mut self, enabled: impl Into, ) -> Self { - self.enabled = Some(enabled.into()); + self.enabled = try_serialize_field(Self::descriptor_enabled(), [enabled]); self } @@ -260,7 +249,7 @@ impl ForceCollisionRadius { mut self, strength: impl Into, ) -> Self { - self.strength = Some(strength.into()); + self.strength = try_serialize_field(Self::descriptor_strength(), [strength]); self } @@ -272,7 +261,7 @@ impl ForceCollisionRadius { mut self, iterations: impl Into, ) -> Self { - self.iterations = Some(iterations.into()); + self.iterations = try_serialize_field(Self::descriptor_iterations(), [iterations]); self } } @@ -284,11 +273,4 @@ impl ::re_byte_size::SizeBytes for ForceCollisionRadius { + self.strength.heap_size_bytes() + self.iterations.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/force_link.rs b/crates/store/re_types/src/blueprint/archetypes/force_link.rs index ed81ba18c7cf..b2b5dd1d045e 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_link.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_link.rs @@ -19,20 +19,20 @@ use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: Aims to achieve a target distance between two nodes that are connected by an edge. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct ForceLink { /// Whether the link force is enabled. /// /// The link force aims to achieve a target distance between two nodes that are connected by one ore more edges. - pub enabled: Option, + pub enabled: Option, /// The target distance between two nodes. - pub distance: Option, + pub distance: Option, /// Specifies how often this force should be applied per iteration. /// /// Increasing this parameter can lead to better results at the cost of longer computation time. - pub iterations: Option, + pub iterations: Option, } impl ForceLink { @@ -156,33 +156,17 @@ impl ::re_types_core::Archetype for ForceLink { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let enabled = if let Some(array) = arrays_by_descr.get(&Self::descriptor_enabled()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForceLink#enabled")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let distance = if let Some(array) = arrays_by_descr.get(&Self::descriptor_distance()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForceLink#distance")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let iterations = if let Some(array) = arrays_by_descr.get(&Self::descriptor_iterations()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForceLink#iterations")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let enabled = arrays_by_descr + .get(&Self::descriptor_enabled()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_enabled())); + let distance = arrays_by_descr + .get(&Self::descriptor_distance()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_distance())); + let iterations = arrays_by_descr + .get(&Self::descriptor_iterations()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_iterations()) + }); Ok(Self { enabled, distance, @@ -192,35 +176,14 @@ impl ::re_types_core::Archetype for ForceLink { } impl ::re_types_core::AsComponents for ForceLink { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (self - .enabled - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_enabled()), - }), - (self - .distance - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_distance()), - }), - (self - .iterations - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_iterations()), - }), + Self::indicator().serialized(), + self.enabled.clone(), + self.distance.clone(), + self.iterations.clone(), ] .into_iter() .flatten() @@ -241,6 +204,32 @@ impl ForceLink { } } + /// Update only some specific fields of a `ForceLink`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `ForceLink`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + enabled: Some(SerializedComponentBatch::new( + crate::blueprint::components::Enabled::arrow_empty(), + Self::descriptor_enabled(), + )), + distance: Some(SerializedComponentBatch::new( + crate::blueprint::components::ForceDistance::arrow_empty(), + Self::descriptor_distance(), + )), + iterations: Some(SerializedComponentBatch::new( + crate::blueprint::components::ForceIterations::arrow_empty(), + Self::descriptor_iterations(), + )), + } + } + /// Whether the link force is enabled. /// /// The link force aims to achieve a target distance between two nodes that are connected by one ore more edges. @@ -249,7 +238,7 @@ impl ForceLink { mut self, enabled: impl Into, ) -> Self { - self.enabled = Some(enabled.into()); + self.enabled = try_serialize_field(Self::descriptor_enabled(), [enabled]); self } @@ -259,7 +248,7 @@ impl ForceLink { mut self, distance: impl Into, ) -> Self { - self.distance = Some(distance.into()); + self.distance = try_serialize_field(Self::descriptor_distance(), [distance]); self } @@ -271,7 +260,7 @@ impl ForceLink { mut self, iterations: impl Into, ) -> Self { - self.iterations = Some(iterations.into()); + self.iterations = try_serialize_field(Self::descriptor_iterations(), [iterations]); self } } @@ -283,11 +272,4 @@ impl ::re_byte_size::SizeBytes for ForceLink { + self.distance.heap_size_bytes() + self.iterations.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs b/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs index 12a4f7f61971..399a1e0c98e4 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_many_body.rs @@ -21,18 +21,18 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: A force between each pair of nodes that ressembles an electrical charge. /// /// If `strength` is smaller than 0, it pushes nodes apart, if it is larger than 0 it pulls them together. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct ForceManyBody { /// Whether the many body force is enabled. /// /// The many body force is applied on each pair of nodes in a way that ressembles an electrical charge. If the /// strength is smaller than 0, it pushes nodes apart; if it is larger than 0, it pulls them together. - pub enabled: Option, + pub enabled: Option, /// The strength of the force. /// /// If `strength` is smaller than 0, it pushes nodes apart, if it is larger than 0 it pulls them together. - pub strength: Option, + pub strength: Option, } impl ForceManyBody { @@ -144,50 +144,24 @@ impl ::re_types_core::Archetype for ForceManyBody { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let enabled = if let Some(array) = arrays_by_descr.get(&Self::descriptor_enabled()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForceManyBody#enabled")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let strength = if let Some(array) = arrays_by_descr.get(&Self::descriptor_strength()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForceManyBody#strength")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let enabled = arrays_by_descr + .get(&Self::descriptor_enabled()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_enabled())); + let strength = arrays_by_descr + .get(&Self::descriptor_strength()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_strength())); Ok(Self { enabled, strength }) } } impl ::re_types_core::AsComponents for ForceManyBody { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (self - .enabled - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_enabled()), - }), - (self - .strength - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_strength()), - }), + Self::indicator().serialized(), + self.enabled.clone(), + self.strength.clone(), ] .into_iter() .flatten() @@ -207,6 +181,28 @@ impl ForceManyBody { } } + /// Update only some specific fields of a `ForceManyBody`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `ForceManyBody`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + enabled: Some(SerializedComponentBatch::new( + crate::blueprint::components::Enabled::arrow_empty(), + Self::descriptor_enabled(), + )), + strength: Some(SerializedComponentBatch::new( + crate::blueprint::components::ForceStrength::arrow_empty(), + Self::descriptor_strength(), + )), + } + } + /// Whether the many body force is enabled. /// /// The many body force is applied on each pair of nodes in a way that ressembles an electrical charge. If the @@ -216,7 +212,7 @@ impl ForceManyBody { mut self, enabled: impl Into, ) -> Self { - self.enabled = Some(enabled.into()); + self.enabled = try_serialize_field(Self::descriptor_enabled(), [enabled]); self } @@ -228,7 +224,7 @@ impl ForceManyBody { mut self, strength: impl Into, ) -> Self { - self.strength = Some(strength.into()); + self.strength = try_serialize_field(Self::descriptor_strength(), [strength]); self } } @@ -238,10 +234,4 @@ impl ::re_byte_size::SizeBytes for ForceManyBody { fn heap_size_bytes(&self) -> u64 { self.enabled.heap_size_bytes() + self.strength.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/force_position.rs b/crates/store/re_types/src/blueprint/archetypes/force_position.rs index ca3cbcec4559..ad4a4d3360f0 100644 --- a/crates/store/re_types/src/blueprint/archetypes/force_position.rs +++ b/crates/store/re_types/src/blueprint/archetypes/force_position.rs @@ -19,18 +19,18 @@ use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: Similar to gravity, this force pulls nodes towards a specific position. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct ForcePosition { /// Whether the position force is enabled. /// /// The position force pulls nodes towards a specific position, similar to gravity. - pub enabled: Option, + pub enabled: Option, /// The strength of the force. - pub strength: Option, + pub strength: Option, /// The position where the nodes should be pulled towards. - pub position: Option, + pub position: Option, } impl ForcePosition { @@ -154,33 +154,15 @@ impl ::re_types_core::Archetype for ForcePosition { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let enabled = if let Some(array) = arrays_by_descr.get(&Self::descriptor_enabled()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForcePosition#enabled")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let strength = if let Some(array) = arrays_by_descr.get(&Self::descriptor_strength()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForcePosition#strength")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let position = if let Some(array) = arrays_by_descr.get(&Self::descriptor_position()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ForcePosition#position")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let enabled = arrays_by_descr + .get(&Self::descriptor_enabled()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_enabled())); + let strength = arrays_by_descr + .get(&Self::descriptor_strength()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_strength())); + let position = arrays_by_descr + .get(&Self::descriptor_position()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_position())); Ok(Self { enabled, strength, @@ -190,35 +172,14 @@ impl ::re_types_core::Archetype for ForcePosition { } impl ::re_types_core::AsComponents for ForcePosition { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (self - .enabled - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_enabled()), - }), - (self - .strength - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_strength()), - }), - (self - .position - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_position()), - }), + Self::indicator().serialized(), + self.enabled.clone(), + self.strength.clone(), + self.position.clone(), ] .into_iter() .flatten() @@ -239,6 +200,32 @@ impl ForcePosition { } } + /// Update only some specific fields of a `ForcePosition`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `ForcePosition`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + enabled: Some(SerializedComponentBatch::new( + crate::blueprint::components::Enabled::arrow_empty(), + Self::descriptor_enabled(), + )), + strength: Some(SerializedComponentBatch::new( + crate::blueprint::components::ForceStrength::arrow_empty(), + Self::descriptor_strength(), + )), + position: Some(SerializedComponentBatch::new( + crate::components::Position2D::arrow_empty(), + Self::descriptor_position(), + )), + } + } + /// Whether the position force is enabled. /// /// The position force pulls nodes towards a specific position, similar to gravity. @@ -247,7 +234,7 @@ impl ForcePosition { mut self, enabled: impl Into, ) -> Self { - self.enabled = Some(enabled.into()); + self.enabled = try_serialize_field(Self::descriptor_enabled(), [enabled]); self } @@ -257,14 +244,14 @@ impl ForcePosition { mut self, strength: impl Into, ) -> Self { - self.strength = Some(strength.into()); + self.strength = try_serialize_field(Self::descriptor_strength(), [strength]); self } /// The position where the nodes should be pulled towards. #[inline] pub fn with_position(mut self, position: impl Into) -> Self { - self.position = Some(position.into()); + self.position = try_serialize_field(Self::descriptor_position(), [position]); self } } @@ -276,11 +263,4 @@ impl ::re_byte_size::SizeBytes for ForcePosition { + self.strength.heap_size_bytes() + self.position.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs index 7c68426495bb..e9d5a7582e8a 100644 --- a/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs +++ b/crates/store/re_types/src/blueprint/archetypes/line_grid3d.rs @@ -19,34 +19,34 @@ use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: Configuration for the 3D line grid. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct LineGrid3D { /// Whether the grid is visible. /// /// Defaults to true. - pub visible: Option, + pub visible: Option, /// Space between grid lines spacing of one line to the next in scene units. /// /// As you zoom out, successively only every tenth line is shown. /// This controls the closest zoom level. - pub spacing: Option, + pub spacing: Option, /// In what plane the grid is drawn. /// /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`components::ViewCoordinates`][crate::components::ViewCoordinates] if present. - pub plane: Option, + pub plane: Option, /// How thick the lines should be in ui units. /// /// Default is 1.0 ui unit. - pub stroke_width: Option, + pub stroke_width: Option, /// Color used for the grid. /// /// Transparency via alpha channel is supported. /// Defaults to a slightly transparent light gray. - pub color: Option, + pub color: Option, } impl LineGrid3D { @@ -194,52 +194,23 @@ impl ::re_types_core::Archetype for LineGrid3D { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let visible = if let Some(array) = arrays_by_descr.get(&Self::descriptor_visible()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.LineGrid3D#visible")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let spacing = if let Some(array) = arrays_by_descr.get(&Self::descriptor_spacing()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.LineGrid3D#spacing")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let plane = if let Some(array) = arrays_by_descr.get(&Self::descriptor_plane()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.LineGrid3D#plane")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let stroke_width = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_stroke_width()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.LineGrid3D#stroke_width")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let color = if let Some(array) = arrays_by_descr.get(&Self::descriptor_color()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.LineGrid3D#color")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let visible = arrays_by_descr + .get(&Self::descriptor_visible()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_visible())); + let spacing = arrays_by_descr + .get(&Self::descriptor_spacing()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_spacing())); + let plane = arrays_by_descr + .get(&Self::descriptor_plane()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_plane())); + let stroke_width = arrays_by_descr + .get(&Self::descriptor_stroke_width()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_stroke_width()) + }); + let color = arrays_by_descr + .get(&Self::descriptor_color()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_color())); Ok(Self { visible, spacing, @@ -251,51 +222,16 @@ impl ::re_types_core::Archetype for LineGrid3D { } impl ::re_types_core::AsComponents for LineGrid3D { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (self - .visible - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_visible()), - }), - (self - .spacing - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_spacing()), - }), - (self - .plane - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_plane()), - }), - (self - .stroke_width - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_stroke_width()), - }), - (self - .color - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_color()), - }), + Self::indicator().serialized(), + self.visible.clone(), + self.spacing.clone(), + self.plane.clone(), + self.stroke_width.clone(), + self.color.clone(), ] .into_iter() .flatten() @@ -318,6 +254,40 @@ impl LineGrid3D { } } + /// Update only some specific fields of a `LineGrid3D`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `LineGrid3D`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + visible: Some(SerializedComponentBatch::new( + crate::blueprint::components::Visible::arrow_empty(), + Self::descriptor_visible(), + )), + spacing: Some(SerializedComponentBatch::new( + crate::blueprint::components::GridSpacing::arrow_empty(), + Self::descriptor_spacing(), + )), + plane: Some(SerializedComponentBatch::new( + crate::components::Plane3D::arrow_empty(), + Self::descriptor_plane(), + )), + stroke_width: Some(SerializedComponentBatch::new( + crate::components::StrokeWidth::arrow_empty(), + Self::descriptor_stroke_width(), + )), + color: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_color(), + )), + } + } + /// Whether the grid is visible. /// /// Defaults to true. @@ -326,7 +296,7 @@ impl LineGrid3D { mut self, visible: impl Into, ) -> Self { - self.visible = Some(visible.into()); + self.visible = try_serialize_field(Self::descriptor_visible(), [visible]); self } @@ -339,7 +309,7 @@ impl LineGrid3D { mut self, spacing: impl Into, ) -> Self { - self.spacing = Some(spacing.into()); + self.spacing = try_serialize_field(Self::descriptor_spacing(), [spacing]); self } @@ -348,7 +318,7 @@ impl LineGrid3D { /// Defaults to whatever plane is determined as the plane at zero units up/down as defined by [`components::ViewCoordinates`][crate::components::ViewCoordinates] if present. #[inline] pub fn with_plane(mut self, plane: impl Into) -> Self { - self.plane = Some(plane.into()); + self.plane = try_serialize_field(Self::descriptor_plane(), [plane]); self } @@ -360,7 +330,7 @@ impl LineGrid3D { mut self, stroke_width: impl Into, ) -> Self { - self.stroke_width = Some(stroke_width.into()); + self.stroke_width = try_serialize_field(Self::descriptor_stroke_width(), [stroke_width]); self } @@ -370,7 +340,7 @@ impl LineGrid3D { /// Defaults to a slightly transparent light gray. #[inline] pub fn with_color(mut self, color: impl Into) -> Self { - self.color = Some(color.into()); + self.color = try_serialize_field(Self::descriptor_color(), [color]); self } } @@ -384,13 +354,4 @@ impl ::re_byte_size::SizeBytes for LineGrid3D { + self.stroke_width.heap_size_bytes() + self.color.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/map_background.rs b/crates/store/re_types/src/blueprint/archetypes/map_background.rs index b1854843b142..dd19b53673ae 100644 --- a/crates/store/re_types/src/blueprint/archetypes/map_background.rs +++ b/crates/store/re_types/src/blueprint/archetypes/map_background.rs @@ -19,12 +19,12 @@ use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: Configuration for the background map of the map view. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct MapBackground { /// Map provider and style to use. /// /// **Note**: Requires a Mapbox API key in the `RERUN_MAPBOX_ACCESS_TOKEN` environment variable. - pub provider: crate::blueprint::components::MapProvider, + pub provider: Option, } impl MapBackground { @@ -120,39 +120,21 @@ impl ::re_types_core::Archetype for MapBackground { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let provider = { - let array = arrays_by_descr - .get(&Self::descriptor_provider()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.blueprint.archetypes.MapBackground#provider")?; - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.MapBackground#provider")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.blueprint.archetypes.MapBackground#provider")? - }; + let provider = arrays_by_descr + .get(&Self::descriptor_provider()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_provider())); Ok(Self { provider }) } } impl ::re_types_core::AsComponents for MapBackground { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; - [ - Some(Self::indicator()), - (Some(&self.provider as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_provider()), - } - }), - ] - .into_iter() - .flatten() - .collect() + [Self::indicator().serialized(), self.provider.clone()] + .into_iter() + .flatten() + .collect() } } @@ -163,9 +145,39 @@ impl MapBackground { #[inline] pub fn new(provider: impl Into) -> Self { Self { - provider: provider.into(), + provider: try_serialize_field(Self::descriptor_provider(), [provider]), } } + + /// Update only some specific fields of a `MapBackground`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `MapBackground`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + provider: Some(SerializedComponentBatch::new( + crate::blueprint::components::MapProvider::arrow_empty(), + Self::descriptor_provider(), + )), + } + } + + /// Map provider and style to use. + /// + /// **Note**: Requires a Mapbox API key in the `RERUN_MAPBOX_ACCESS_TOKEN` environment variable. + #[inline] + pub fn with_provider( + mut self, + provider: impl Into, + ) -> Self { + self.provider = try_serialize_field(Self::descriptor_provider(), [provider]); + self + } } impl ::re_byte_size::SizeBytes for MapBackground { @@ -173,9 +185,4 @@ impl ::re_byte_size::SizeBytes for MapBackground { fn heap_size_bytes(&self) -> u64 { self.provider.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - ::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/map_zoom.rs b/crates/store/re_types/src/blueprint/archetypes/map_zoom.rs index 4c08c0ded30d..5f8ac2714640 100644 --- a/crates/store/re_types/src/blueprint/archetypes/map_zoom.rs +++ b/crates/store/re_types/src/blueprint/archetypes/map_zoom.rs @@ -19,12 +19,12 @@ use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: Configuration of the map view zoom level. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct MapZoom { /// Zoom level for the map. /// /// Zoom level follow the [`OpenStreetMap` definition](https://wiki.openstreetmap.org/wiki/Zoom_levels). - pub zoom: crate::blueprint::components::ZoomLevel, + pub zoom: Option, } impl MapZoom { @@ -115,39 +115,21 @@ impl ::re_types_core::Archetype for MapZoom { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let zoom = { - let array = arrays_by_descr - .get(&Self::descriptor_zoom()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.blueprint.archetypes.MapZoom#zoom")?; - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.MapZoom#zoom")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.blueprint.archetypes.MapZoom#zoom")? - }; + let zoom = arrays_by_descr + .get(&Self::descriptor_zoom()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_zoom())); Ok(Self { zoom }) } } impl ::re_types_core::AsComponents for MapZoom { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; - [ - Some(Self::indicator()), - (Some(&self.zoom as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_zoom()), - } - }), - ] - .into_iter() - .flatten() - .collect() + [Self::indicator().serialized(), self.zoom.clone()] + .into_iter() + .flatten() + .collect() } } @@ -157,7 +139,36 @@ impl MapZoom { /// Create a new `MapZoom`. #[inline] pub fn new(zoom: impl Into) -> Self { - Self { zoom: zoom.into() } + Self { + zoom: try_serialize_field(Self::descriptor_zoom(), [zoom]), + } + } + + /// Update only some specific fields of a `MapZoom`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `MapZoom`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + zoom: Some(SerializedComponentBatch::new( + crate::blueprint::components::ZoomLevel::arrow_empty(), + Self::descriptor_zoom(), + )), + } + } + + /// Zoom level for the map. + /// + /// Zoom level follow the [`OpenStreetMap` definition](https://wiki.openstreetmap.org/wiki/Zoom_levels). + #[inline] + pub fn with_zoom(mut self, zoom: impl Into) -> Self { + self.zoom = try_serialize_field(Self::descriptor_zoom(), [zoom]); + self } } @@ -166,9 +177,4 @@ impl ::re_byte_size::SizeBytes for MapZoom { fn heap_size_bytes(&self) -> u64 { self.zoom.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - ::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/mod.rs b/crates/store/re_types/src/blueprint/archetypes/mod.rs index e226ce3141b4..20bbbac5355f 100644 --- a/crates/store/re_types/src/blueprint/archetypes/mod.rs +++ b/crates/store/re_types/src/blueprint/archetypes/mod.rs @@ -22,7 +22,6 @@ mod view_blueprint; mod view_contents; mod viewport_blueprint; mod visible_time_ranges; -mod visible_time_ranges_ext; mod visual_bounds2d; pub use self::background::Background; diff --git a/crates/store/re_types/src/blueprint/archetypes/near_clip_plane.rs b/crates/store/re_types/src/blueprint/archetypes/near_clip_plane.rs index 3ecaabfff1e0..8aa5043ad643 100644 --- a/crates/store/re_types/src/blueprint/archetypes/near_clip_plane.rs +++ b/crates/store/re_types/src/blueprint/archetypes/near_clip_plane.rs @@ -19,12 +19,12 @@ use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: Controls the distance to the near clip plane in 3D scene units. -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Debug, Default)] pub struct NearClipPlane { /// Controls the distance to the near clip plane in 3D scene units. /// /// Content closer than this distance will not be visible. - pub near_clip_plane: crate::blueprint::components::NearClipPlane, + pub near_clip_plane: Option, } impl NearClipPlane { @@ -120,39 +120,23 @@ impl ::re_types_core::Archetype for NearClipPlane { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let near_clip_plane = { - let array = arrays_by_descr - .get(&Self::descriptor_near_clip_plane()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.blueprint.archetypes.NearClipPlane#near_clip_plane")?; - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.NearClipPlane#near_clip_plane")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.blueprint.archetypes.NearClipPlane#near_clip_plane")? - }; + let near_clip_plane = arrays_by_descr + .get(&Self::descriptor_near_clip_plane()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_near_clip_plane()) + }); Ok(Self { near_clip_plane }) } } impl ::re_types_core::AsComponents for NearClipPlane { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; - [ - Some(Self::indicator()), - (Some(&self.near_clip_plane as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_near_clip_plane()), - } - }), - ] - .into_iter() - .flatten() - .collect() + [Self::indicator().serialized(), self.near_clip_plane.clone()] + .into_iter() + .flatten() + .collect() } } @@ -163,9 +147,43 @@ impl NearClipPlane { #[inline] pub fn new(near_clip_plane: impl Into) -> Self { Self { - near_clip_plane: near_clip_plane.into(), + near_clip_plane: try_serialize_field( + Self::descriptor_near_clip_plane(), + [near_clip_plane], + ), } } + + /// Update only some specific fields of a `NearClipPlane`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `NearClipPlane`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + near_clip_plane: Some(SerializedComponentBatch::new( + crate::blueprint::components::NearClipPlane::arrow_empty(), + Self::descriptor_near_clip_plane(), + )), + } + } + + /// Controls the distance to the near clip plane in 3D scene units. + /// + /// Content closer than this distance will not be visible. + #[inline] + pub fn with_near_clip_plane( + mut self, + near_clip_plane: impl Into, + ) -> Self { + self.near_clip_plane = + try_serialize_field(Self::descriptor_near_clip_plane(), [near_clip_plane]); + self + } } impl ::re_byte_size::SizeBytes for NearClipPlane { @@ -173,9 +191,4 @@ impl ::re_byte_size::SizeBytes for NearClipPlane { fn heap_size_bytes(&self) -> u64 { self.near_clip_plane.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - ::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/panel_blueprint.rs b/crates/store/re_types/src/blueprint/archetypes/panel_blueprint.rs index 30f03a303bf5..8453243f90fe 100644 --- a/crates/store/re_types/src/blueprint/archetypes/panel_blueprint.rs +++ b/crates/store/re_types/src/blueprint/archetypes/panel_blueprint.rs @@ -22,7 +22,7 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; #[derive(Clone, Debug, Default)] pub struct PanelBlueprint { /// Current state of the panels. - pub state: Option, + pub state: Option, } impl PanelBlueprint { @@ -118,37 +118,21 @@ impl ::re_types_core::Archetype for PanelBlueprint { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let state = if let Some(array) = arrays_by_descr.get(&Self::descriptor_state()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.PanelBlueprint#state")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let state = arrays_by_descr + .get(&Self::descriptor_state()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_state())); Ok(Self { state }) } } impl ::re_types_core::AsComponents for PanelBlueprint { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; - [ - Some(Self::indicator()), - (self - .state - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_state()), - }), - ] - .into_iter() - .flatten() - .collect() + [Self::indicator().serialized(), self.state.clone()] + .into_iter() + .flatten() + .collect() } } @@ -161,13 +145,31 @@ impl PanelBlueprint { Self { state: None } } + /// Update only some specific fields of a `PanelBlueprint`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `PanelBlueprint`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + state: Some(SerializedComponentBatch::new( + crate::blueprint::components::PanelState::arrow_empty(), + Self::descriptor_state(), + )), + } + } + /// Current state of the panels. #[inline] pub fn with_state( mut self, state: impl Into, ) -> Self { - self.state = Some(state.into()); + self.state = try_serialize_field(Self::descriptor_state(), [state]); self } } @@ -177,9 +179,4 @@ impl ::re_byte_size::SizeBytes for PanelBlueprint { fn heap_size_bytes(&self) -> u64 { self.state.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/plot_legend.rs b/crates/store/re_types/src/blueprint/archetypes/plot_legend.rs index 3f5bde616686..1182b1644874 100644 --- a/crates/store/re_types/src/blueprint/archetypes/plot_legend.rs +++ b/crates/store/re_types/src/blueprint/archetypes/plot_legend.rs @@ -24,12 +24,12 @@ pub struct PlotLegend { /// To what corner the legend is aligned. /// /// Defaults to the right bottom corner. - pub corner: Option, + pub corner: Option, /// Whether the legend is shown at all. /// /// True by default. - pub visible: Option, + pub visible: Option, } impl PlotLegend { @@ -141,50 +141,24 @@ impl ::re_types_core::Archetype for PlotLegend { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let corner = if let Some(array) = arrays_by_descr.get(&Self::descriptor_corner()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.PlotLegend#corner")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let visible = if let Some(array) = arrays_by_descr.get(&Self::descriptor_visible()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.PlotLegend#visible")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let corner = arrays_by_descr + .get(&Self::descriptor_corner()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_corner())); + let visible = arrays_by_descr + .get(&Self::descriptor_visible()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_visible())); Ok(Self { corner, visible }) } } impl ::re_types_core::AsComponents for PlotLegend { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (self - .corner - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_corner()), - }), - (self - .visible - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_visible()), - }), + Self::indicator().serialized(), + self.corner.clone(), + self.visible.clone(), ] .into_iter() .flatten() @@ -204,6 +178,28 @@ impl PlotLegend { } } + /// Update only some specific fields of a `PlotLegend`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `PlotLegend`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + corner: Some(SerializedComponentBatch::new( + crate::blueprint::components::Corner2D::arrow_empty(), + Self::descriptor_corner(), + )), + visible: Some(SerializedComponentBatch::new( + crate::blueprint::components::Visible::arrow_empty(), + Self::descriptor_visible(), + )), + } + } + /// To what corner the legend is aligned. /// /// Defaults to the right bottom corner. @@ -212,7 +208,7 @@ impl PlotLegend { mut self, corner: impl Into, ) -> Self { - self.corner = Some(corner.into()); + self.corner = try_serialize_field(Self::descriptor_corner(), [corner]); self } @@ -224,7 +220,7 @@ impl PlotLegend { mut self, visible: impl Into, ) -> Self { - self.visible = Some(visible.into()); + self.visible = try_serialize_field(Self::descriptor_visible(), [visible]); self } } @@ -234,10 +230,4 @@ impl ::re_byte_size::SizeBytes for PlotLegend { fn heap_size_bytes(&self) -> u64 { self.corner.heap_size_bytes() + self.visible.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/scalar_axis.rs b/crates/store/re_types/src/blueprint/archetypes/scalar_axis.rs index b354df518205..506b26ba017d 100644 --- a/crates/store/re_types/src/blueprint/archetypes/scalar_axis.rs +++ b/crates/store/re_types/src/blueprint/archetypes/scalar_axis.rs @@ -24,10 +24,10 @@ pub struct ScalarAxis { /// The range of the axis. /// /// If unset, the range well be automatically determined based on the queried data. - pub range: Option, + pub range: Option, /// If enabled, the Y axis range will remain locked to the specified range when zooming. - pub zoom_lock: Option, + pub zoom_lock: Option, } impl ScalarAxis { @@ -139,50 +139,26 @@ impl ::re_types_core::Archetype for ScalarAxis { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let range = if let Some(array) = arrays_by_descr.get(&Self::descriptor_range()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ScalarAxis#range")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let zoom_lock = if let Some(array) = arrays_by_descr.get(&Self::descriptor_zoom_lock()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ScalarAxis#zoom_lock")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let range = arrays_by_descr + .get(&Self::descriptor_range()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_range())); + let zoom_lock = arrays_by_descr + .get(&Self::descriptor_zoom_lock()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_zoom_lock()) + }); Ok(Self { range, zoom_lock }) } } impl ::re_types_core::AsComponents for ScalarAxis { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (self - .range - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_range()), - }), - (self - .zoom_lock - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_zoom_lock()), - }), + Self::indicator().serialized(), + self.range.clone(), + self.zoom_lock.clone(), ] .into_iter() .flatten() @@ -202,12 +178,34 @@ impl ScalarAxis { } } + /// Update only some specific fields of a `ScalarAxis`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `ScalarAxis`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + range: Some(SerializedComponentBatch::new( + crate::components::Range1D::arrow_empty(), + Self::descriptor_range(), + )), + zoom_lock: Some(SerializedComponentBatch::new( + crate::blueprint::components::LockRangeDuringZoom::arrow_empty(), + Self::descriptor_zoom_lock(), + )), + } + } + /// The range of the axis. /// /// If unset, the range well be automatically determined based on the queried data. #[inline] pub fn with_range(mut self, range: impl Into) -> Self { - self.range = Some(range.into()); + self.range = try_serialize_field(Self::descriptor_range(), [range]); self } @@ -217,7 +215,7 @@ impl ScalarAxis { mut self, zoom_lock: impl Into, ) -> Self { - self.zoom_lock = Some(zoom_lock.into()); + self.zoom_lock = try_serialize_field(Self::descriptor_zoom_lock(), [zoom_lock]); self } } @@ -227,10 +225,4 @@ impl ::re_byte_size::SizeBytes for ScalarAxis { fn heap_size_bytes(&self) -> u64 { self.range.heap_size_bytes() + self.zoom_lock.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs b/crates/store/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs index 17b9bf68667e..dc2e34caa03d 100644 --- a/crates/store/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs +++ b/crates/store/re_types/src/blueprint/archetypes/tensor_scalar_mapping.rs @@ -24,10 +24,10 @@ pub struct TensorScalarMapping { /// Filter used when zooming in on the tensor. /// /// Note that the filter is applied to the scalar values *before* they are mapped to color. - pub mag_filter: Option, + pub mag_filter: Option, /// How scalar values map to colors. - pub colormap: Option, + pub colormap: Option, /// Gamma exponent applied to normalized values before mapping to color. /// @@ -36,7 +36,7 @@ pub struct TensorScalarMapping { /// /// The final value for display is set as: /// `colormap( ((value - data_display_range.min) / (data_display_range.max - data_display_range.min)) ** gamma )` - pub gamma: Option, + pub gamma: Option, } impl TensorScalarMapping { @@ -161,33 +161,17 @@ impl ::re_types_core::Archetype for TensorScalarMapping { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let mag_filter = if let Some(array) = arrays_by_descr.get(&Self::descriptor_mag_filter()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.TensorScalarMapping#mag_filter")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let colormap = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colormap()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.TensorScalarMapping#colormap")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let gamma = if let Some(array) = arrays_by_descr.get(&Self::descriptor_gamma()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.TensorScalarMapping#gamma")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let mag_filter = arrays_by_descr + .get(&Self::descriptor_mag_filter()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_mag_filter()) + }); + let colormap = arrays_by_descr + .get(&Self::descriptor_colormap()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_colormap())); + let gamma = arrays_by_descr + .get(&Self::descriptor_gamma()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_gamma())); Ok(Self { mag_filter, colormap, @@ -197,35 +181,14 @@ impl ::re_types_core::Archetype for TensorScalarMapping { } impl ::re_types_core::AsComponents for TensorScalarMapping { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (self - .mag_filter - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_mag_filter()), - }), - (self - .colormap - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_colormap()), - }), - (self - .gamma - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_gamma()), - }), + Self::indicator().serialized(), + self.mag_filter.clone(), + self.colormap.clone(), + self.gamma.clone(), ] .into_iter() .flatten() @@ -246,6 +209,32 @@ impl TensorScalarMapping { } } + /// Update only some specific fields of a `TensorScalarMapping`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `TensorScalarMapping`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + mag_filter: Some(SerializedComponentBatch::new( + crate::components::MagnificationFilter::arrow_empty(), + Self::descriptor_mag_filter(), + )), + colormap: Some(SerializedComponentBatch::new( + crate::components::Colormap::arrow_empty(), + Self::descriptor_colormap(), + )), + gamma: Some(SerializedComponentBatch::new( + crate::components::GammaCorrection::arrow_empty(), + Self::descriptor_gamma(), + )), + } + } + /// Filter used when zooming in on the tensor. /// /// Note that the filter is applied to the scalar values *before* they are mapped to color. @@ -254,14 +243,14 @@ impl TensorScalarMapping { mut self, mag_filter: impl Into, ) -> Self { - self.mag_filter = Some(mag_filter.into()); + self.mag_filter = try_serialize_field(Self::descriptor_mag_filter(), [mag_filter]); self } /// How scalar values map to colors. #[inline] pub fn with_colormap(mut self, colormap: impl Into) -> Self { - self.colormap = Some(colormap.into()); + self.colormap = try_serialize_field(Self::descriptor_colormap(), [colormap]); self } @@ -274,7 +263,7 @@ impl TensorScalarMapping { /// `colormap( ((value - data_display_range.min) / (data_display_range.max - data_display_range.min)) ** gamma )` #[inline] pub fn with_gamma(mut self, gamma: impl Into) -> Self { - self.gamma = Some(gamma.into()); + self.gamma = try_serialize_field(Self::descriptor_gamma(), [gamma]); self } } @@ -286,11 +275,4 @@ impl ::re_byte_size::SizeBytes for TensorScalarMapping { + self.colormap.heap_size_bytes() + self.gamma.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/tensor_slice_selection.rs b/crates/store/re_types/src/blueprint/archetypes/tensor_slice_selection.rs index 035003e10020..60ef51ce0bb4 100644 --- a/crates/store/re_types/src/blueprint/archetypes/tensor_slice_selection.rs +++ b/crates/store/re_types/src/blueprint/archetypes/tensor_slice_selection.rs @@ -19,29 +19,29 @@ use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: Specifies a 2D slice of a tensor. -#[derive(Clone, Debug, Default, Hash, PartialEq, Eq)] +#[derive(Clone, Debug, Default)] pub struct TensorSliceSelection { /// Which dimension to map to width. /// /// If not specified, the height will be determined automatically based on the name and index of the dimension. - pub width: Option, + pub width: Option, /// Which dimension to map to height. /// /// If not specified, the height will be determined automatically based on the name and index of the dimension. - pub height: Option, + pub height: Option, /// Selected indices for all other dimensions. /// /// If any of the here listed dimensions is equal to `width` or `height`, it will be ignored. - pub indices: Option>, + pub indices: Option, /// Any dimension listed here will have a slider for the index. /// /// Edits to the sliders will directly manipulate dimensions on the `indices` list. /// If any of the here listed dimensions is equal to `width` or `height`, it will be ignored. /// If not specified, adds slides for any dimension in `indices`. - pub slider: Option>, + pub slider: Option, } impl TensorSliceSelection { @@ -178,48 +178,18 @@ impl ::re_types_core::Archetype for TensorSliceSelection { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let width = if let Some(array) = arrays_by_descr.get(&Self::descriptor_width()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.TensorSliceSelection#width")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let height = if let Some(array) = arrays_by_descr.get(&Self::descriptor_height()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.TensorSliceSelection#height")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let indices = if let Some(array) = arrays_by_descr.get(&Self::descriptor_indices()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.TensorSliceSelection#indices")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.blueprint.archetypes.TensorSliceSelection#indices")? - }) - } else { - None - }; - let slider = if let Some(array) = arrays_by_descr.get(&Self::descriptor_slider()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.TensorSliceSelection#slider")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.blueprint.archetypes.TensorSliceSelection#slider")? - }) - } else { - None - }; + let width = arrays_by_descr + .get(&Self::descriptor_width()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_width())); + let height = arrays_by_descr + .get(&Self::descriptor_height()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_height())); + let indices = arrays_by_descr + .get(&Self::descriptor_indices()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_indices())); + let slider = arrays_by_descr + .get(&Self::descriptor_slider()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_slider())); Ok(Self { width, height, @@ -230,43 +200,15 @@ impl ::re_types_core::Archetype for TensorSliceSelection { } impl ::re_types_core::AsComponents for TensorSliceSelection { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (self - .width - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_width()), - }), - (self - .height - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_height()), - }), - (self - .indices - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_indices()), - }), - (self - .slider - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_slider()), - }), + Self::indicator().serialized(), + self.width.clone(), + self.height.clone(), + self.indices.clone(), + self.slider.clone(), ] .into_iter() .flatten() @@ -288,12 +230,42 @@ impl TensorSliceSelection { } } + /// Update only some specific fields of a `TensorSliceSelection`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `TensorSliceSelection`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + width: Some(SerializedComponentBatch::new( + crate::components::TensorWidthDimension::arrow_empty(), + Self::descriptor_width(), + )), + height: Some(SerializedComponentBatch::new( + crate::components::TensorHeightDimension::arrow_empty(), + Self::descriptor_height(), + )), + indices: Some(SerializedComponentBatch::new( + crate::components::TensorDimensionIndexSelection::arrow_empty(), + Self::descriptor_indices(), + )), + slider: Some(SerializedComponentBatch::new( + crate::blueprint::components::TensorDimensionIndexSlider::arrow_empty(), + Self::descriptor_slider(), + )), + } + } + /// Which dimension to map to width. /// /// If not specified, the height will be determined automatically based on the name and index of the dimension. #[inline] pub fn with_width(mut self, width: impl Into) -> Self { - self.width = Some(width.into()); + self.width = try_serialize_field(Self::descriptor_width(), [width]); self } @@ -305,7 +277,7 @@ impl TensorSliceSelection { mut self, height: impl Into, ) -> Self { - self.height = Some(height.into()); + self.height = try_serialize_field(Self::descriptor_height(), [height]); self } @@ -317,7 +289,7 @@ impl TensorSliceSelection { mut self, indices: impl IntoIterator>, ) -> Self { - self.indices = Some(indices.into_iter().map(Into::into).collect()); + self.indices = try_serialize_field(Self::descriptor_indices(), indices); self } @@ -333,7 +305,7 @@ impl TensorSliceSelection { Item = impl Into, >, ) -> Self { - self.slider = Some(slider.into_iter().map(Into::into).collect()); + self.slider = try_serialize_field(Self::descriptor_slider(), slider); self } } @@ -346,12 +318,4 @@ impl ::re_byte_size::SizeBytes for TensorSliceSelection { + self.indices.heap_size_bytes() + self.slider.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - && >>::is_pod() - && >>::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/tensor_view_fit.rs b/crates/store/re_types/src/blueprint/archetypes/tensor_view_fit.rs index 009e5a72db54..ef0938daa70a 100644 --- a/crates/store/re_types/src/blueprint/archetypes/tensor_view_fit.rs +++ b/crates/store/re_types/src/blueprint/archetypes/tensor_view_fit.rs @@ -22,7 +22,7 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; #[derive(Clone, Debug, Default)] pub struct TensorViewFit { /// How the image is scaled to fit the view. - pub scaling: Option, + pub scaling: Option, } impl TensorViewFit { @@ -118,37 +118,21 @@ impl ::re_types_core::Archetype for TensorViewFit { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let scaling = if let Some(array) = arrays_by_descr.get(&Self::descriptor_scaling()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.TensorViewFit#scaling")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let scaling = arrays_by_descr + .get(&Self::descriptor_scaling()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_scaling())); Ok(Self { scaling }) } } impl ::re_types_core::AsComponents for TensorViewFit { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; - [ - Some(Self::indicator()), - (self - .scaling - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_scaling()), - }), - ] - .into_iter() - .flatten() - .collect() + [Self::indicator().serialized(), self.scaling.clone()] + .into_iter() + .flatten() + .collect() } } @@ -161,13 +145,31 @@ impl TensorViewFit { Self { scaling: None } } + /// Update only some specific fields of a `TensorViewFit`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `TensorViewFit`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + scaling: Some(SerializedComponentBatch::new( + crate::blueprint::components::ViewFit::arrow_empty(), + Self::descriptor_scaling(), + )), + } + } + /// How the image is scaled to fit the view. #[inline] pub fn with_scaling( mut self, scaling: impl Into, ) -> Self { - self.scaling = Some(scaling.into()); + self.scaling = try_serialize_field(Self::descriptor_scaling(), [scaling]); self } } @@ -177,9 +179,4 @@ impl ::re_byte_size::SizeBytes for TensorViewFit { fn heap_size_bytes(&self) -> u64 { self.scaling.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/view_blueprint.rs b/crates/store/re_types/src/blueprint/archetypes/view_blueprint.rs index e7699eda7997..21530cc8f904 100644 --- a/crates/store/re_types/src/blueprint/archetypes/view_blueprint.rs +++ b/crates/store/re_types/src/blueprint/archetypes/view_blueprint.rs @@ -19,13 +19,13 @@ use ::re_types_core::{ComponentDescriptor, ComponentName}; use ::re_types_core::{DeserializationError, DeserializationResult}; /// **Archetype**: The description of a single view. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct ViewBlueprint { /// The class of the view. - pub class_identifier: crate::blueprint::components::ViewClass, + pub class_identifier: Option, /// The name of the view. - pub display_name: Option, + pub display_name: Option, /// The "anchor point" of this view. /// @@ -34,12 +34,12 @@ pub struct ViewBlueprint { /// The transform at this path forms the reference point for all scene->world transforms in this view. /// I.e. the position of this entity path in space forms the origin of the coordinate system in this view. /// Furthermore, this is the primary indicator for heuristics on what entities we show in this view. - pub space_origin: Option, + pub space_origin: Option, /// Whether this view is visible. /// /// Defaults to true if not specified. - pub visible: Option, + pub visible: Option, } impl ViewBlueprint { @@ -174,48 +174,24 @@ impl ::re_types_core::Archetype for ViewBlueprint { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let class_identifier = { - let array = arrays_by_descr - .get(&Self::descriptor_class_identifier()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.blueprint.archetypes.ViewBlueprint#class_identifier")?; - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ViewBlueprint#class_identifier")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.blueprint.archetypes.ViewBlueprint#class_identifier")? - }; - let display_name = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_display_name()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ViewBlueprint#display_name")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let space_origin = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_space_origin()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ViewBlueprint#space_origin")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let visible = if let Some(array) = arrays_by_descr.get(&Self::descriptor_visible()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ViewBlueprint#visible")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let class_identifier = arrays_by_descr + .get(&Self::descriptor_class_identifier()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_class_identifier()) + }); + let display_name = arrays_by_descr + .get(&Self::descriptor_display_name()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_display_name()) + }); + let space_origin = arrays_by_descr + .get(&Self::descriptor_space_origin()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_space_origin()) + }); + let visible = arrays_by_descr + .get(&Self::descriptor_visible()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_visible())); Ok(Self { class_identifier, display_name, @@ -226,41 +202,15 @@ impl ::re_types_core::Archetype for ViewBlueprint { } impl ::re_types_core::AsComponents for ViewBlueprint { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.class_identifier as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_class_identifier()), - } - }), - (self - .display_name - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_display_name()), - }), - (self - .space_origin - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_space_origin()), - }), - (self - .visible - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_visible()), - }), + Self::indicator().serialized(), + self.class_identifier.clone(), + self.display_name.clone(), + self.space_origin.clone(), + self.visible.clone(), ] .into_iter() .flatten() @@ -275,17 +225,61 @@ impl ViewBlueprint { #[inline] pub fn new(class_identifier: impl Into) -> Self { Self { - class_identifier: class_identifier.into(), + class_identifier: try_serialize_field( + Self::descriptor_class_identifier(), + [class_identifier], + ), display_name: None, space_origin: None, visible: None, } } + /// Update only some specific fields of a `ViewBlueprint`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `ViewBlueprint`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + class_identifier: Some(SerializedComponentBatch::new( + crate::blueprint::components::ViewClass::arrow_empty(), + Self::descriptor_class_identifier(), + )), + display_name: Some(SerializedComponentBatch::new( + crate::components::Name::arrow_empty(), + Self::descriptor_display_name(), + )), + space_origin: Some(SerializedComponentBatch::new( + crate::blueprint::components::ViewOrigin::arrow_empty(), + Self::descriptor_space_origin(), + )), + visible: Some(SerializedComponentBatch::new( + crate::blueprint::components::Visible::arrow_empty(), + Self::descriptor_visible(), + )), + } + } + + /// The class of the view. + #[inline] + pub fn with_class_identifier( + mut self, + class_identifier: impl Into, + ) -> Self { + self.class_identifier = + try_serialize_field(Self::descriptor_class_identifier(), [class_identifier]); + self + } + /// The name of the view. #[inline] pub fn with_display_name(mut self, display_name: impl Into) -> Self { - self.display_name = Some(display_name.into()); + self.display_name = try_serialize_field(Self::descriptor_display_name(), [display_name]); self } @@ -301,7 +295,7 @@ impl ViewBlueprint { mut self, space_origin: impl Into, ) -> Self { - self.space_origin = Some(space_origin.into()); + self.space_origin = try_serialize_field(Self::descriptor_space_origin(), [space_origin]); self } @@ -313,7 +307,7 @@ impl ViewBlueprint { mut self, visible: impl Into, ) -> Self { - self.visible = Some(visible.into()); + self.visible = try_serialize_field(Self::descriptor_visible(), [visible]); self } } @@ -326,12 +320,4 @@ impl ::re_byte_size::SizeBytes for ViewBlueprint { + self.space_origin.heap_size_bytes() + self.visible.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - ::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/view_contents.rs b/crates/store/re_types/src/blueprint/archetypes/view_contents.rs index d6c99cfa3613..1a767693fe74 100644 --- a/crates/store/re_types/src/blueprint/archetypes/view_contents.rs +++ b/crates/store/re_types/src/blueprint/archetypes/view_contents.rs @@ -61,7 +61,7 @@ pub struct ViewContents { /// The `QueryExpression` that populates the contents for the view. /// /// They determine which entities are part of the view. - pub query: Vec, + pub query: Option, } impl ViewContents { @@ -157,38 +157,21 @@ impl ::re_types_core::Archetype for ViewContents { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let query = { - let array = arrays_by_descr - .get(&Self::descriptor_query()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.blueprint.archetypes.ViewContents#query")?; - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ViewContents#query")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.blueprint.archetypes.ViewContents#query")? - }; + let query = arrays_by_descr + .get(&Self::descriptor_query()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_query())); Ok(Self { query }) } } impl ::re_types_core::AsComponents for ViewContents { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; - [ - Some(Self::indicator()), - (Some(&self.query as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_query()), - } - }), - ] - .into_iter() - .flatten() - .collect() + [Self::indicator().serialized(), self.query.clone()] + .into_iter() + .flatten() + .collect() } } @@ -201,9 +184,39 @@ impl ViewContents { query: impl IntoIterator>, ) -> Self { Self { - query: query.into_iter().map(Into::into).collect(), + query: try_serialize_field(Self::descriptor_query(), query), + } + } + + /// Update only some specific fields of a `ViewContents`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `ViewContents`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + query: Some(SerializedComponentBatch::new( + crate::blueprint::components::QueryExpression::arrow_empty(), + Self::descriptor_query(), + )), } } + + /// The `QueryExpression` that populates the contents for the view. + /// + /// They determine which entities are part of the view. + #[inline] + pub fn with_query( + mut self, + query: impl IntoIterator>, + ) -> Self { + self.query = try_serialize_field(Self::descriptor_query(), query); + self + } } impl ::re_byte_size::SizeBytes for ViewContents { @@ -211,9 +224,4 @@ impl ::re_byte_size::SizeBytes for ViewContents { fn heap_size_bytes(&self) -> u64 { self.query.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/viewport_blueprint.rs b/crates/store/re_types/src/blueprint/archetypes/viewport_blueprint.rs index a72945cb4bb2..cd2b1d05ee0c 100644 --- a/crates/store/re_types/src/blueprint/archetypes/viewport_blueprint.rs +++ b/crates/store/re_types/src/blueprint/archetypes/viewport_blueprint.rs @@ -22,23 +22,23 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; #[derive(Clone, Debug, Default)] pub struct ViewportBlueprint { /// The layout of the views - pub root_container: Option, + pub root_container: Option, /// Show one tab as maximized? - pub maximized: Option, + pub maximized: Option, /// Whether the viewport layout is determined automatically. /// /// If `true`, the container layout will be reset whenever a new view is added or removed. /// This defaults to `false` and is automatically set to `false` when there is user determined layout. - pub auto_layout: Option, + pub auto_layout: Option, /// Whether or not views should be created automatically. /// /// If `true`, the viewer will only add views that it hasn't considered previously (as identified by `past_viewer_recommendations`) /// and which aren't deemed redundant to existing views. /// This defaults to `false` and is automatically set to `false` when the user adds views manually in the viewer. - pub auto_views: Option, + pub auto_views: Option, /// Hashes of all recommended views the viewer has already added and that should not be added again. /// @@ -46,8 +46,7 @@ pub struct ViewportBlueprint { /// If you want the viewer from stopping to add views, you should set `auto_views` to `false`. /// /// The viewer uses this to determine whether it should keep adding views. - pub past_viewer_recommendations: - Option>, + pub past_viewer_recommendations: Option, } impl ViewportBlueprint { @@ -195,62 +194,34 @@ impl ::re_types_core::Archetype for ViewportBlueprint { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let root_container = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_root_container()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ViewportBlueprint#root_container")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let maximized = if let Some(array) = arrays_by_descr.get(&Self::descriptor_maximized()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ViewportBlueprint#maximized")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let auto_layout = if let Some(array) = arrays_by_descr.get(&Self::descriptor_auto_layout()) - { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ViewportBlueprint#auto_layout")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let auto_views = if let Some(array) = arrays_by_descr.get(&Self::descriptor_auto_views()) { - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.ViewportBlueprint#auto_views")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let past_viewer_recommendations = if let Some(array) = - arrays_by_descr.get(&Self::descriptor_past_viewer_recommendations()) - { - Some({ - ::from_arrow_opt(&**array) - .with_context( - "rerun.blueprint.archetypes.ViewportBlueprint#past_viewer_recommendations", - )? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context( - "rerun.blueprint.archetypes.ViewportBlueprint#past_viewer_recommendations", - )? - }) - } else { - None - }; + let root_container = arrays_by_descr + .get(&Self::descriptor_root_container()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_root_container()) + }); + let maximized = arrays_by_descr + .get(&Self::descriptor_maximized()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_maximized()) + }); + let auto_layout = arrays_by_descr + .get(&Self::descriptor_auto_layout()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_auto_layout()) + }); + let auto_views = arrays_by_descr + .get(&Self::descriptor_auto_views()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_auto_views()) + }); + let past_viewer_recommendations = arrays_by_descr + .get(&Self::descriptor_past_viewer_recommendations()) + .map(|array| { + SerializedComponentBatch::new( + array.clone(), + Self::descriptor_past_viewer_recommendations(), + ) + }); Ok(Self { root_container, maximized, @@ -262,51 +233,16 @@ impl ::re_types_core::Archetype for ViewportBlueprint { } impl ::re_types_core::AsComponents for ViewportBlueprint { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (self - .root_container - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_root_container()), - }), - (self - .maximized - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_maximized()), - }), - (self - .auto_layout - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_auto_layout()), - }), - (self - .auto_views - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_auto_views()), - }), - (self - .past_viewer_recommendations - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_past_viewer_recommendations()), - }), + Self::indicator().serialized(), + self.root_container.clone(), + self.maximized.clone(), + self.auto_layout.clone(), + self.auto_views.clone(), + self.past_viewer_recommendations.clone(), ] .into_iter() .flatten() @@ -329,13 +265,48 @@ impl ViewportBlueprint { } } + /// Update only some specific fields of a `ViewportBlueprint`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `ViewportBlueprint`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + root_container: Some(SerializedComponentBatch::new( + crate::blueprint::components::RootContainer::arrow_empty(), + Self::descriptor_root_container(), + )), + maximized: Some(SerializedComponentBatch::new( + crate::blueprint::components::ViewMaximized::arrow_empty(), + Self::descriptor_maximized(), + )), + auto_layout: Some(SerializedComponentBatch::new( + crate::blueprint::components::AutoLayout::arrow_empty(), + Self::descriptor_auto_layout(), + )), + auto_views: Some(SerializedComponentBatch::new( + crate::blueprint::components::AutoViews::arrow_empty(), + Self::descriptor_auto_views(), + )), + past_viewer_recommendations: Some(SerializedComponentBatch::new( + crate::blueprint::components::ViewerRecommendationHash::arrow_empty(), + Self::descriptor_past_viewer_recommendations(), + )), + } + } + /// The layout of the views #[inline] pub fn with_root_container( mut self, root_container: impl Into, ) -> Self { - self.root_container = Some(root_container.into()); + self.root_container = + try_serialize_field(Self::descriptor_root_container(), [root_container]); self } @@ -345,7 +316,7 @@ impl ViewportBlueprint { mut self, maximized: impl Into, ) -> Self { - self.maximized = Some(maximized.into()); + self.maximized = try_serialize_field(Self::descriptor_maximized(), [maximized]); self } @@ -358,7 +329,7 @@ impl ViewportBlueprint { mut self, auto_layout: impl Into, ) -> Self { - self.auto_layout = Some(auto_layout.into()); + self.auto_layout = try_serialize_field(Self::descriptor_auto_layout(), [auto_layout]); self } @@ -372,7 +343,7 @@ impl ViewportBlueprint { mut self, auto_views: impl Into, ) -> Self { - self.auto_views = Some(auto_views.into()); + self.auto_views = try_serialize_field(Self::descriptor_auto_views(), [auto_views]); self } @@ -389,11 +360,9 @@ impl ViewportBlueprint { Item = impl Into, >, ) -> Self { - self.past_viewer_recommendations = Some( - past_viewer_recommendations - .into_iter() - .map(Into::into) - .collect(), + self.past_viewer_recommendations = try_serialize_field( + Self::descriptor_past_viewer_recommendations(), + past_viewer_recommendations, ); self } @@ -408,13 +377,4 @@ impl ::re_byte_size::SizeBytes for ViewportBlueprint { + self.auto_views.heap_size_bytes() + self.past_viewer_recommendations.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - && >>::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges.rs b/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges.rs index db09e1d83237..e55280213b66 100644 --- a/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges.rs +++ b/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges.rs @@ -32,7 +32,7 @@ pub struct VisibleTimeRanges { /// The time ranges to show for each timeline unless specified otherwise on a per-entity basis. /// /// If a timeline is specified more than once, the first entry will be used. - pub ranges: Vec, + pub ranges: Option, } impl VisibleTimeRanges { @@ -128,38 +128,21 @@ impl ::re_types_core::Archetype for VisibleTimeRanges { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let ranges = { - let array = arrays_by_descr - .get(&Self::descriptor_ranges()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.blueprint.archetypes.VisibleTimeRanges#ranges")?; - ::from_arrow_opt(&**array) - .with_context("rerun.blueprint.archetypes.VisibleTimeRanges#ranges")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.blueprint.archetypes.VisibleTimeRanges#ranges")? - }; + let ranges = arrays_by_descr + .get(&Self::descriptor_ranges()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_ranges())); Ok(Self { ranges }) } } impl ::re_types_core::AsComponents for VisibleTimeRanges { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; - [ - Some(Self::indicator()), - (Some(&self.ranges as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_ranges()), - } - }), - ] - .into_iter() - .flatten() - .collect() + [Self::indicator().serialized(), self.ranges.clone()] + .into_iter() + .flatten() + .collect() } } @@ -172,9 +155,39 @@ impl VisibleTimeRanges { ranges: impl IntoIterator>, ) -> Self { Self { - ranges: ranges.into_iter().map(Into::into).collect(), + ranges: try_serialize_field(Self::descriptor_ranges(), ranges), + } + } + + /// Update only some specific fields of a `VisibleTimeRanges`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `VisibleTimeRanges`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + ranges: Some(SerializedComponentBatch::new( + crate::blueprint::components::VisibleTimeRange::arrow_empty(), + Self::descriptor_ranges(), + )), } } + + /// The time ranges to show for each timeline unless specified otherwise on a per-entity basis. + /// + /// If a timeline is specified more than once, the first entry will be used. + #[inline] + pub fn with_ranges( + mut self, + ranges: impl IntoIterator>, + ) -> Self { + self.ranges = try_serialize_field(Self::descriptor_ranges(), ranges); + self + } } impl ::re_byte_size::SizeBytes for VisibleTimeRanges { @@ -182,9 +195,4 @@ impl ::re_byte_size::SizeBytes for VisibleTimeRanges { fn heap_size_bytes(&self) -> u64 { self.ranges.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - } } diff --git a/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges_ext.rs b/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges_ext.rs deleted file mode 100644 index d57ffcac5a0f..000000000000 --- a/crates/store/re_types/src/blueprint/archetypes/visible_time_ranges_ext.rs +++ /dev/null @@ -1,38 +0,0 @@ -use re_types_core::datatypes::TimeRange; - -use super::VisibleTimeRanges; - -impl VisibleTimeRanges { - /// Retrieves the time range for a given timeline. - pub fn range_for_timeline(&self, timeline_name: &str) -> Option<&TimeRange> { - self.ranges - .iter() - .find(|range| range.timeline.as_str() == timeline_name) - .map(|range| &range.range) - } - - /// Sets the time range for a given timeline. - /// - /// If the range is `None`, the timeline will be removed from the list of visible time ranges. - pub fn set_range_for_timeline(&mut self, timeline_name: &str, range: Option) { - if let Some(range) = range { - if let Some(existing_range) = self - .ranges - .iter_mut() - .find(|range| range.timeline.as_str() == timeline_name) - { - existing_range.0.range = range; - } else { - self.ranges.push( - crate::datatypes::VisibleTimeRange { - timeline: timeline_name.to_owned().into(), - range, - } - .into(), - ); - } - } else { - self.ranges.retain(|r| r.timeline.as_str() != timeline_name); - } - } -} diff --git a/crates/viewer/re_selection_panel/src/visible_time_range_ui.rs b/crates/viewer/re_selection_panel/src/visible_time_range_ui.rs index 7caae1c0e531..01a309723497 100644 --- a/crates/viewer/re_selection_panel/src/visible_time_range_ui.rs +++ b/crates/viewer/re_selection_panel/src/visible_time_range_ui.rs @@ -61,7 +61,7 @@ fn visible_time_range_ui( ) { use re_types::Component as _; - let ranges = ctx + let visible_time_ranges = ctx .blueprint_db() .latest_at( ctx.blueprint_query, @@ -70,12 +70,11 @@ fn visible_time_range_ui( ) .component_batch::() .unwrap_or_default(); - let visible_time_ranges = re_types::blueprint::archetypes::VisibleTimeRanges { ranges }; let timeline_name = *ctx.rec_cfg.time_ctrl.read().timeline().name(); let mut has_individual_range = visible_time_ranges - .range_for_timeline(timeline_name.as_str()) - .is_some(); + .iter() + .any(|range| range.timeline.as_str() == timeline_name.as_str()); let has_individual_range_before = has_individual_range; let query_range_before = resolved_query_range.clone(); @@ -112,7 +111,7 @@ fn save_visible_time_ranges( has_individual_range: bool, query_range: QueryRange, property_path: &EntityPath, - mut visible_time_ranges: re_types::blueprint::archetypes::VisibleTimeRanges, + mut visible_time_range_list: Vec, ) { if has_individual_range { let time_range = match query_range { @@ -125,12 +124,26 @@ fn save_visible_time_ranges( return; } }; - visible_time_ranges.set_range_for_timeline(timeline_name, Some(time_range)); + + if let Some(existing) = visible_time_range_list + .iter_mut() + .find(|r| r.timeline.as_str() == timeline_name.as_str()) + { + existing.range = time_range; + } else { + visible_time_range_list.push( + re_types::datatypes::VisibleTimeRange { + timeline: timeline_name.as_str().into(), + range: time_range, + } + .into(), + ); + } } else { - visible_time_ranges.set_range_for_timeline(timeline_name, None); + visible_time_range_list.retain(|r| r.timeline.as_str() != timeline_name.as_str()); } - ctx.save_blueprint_archetype(property_path, &visible_time_ranges); + ctx.save_blueprint_component(property_path, &visible_time_range_list); } /// Draws ui for showing and configuring a query range. diff --git a/crates/viewer/re_view_tensor/src/dimension_mapping.rs b/crates/viewer/re_view_tensor/src/dimension_mapping.rs index 6fd1f1cd13aa..adbd7894597a 100644 --- a/crates/viewer/re_view_tensor/src/dimension_mapping.rs +++ b/crates/viewer/re_view_tensor/src/dimension_mapping.rs @@ -1,7 +1,7 @@ use egui::NumExt as _; use re_types::{ - blueprint::{archetypes::TensorSliceSelection, components::TensorDimensionIndexSlider}, + blueprint::components::TensorDimensionIndexSlider, components::{TensorDimensionIndexSelection, TensorHeightDimension, TensorWidthDimension}, datatypes::TensorDimensionSelection, }; @@ -9,38 +9,51 @@ use re_viewport_blueprint::ViewProperty; use crate::TensorDimension; -/// Loads slice selection from blueprint and makes modifications (without writing back) such that it is valid -/// for the given tensor shape. +/// Selection of a 2D slice of a tensor. /// -/// This is a best effort function and will insert fallbacks as needed. -/// Note that fallbacks are defined on the spot here and don't use the component fallback system. -/// We don't need the fallback system here since we're also not using generic ui either. -/// -/// General rules for scrubbing the input data: -/// * out of bounds dimensions and indices are clamped to valid -/// * missing width/height is filled in if there's at least 2 dimensions. -pub fn load_tensor_slice_selection_and_make_valid( - slice_selection: &ViewProperty, - shape: &[TensorDimension], -) -> Result { - re_tracing::profile_function!(); - - let mut width = slice_selection.component_or_empty::()?; - let mut height = slice_selection.component_or_empty::()?; - let mut indices = - slice_selection.component_array_or_empty::()?; - let mut slider = slice_selection.component_array::()?; - - make_width_height_valid(shape, &mut width, &mut height); - make_indices_valid(shape, &mut indices, width, height); - make_slider_valid(shape.len() as _, &mut slider, &indices, width, height); - - Ok(TensorSliceSelection { - width, - height, - indices: Some(indices), - slider, - }) +/// This is practically a deserialized & validated version of [`re_types::blueprint::archetypes::TensorSliceSelection`]. +#[derive(Clone, Debug, Hash)] +pub struct TensorSliceSelection { + pub width: Option, + pub height: Option, + pub indices: Vec, + pub slider: Option>, +} + +impl TensorSliceSelection { + /// Loads slice selection from blueprint and makes modifications (without writing back) such that it is valid + /// for the given tensor shape. + /// + /// This is a best effort function and will insert fallbacks as needed. + /// Note that fallbacks are defined on the spot here and don't use the component fallback system. + /// We don't need the fallback system here since we're also not using generic ui either. + /// + /// General rules for scrubbing the input data: + /// * out of bounds dimensions and indices are clamped to valid + /// * missing width/height is filled in if there's at least 2 dimensions. + pub fn load_and_make_valid( + slice_selection: &ViewProperty, + shape: &[TensorDimension], + ) -> Result { + re_tracing::profile_function!(); + + let mut width = slice_selection.component_or_empty::()?; + let mut height = slice_selection.component_or_empty::()?; + let mut indices = + slice_selection.component_array_or_empty::()?; + let mut slider = slice_selection.component_array::()?; + + make_width_height_valid(shape, &mut width, &mut height); + make_indices_valid(shape, &mut indices, width, height); + make_slider_valid(shape.len() as _, &mut slider, &indices, width, height); + + Ok(Self { + width, + height, + indices, + slider, + }) + } } fn make_width_height_valid( diff --git a/crates/viewer/re_view_tensor/src/tensor_dimension_mapper.rs b/crates/viewer/re_view_tensor/src/tensor_dimension_mapper.rs index 6a35e6bbe165..cc5613555961 100644 --- a/crates/viewer/re_view_tensor/src/tensor_dimension_mapper.rs +++ b/crates/viewer/re_view_tensor/src/tensor_dimension_mapper.rs @@ -1,11 +1,9 @@ -use re_types::{ - blueprint::archetypes::TensorSliceSelection, datatypes::TensorDimensionIndexSelection, -}; +use re_types::datatypes::TensorDimensionIndexSelection; use re_ui::UiExt as _; use re_viewer_context::ViewerContext; use re_viewport_blueprint::ViewProperty; -use crate::TensorDimension; +use crate::{dimension_mapping::TensorSliceSelection, TensorDimension}; #[derive(Clone, Copy, PartialEq, Eq)] enum DragDropAddress { @@ -41,9 +39,7 @@ impl DragDropAddress { index: shape[h.dimension as usize].size / 2, // Select middle if this becomes index fixed. }), #[allow(clippy::unwrap_used)] - Self::Selector(selector_idx) => { - Some(slice_selection.indices.as_ref().unwrap()[*selector_idx].0) - } + Self::Selector(selector_idx) => Some(slice_selection.indices[*selector_idx].0), Self::NewSelector => None, } } @@ -74,7 +70,7 @@ impl DragDropAddress { slice_property.save_blueprint_component(ctx, &height); } Self::Selector(selector_idx) => { - let mut indices = slice_selection.indices.clone().unwrap_or_default(); + let mut indices = slice_selection.indices.clone(); let mut slider = slice_selection.slider.clone().unwrap_or_default(); if let Some(new_selection) = new_selection { indices[*selector_idx] = new_selection.into(); @@ -90,7 +86,7 @@ impl DragDropAddress { Self::NewSelector => { // NewSelector can only be a drop *target*, therefore dim_idx can't be None! if let Some(new_selection) = new_selection { - let mut indices = slice_selection.indices.clone().unwrap_or_default(); + let mut indices = slice_selection.indices.clone(); let mut slider = slice_selection.slider.clone().unwrap_or_default(); indices.push(new_selection.into()); slider.push(new_selection.dimension.into()); // Enable slider by default. @@ -206,15 +202,11 @@ pub fn dimension_mapping_ui( ui.vertical(|ui| { ui.label("Selectors"); - let Some(indices) = &slice_selection.indices else { - return; - }; - // Use Grid instead of Vertical layout to match styling of the parallel Grid for egui::Grid::new("selectiongrid") .num_columns(2) .show(ui, |ui| { - for (selector_idx, selector) in indices.iter().enumerate() { + for (selector_idx, selector) in slice_selection.indices.iter().enumerate() { tensor_dimension_ui( ui, drag_context_id, diff --git a/crates/viewer/re_view_tensor/src/tensor_slice_to_gpu.rs b/crates/viewer/re_view_tensor/src/tensor_slice_to_gpu.rs index eb6c0a453f5a..df3be1ce8a00 100644 --- a/crates/viewer/re_view_tensor/src/tensor_slice_to_gpu.rs +++ b/crates/viewer/re_view_tensor/src/tensor_slice_to_gpu.rs @@ -4,7 +4,6 @@ use re_renderer::{ resource_managers::{GpuTexture2D, ImageDataDesc, TextureManager2DError}, }; use re_types::{ - blueprint::archetypes::TensorSliceSelection, components::GammaCorrection, datatypes::TensorData, tensor_data::{TensorCastError, TensorDataType}, @@ -14,7 +13,7 @@ use re_viewer_context::{ ColormapWithRange, }; -use crate::view_class::selected_tensor_slice; +use crate::{dimension_mapping::TensorSliceSelection, view_class::selected_tensor_slice}; #[derive(thiserror::Error, Debug, PartialEq)] pub enum TensorUploadError { diff --git a/crates/viewer/re_view_tensor/src/view_class.rs b/crates/viewer/re_view_tensor/src/view_class.rs index 5568eb2b239a..3727ee9c73cf 100644 --- a/crates/viewer/re_view_tensor/src/view_class.rs +++ b/crates/viewer/re_view_tensor/src/view_class.rs @@ -5,7 +5,7 @@ use re_data_ui::tensor_summary_ui_grid_contents; use re_log_types::EntityPath; use re_types::{ blueprint::{ - archetypes::{TensorScalarMapping, TensorSliceSelection, TensorViewFit}, + archetypes::{TensorScalarMapping, TensorViewFit}, components::ViewFit, }, components::{Colormap, GammaCorrection, MagnificationFilter, TensorDimensionIndexSelection}, @@ -23,7 +23,7 @@ use re_viewer_context::{ use re_viewport_blueprint::ViewProperty; use crate::{ - dimension_mapping::load_tensor_slice_selection_and_make_valid, + dimension_mapping::TensorSliceSelection, tensor_dimension_mapper::dimension_mapping_ui, visualizer_system::{TensorSystem, TensorVisualization}, TensorDimension, @@ -147,12 +147,10 @@ Note: select the view to configure which dimensions are shown." // TODO(#6075): Listitemify if let Some(TensorVisualization { tensor, .. }) = &state.tensor { - let slice_property = ViewProperty::from_archetype::( - ctx.blueprint_db(), - ctx.blueprint_query, - view_id, - ); - let slice_selection = load_tensor_slice_selection_and_make_valid( + let slice_property = ViewProperty::from_archetype::< + re_types::blueprint::archetypes::TensorSliceSelection, + >(ctx.blueprint_db(), ctx.blueprint_query, view_id); + let slice_selection = TensorSliceSelection::load_and_make_valid( &slice_property, &TensorDimension::from_tensor_data(tensor), )?; @@ -246,12 +244,10 @@ impl TensorView { ) -> Result<(), ViewSystemExecutionError> { re_tracing::profile_function!(); - let slice_property = ViewProperty::from_archetype::( - ctx.blueprint_db(), - ctx.blueprint_query, - view_id, - ); - let slice_selection = load_tensor_slice_selection_and_make_valid( + let slice_property = ViewProperty::from_archetype::< + re_types::blueprint::archetypes::TensorSliceSelection, + >(ctx.blueprint_db(), ctx.blueprint_query, view_id); + let slice_selection = TensorSliceSelection::load_and_make_valid( &slice_property, &TensorDimension::from_tensor_data(tensor), )?; @@ -426,9 +422,6 @@ pub fn selected_tensor_slice<'a, T: Copy>( slider: _, } = slice_selection; - let empty_indices = Vec::new(); - let indices = indices.as_ref().unwrap_or(&empty_indices); - let (dwidth, dheight) = if let (Some(width), Some(height)) = (width, height) { (width.dimension, height.dimension) } else if let Some(width) = width { @@ -628,7 +621,7 @@ fn selectors_ui( }; let mut changed_indices = false; - let mut indices = slice_selection.indices.clone().unwrap_or_default(); + let mut indices = slice_selection.indices.clone(); for index_slider in slider { let dim = &shape[index_slider.dimension as usize]; diff --git a/crates/viewer/re_viewport_blueprint/src/view.rs b/crates/viewer/re_viewport_blueprint/src/view.rs index e040eadcf27a..7d223dff19fb 100644 --- a/crates/viewer/re_viewport_blueprint/src/view.rs +++ b/crates/viewer/re_viewport_blueprint/src/view.rs @@ -137,19 +137,10 @@ impl ViewBlueprint { // This is a required component. Note that when loading views we crawl the subtree and so // cleared empty views paths may exist transiently. The fact that they have an empty class_identifier // is the marker that the have been cleared and not an error. - let class_identifier = results.component_instance::(0)?; - - let blueprint_archetypes::ViewBlueprint { - class_identifier, - display_name, - space_origin, - visible, - } = blueprint_archetypes::ViewBlueprint { - class_identifier, - display_name: results.component_instance::(0), - space_origin: results.component_instance::(0), - visible: results.component_instance::(0), - }; + let class_identifier = results.component_mono::()?; + let display_name = results.component_mono::(); + let space_origin = results.component_mono::(); + let visible = results.component_mono::(); let space_origin = space_origin.map_or_else(EntityPath::root, |origin| origin.0.into()); let class_identifier: ViewClassIdentifier = class_identifier.0.as_str().into(); @@ -373,12 +364,13 @@ impl ViewBlueprint { blueprint_query, self.id, ); - let ranges = property.component_array(); + let ranges = property.component_array::(); let time_range = ranges.ok().flatten().and_then(|ranges| { - blueprint_archetypes::VisibleTimeRanges { ranges } - .range_for_timeline(active_timeline.name().as_str()) - .cloned() + ranges + .iter() + .find(|range| range.timeline.as_str() == active_timeline.name().as_str()) + .map(|range| range.range.clone()) }); time_range.map_or_else( || { diff --git a/crates/viewer/re_viewport_blueprint/src/viewport_blueprint.rs b/crates/viewer/re_viewport_blueprint/src/viewport_blueprint.rs index 2142a7c4acbd..b2594f754134 100644 --- a/crates/viewer/re_viewport_blueprint/src/viewport_blueprint.rs +++ b/crates/viewer/re_viewport_blueprint/src/viewport_blueprint.rs @@ -93,19 +93,11 @@ impl ViewportBlueprint { blueprint_archetypes::ViewportBlueprint::all_components().iter(), ); - let blueprint_archetypes::ViewportBlueprint { - root_container, - maximized, - auto_layout, - auto_views, - past_viewer_recommendations, - } = blueprint_archetypes::ViewportBlueprint { - root_container: results.component_instance(0), - maximized: results.component_instance(0), - auto_layout: results.component_instance(0), - auto_views: results.component_instance(0), - past_viewer_recommendations: results.component_batch(), - }; + let root_container = results.component_mono::(); + let maximized = results.component_mono::(); + let auto_layout = results.component_mono::(); + let auto_views = results.component_mono::(); + let past_viewer_recommendations = results.component_batch::(); let root_container: Option = root_container.map(|id| id.0.into()); re_log::trace_once!("Loaded root_container: {root_container:?}"); From 2e1a59e7232acfa3e06bf2b2b730e2d94063c88e Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Thu, 16 Jan 2025 09:17:32 +0100 Subject: [PATCH 46/57] Remove unused `num_instances()` method (#8702) ### What This has been dead-code in our Python SDK for a very long time. No longer. --------- Co-authored-by: Clement Rey --- .../reference/migration/migration-0-22.md | 15 +++++++++--- rerun_py/rerun_sdk/rerun/_baseclasses.py | 24 +------------------ rerun_py/rerun_sdk/rerun/_log.py | 16 +------------ .../rerun/components/view_coordinates_ext.py | 4 ---- 4 files changed, 14 insertions(+), 45 deletions(-) diff --git a/docs/content/reference/migration/migration-0-22.md b/docs/content/reference/migration/migration-0-22.md index 265b1876cadf..09806a9e8e56 100644 --- a/docs/content/reference/migration/migration-0-22.md +++ b/docs/content/reference/migration/migration-0-22.md @@ -1,9 +1,9 @@ --- -title: Migrating from 0.20 to 0.21 -order: 989 +title: Migrating from 0.21 to 0.22 +order: 988 --- -### Previously deprecated `DisconnectedSpace` archetype/component got now removed. +### Previously deprecated `DisconnectedSpace` archetype/component got now removed The deprecated `DisconnectedSpace` archetype and `DisconnectedSpace` component have been removed. To achieve the same effect, you can log any of the following "invalid" transforms: @@ -16,3 +16,12 @@ Previously, the `DisconnectedSpace` archetype played a double role by governing This led to a lot of complexity and often broke or caused confusion (see https://github.com/rerun-io/rerun/issues/6817, https://github.com/rerun-io/rerun/issues/4465, https://github.com/rerun-io/rerun/issues/4221). By now, explicit blueprints offer a better way to express which views should be spawned and what content they should query. (you can learn more about blueprints [here](https://rerun.io/docs/getting-started/configure-the-viewer/through-code-tutorial)). + + +### Removed `num_instances` keyword argument to `rr.log_components()` + +For historical reasons, the `rr.log_components()` function of the Python SDK accepts an optional, keyword-only argument `num_instances`. +It was no longer used for several releases, so we removed it. + +**Note**: although `rr.log_components()` is technically a public API, it is undocumented, and we discourage using it. +For logging custom components, use [`rr.AnyValue`](https://ref.rerun.io/docs/python/main/common/custom_data/#rerun.AnyValues) and [`rr.AnyBatchValue`](https://ref.rerun.io/docs/python/main/common/custom_data/#rerun.AnyBatchValue). diff --git a/rerun_py/rerun_sdk/rerun/_baseclasses.py b/rerun_py/rerun_sdk/rerun/_baseclasses.py index 9c5056e64c74..efe7b52852ca 100644 --- a/rerun_py/rerun_sdk/rerun/_baseclasses.py +++ b/rerun_py/rerun_sdk/rerun/_baseclasses.py @@ -147,13 +147,7 @@ def as_arrow_array(self) -> pa.Array: class AsComponents(Protocol): - """ - Describes interface for interpreting an object as a bundle of Components. - - Note: the `num_instances()` function is an optional part of this interface. The method does not need to be - implemented as it is only used after checking for its existence. (There is unfortunately no way to express this - correctly with the Python typing system, see ). - """ + """Describes interface for interpreting an object as a bundle of Components.""" def as_component_batches(self) -> Iterable[ComponentBatchLike]: """ @@ -198,22 +192,6 @@ def indicator(cls) -> ComponentBatchLike: return IndicatorComponentBatch(cls.archetype_name()) - def num_instances(self) -> int: - """ - The number of instances that make up the batch. - - Part of the `AsComponents` logging interface. - """ - num_instances = 0 - for fld in fields(type(self)): - if "component" in fld.metadata: - try: - num_instances = max(num_instances, len(getattr(self, fld.name))) - except TypeError: # Happens for indicator batches. - num_instances = max(num_instances, 1) - - return num_instances - def as_component_batches(self) -> Iterable[ComponentBatchLike]: """ Return all the component batches that make up the archetype. diff --git a/rerun_py/rerun_sdk/rerun/_log.py b/rerun_py/rerun_sdk/rerun/_log.py index 5dc405c4a4ac..b624e2ab3090 100644 --- a/rerun_py/rerun_sdk/rerun/_log.py +++ b/rerun_py/rerun_sdk/rerun/_log.py @@ -172,15 +172,9 @@ def log( f"but got {type(entity)} instead." ) - if hasattr(entity, "num_instances"): - num_instances = entity.num_instances() - else: - num_instances = None - log_components( entity_path=entity_path, components=components, - num_instances=num_instances, static=static, recording=recording, # NOLINT ) @@ -191,7 +185,6 @@ def log_components( entity_path: str | list[str], components: Iterable[ComponentBatchLike], *, - num_instances: int | None = None, timeless: bool = False, static: bool = False, recording: RecordingStream | None = None, @@ -216,11 +209,7 @@ def log_components( See for more on entity paths. components: - A collection of `ComponentBatchLike` objects that - - num_instances: - Optional. The number of instances in each batch. If not provided, the max of all - components will be used instead. + A collection of `ComponentBatchLike` objects. timeless: Deprecated. Refer to `static` instead. @@ -263,9 +252,6 @@ def log_components( descriptors = [comp.component_descriptor() for comp in components] arrow_arrays = [comp.as_arrow_array() for comp in components] - if num_instances is None: - num_instances = max(len(arr) for arr in arrow_arrays) - if isinstance(entity_path, list): entity_path = bindings.new_entity_path([str(part) for part in entity_path]) diff --git a/rerun_py/rerun_sdk/rerun/components/view_coordinates_ext.py b/rerun_py/rerun_sdk/rerun/components/view_coordinates_ext.py index abc1559fde84..c98b7d1ad6fe 100644 --- a/rerun_py/rerun_sdk/rerun/components/view_coordinates_ext.py +++ b/rerun_py/rerun_sdk/rerun/components/view_coordinates_ext.py @@ -36,10 +36,6 @@ def as_component_batches(self) -> Iterable[ComponentBatchLike]: return ViewCoordinates(cast(ViewCoordinatesComponent, self)).as_component_batches() - def num_instances(self) -> int: - # Always a mono-component - return 1 - # # This section is generated by running `scripts/generate_view_coordinate_defs.py --python` # The following declarations are replaced in `deferred_patch_class`. From e99a507aad1131a48f5ee600210f94f050f503e7 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 16 Jan 2025 10:12:19 +0100 Subject: [PATCH 47/57] Port `TransportChunk` to `arrow-rs` (#8700) * Part of #3741 * [x] Tested that it does not regress https://github.com/rerun-io/rerun/issues/8668 This makes `TransportChunk` a wrapper around an arrow `RecordBatch`. ### Future work * Remove `TransportChunk` and replace it with an extension trait on `RecordBatch` * Simplify the dataframe API to always return a full `RecordBatch` (adding a schema to the rows is basically free now) --- Cargo.lock | 3 + crates/store/re_chunk/Cargo.toml | 3 - crates/store/re_chunk/src/arrow.rs | 40 --- crates/store/re_chunk/src/chunk.rs | 18 +- .../re_chunk/src/concat_record_batches.rs | 40 --- crates/store/re_chunk/src/lib.rs | 4 - crates/store/re_chunk/src/transport.rs | 265 ++++++-------- crates/store/re_chunk_store/src/dataframe.rs | 27 +- crates/store/re_dataframe/Cargo.toml | 1 + crates/store/re_dataframe/examples/query.rs | 3 +- crates/store/re_dataframe/src/engine.rs | 10 +- crates/store/re_dataframe/src/lib.rs | 8 +- crates/store/re_dataframe/src/query.rs | 332 +++++++++--------- crates/store/re_format_arrow/src/lib.rs | 20 +- crates/store/re_grpc_client/src/lib.rs | 130 +++---- .../re_log_encoding/src/codec/wire/decoder.rs | 2 +- .../re_log_encoding/src/codec/wire/encoder.rs | 18 +- crates/store/re_log_types/src/arrow_msg.rs | 2 +- crates/top/rerun/Cargo.toml | 2 + crates/top/rerun/src/lib.rs | 2 + .../snippets/all/reference/dataframe_query.rs | 3 +- examples/rust/dataframe_query/src/main.rs | 11 +- rerun_py/Cargo.toml | 2 +- rerun_py/src/dataframe.rs | 32 +- rerun_py/src/remote.rs | 23 +- 25 files changed, 441 insertions(+), 560 deletions(-) delete mode 100644 crates/store/re_chunk/src/arrow.rs delete mode 100644 crates/store/re_chunk/src/concat_record_batches.rs diff --git a/Cargo.lock b/Cargo.lock index 75faee5fd61a..250bf25c9fdf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5921,6 +5921,7 @@ dependencies = [ "re_arrow_util", "re_chunk", "re_chunk_store", + "re_format_arrow", "re_log", "re_log_encoding", "re_log_types", @@ -7322,6 +7323,7 @@ name = "rerun" version = "0.22.0-alpha.1+dev" dependencies = [ "anyhow", + "arrow", "clap", "document-features", "env_logger", @@ -7342,6 +7344,7 @@ dependencies = [ "re_entity_db", "re_error", "re_format", + "re_format_arrow", "re_log", "re_log_encoding", "re_log_types", diff --git a/crates/store/re_chunk/Cargo.toml b/crates/store/re_chunk/Cargo.toml index d3e285ca2a53..1907fa355e48 100644 --- a/crates/store/re_chunk/Cargo.toml +++ b/crates/store/re_chunk/Cargo.toml @@ -30,9 +30,6 @@ serde = [ "re_types_core/serde", ] -## Enable conversion to and from arrow-rs types -arrow = ["arrow2/arrow"] - [dependencies] diff --git a/crates/store/re_chunk/src/arrow.rs b/crates/store/re_chunk/src/arrow.rs deleted file mode 100644 index 4802c2170484..000000000000 --- a/crates/store/re_chunk/src/arrow.rs +++ /dev/null @@ -1,40 +0,0 @@ -use arrow::{ - array::{make_array, RecordBatch}, - error::ArrowError, -}; - -use crate::TransportChunk; - -impl TransportChunk { - /// Create an arrow-rs [`RecordBatch`] containing the data from this [`TransportChunk`]. - /// - /// This is a "fairly" cheap operation, as it does not copy the underlying arrow data, - /// but does incur overhead of generating an alternative representation of the arrow- - /// related rust structures that refer to those data buffers. - pub fn try_to_arrow_record_batch(&self) -> Result { - let columns: Vec<_> = self - .columns() - .iter() - .map(|arr2_array| make_array(arrow2::array::to_data(*arr2_array))) - .collect(); - - RecordBatch::try_new(self.schema(), columns) - } - - /// Create a [`TransportChunk`] from an arrow-rs [`RecordBatch`]. - /// - /// This is a "fairly" cheap operation, as it does not copy the underlying arrow data, - /// but does incur overhead of generating an alternative representation of the arrow- - /// related rust structures that refer to those data buffers. - pub fn from_arrow_record_batch(batch: &RecordBatch) -> Self { - let columns: Vec<_> = batch - .columns() - .iter() - .map(|array| arrow2::array::from_data(&array.to_data())) - .collect(); - - let data = arrow2::chunk::Chunk::new(columns); - - Self::new(batch.schema(), data) - } -} diff --git a/crates/store/re_chunk/src/chunk.rs b/crates/store/re_chunk/src/chunk.rs index 72827a1b81e5..31cdc5fe5fdc 100644 --- a/crates/store/re_chunk/src/chunk.rs +++ b/crates/store/re_chunk/src/chunk.rs @@ -956,13 +956,29 @@ impl Chunk { } } - /// Unconditionally inserts an [`Arrow2ListArray`] as a component column. + /// Unconditionally inserts an [`ArrowListArray`] as a component column. /// /// Removes and replaces the column if it already exists. /// /// This will fail if the end result is malformed in any way -- see [`Self::sanity_check`]. #[inline] pub fn add_component( + &mut self, + component_desc: ComponentDescriptor, + list_array: ArrowListArray, + ) -> ChunkResult<()> { + self.components + .insert_descriptor(component_desc, list_array); + self.sanity_check() + } + + /// Unconditionally inserts an [`Arrow2ListArray`] as a component column. + /// + /// Removes and replaces the column if it already exists. + /// + /// This will fail if the end result is malformed in any way -- see [`Self::sanity_check`]. + #[inline] + pub fn add_component_arrow2( &mut self, component_desc: ComponentDescriptor, list_array: Arrow2ListArray, diff --git a/crates/store/re_chunk/src/concat_record_batches.rs b/crates/store/re_chunk/src/concat_record_batches.rs deleted file mode 100644 index beae93c6a655..000000000000 --- a/crates/store/re_chunk/src/concat_record_batches.rs +++ /dev/null @@ -1,40 +0,0 @@ -use crate::TransportChunk; - -use arrow::datatypes::Schema as ArrowSchema; -use arrow2::chunk::Chunk as Arrow2Chunk; - -/// Concatenate multiple [`TransportChunk`]s into one. -/// -/// This is a temporary method that we use while waiting to migrate towards `arrow-rs`. -/// * `arrow2` doesn't have a `RecordBatch` type, therefore we emulate that using our `TransportChunk`s. -/// * `arrow-rs` does have one, and it natively supports concatenation. -pub fn concatenate_record_batches( - schema: impl Into, - batches: &[TransportChunk], -) -> anyhow::Result { - let schema: ArrowSchema = schema.into(); - anyhow::ensure!( - batches - .iter() - .all(|batch| batch.schema_ref().as_ref() == &schema), - "concatenate_record_batches: all batches must have the same schema" - ); - - let mut output_columns = Vec::new(); - - if !batches.is_empty() { - for (i, _field) in schema.fields.iter().enumerate() { - let arrays: Option> = batches.iter().map(|batch| batch.column(i)).collect(); - let arrays = arrays.ok_or_else(|| { - anyhow::anyhow!("concatenate_record_batches: all batches must have the same schema") - })?; - let array = re_arrow_util::arrow2_util::concat_arrays(&arrays)?; - output_columns.push(array); - } - } - - Ok(TransportChunk::new( - schema, - Arrow2Chunk::new(output_columns), - )) -} diff --git a/crates/store/re_chunk/src/lib.rs b/crates/store/re_chunk/src/lib.rs index 30ff3c5820da..c02fbbdbf75b 100644 --- a/crates/store/re_chunk/src/lib.rs +++ b/crates/store/re_chunk/src/lib.rs @@ -6,7 +6,6 @@ mod builder; mod chunk; -pub mod concat_record_batches; mod helpers; mod id; mod iter; @@ -21,9 +20,6 @@ mod transport; #[cfg(not(target_arch = "wasm32"))] mod batcher; -#[cfg(feature = "arrow")] -mod arrow; - pub use self::builder::{ChunkBuilder, TimeColumnBuilder}; pub use self::chunk::{ Chunk, ChunkComponents, ChunkError, ChunkResult, TimeColumn, TimeColumnError, diff --git a/crates/store/re_chunk/src/transport.rs b/crates/store/re_chunk/src/transport.rs index d157c8b52f98..90ea338e21d9 100644 --- a/crates/store/re_chunk/src/transport.rs +++ b/crates/store/re_chunk/src/transport.rs @@ -1,26 +1,23 @@ -use std::sync::Arc; - use arrow::{ array::{ - ArrayRef as ArrowArrayRef, RecordBatch as ArrowRecordBatch, StructArray as ArrowStructArray, + Array as ArrowArray, ArrayRef as ArrowArrayRef, ListArray as ArrowListArray, + RecordBatch as ArrowRecordBatch, StructArray as ArrowStructArray, + }, + datatypes::{ + DataType as ArrowDatatype, Field as ArrowField, Fields as ArrowFields, + Schema as ArrowSchema, TimeUnit as ArrowTimeUnit, }, - datatypes::{Field as ArrowField, Schema as ArrowSchema, SchemaRef as ArrowSchemaRef}, -}; -use arrow2::{ - array::{Array as Arrow2Array, ListArray as Arrow2ListArray}, - chunk::Chunk as Arrow2Chunk, - datatypes::{DataType as Arrow2Datatype, TimeUnit as Arrow2TimeUnit}, }; use itertools::Itertools; use nohash_hasher::IntMap; use tap::Tap as _; -use re_arrow_util::{ - arrow_util::into_arrow_ref, Arrow2ArrayDowncastRef as _, ArrowArrayDowncastRef as _, -}; +use re_arrow_util::{arrow_util::into_arrow_ref, ArrowArrayDowncastRef as _}; use re_byte_size::SizeBytes as _; use re_log_types::{EntityPath, Timeline}; -use re_types_core::{Component as _, ComponentDescriptor, Loggable as _}; +use re_types_core::{ + arrow_helpers::as_array_ref, Component as _, ComponentDescriptor, Loggable as _, +}; use crate::{chunk::ChunkComponents, Chunk, ChunkError, ChunkId, ChunkResult, RowId, TimeColumn}; @@ -30,7 +27,10 @@ pub type ArrowMetadata = std::collections::HashMap; /// A [`Chunk`] that is ready for transport. Obtained by calling [`Chunk::to_transport`]. /// -/// Implemented as an Arrow dataframe: a schema and a batch. +/// It contains a schema with a matching number of columns, all of the same length. +/// +/// This is just a wrapper around an [`ArrowRecordBatch`], with some helper functions on top. +/// It can be converted to and from [`ArrowRecordBatch`] without overhead. /// /// Use the `Display` implementation to dump the chunk as a nicely formatted table. /// @@ -39,75 +39,46 @@ pub type ArrowMetadata = std::collections::HashMap; /// This means we have to be very careful when checking the validity of the data: slipping corrupt /// data into the store could silently break all the index search logic (e.g. think of a chunk /// claiming to be sorted while it is in fact not). +// TODO(emilk): remove this, and replace it with a trait extension type for `ArrowRecordBatch`. #[derive(Debug, Clone)] pub struct TransportChunk { - /// The schema of the dataframe, and all chunk-level and field-level metadata. - /// - /// Take a look at the `TransportChunk::CHUNK_METADATA_*` and `TransportChunk::FIELD_METADATA_*` - /// constants for more information about available metadata. - schema: ArrowSchemaRef, - - /// All the control, time and component data. - data: Arrow2Chunk>, + batch: ArrowRecordBatch, } impl std::fmt::Display for TransportChunk { #[inline] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - // TODO(#3741): simplify code when we have migrated to arrow-rs - re_format_arrow::format_dataframe( - &self.schema.metadata.clone().into_iter().collect(), - &self.schema.fields, - &self - .data - .iter() - .map(|list_array| ArrowArrayRef::from(list_array.clone())) - .collect_vec(), - f.width(), - ) - .fmt(f) + re_format_arrow::format_record_batch_with_width(self, f.width()).fmt(f) } } -impl TransportChunk { - pub fn new( - schema: impl Into, - columns: impl Into>>, - ) -> Self { - Self { - schema: schema.into(), - data: columns.into(), - } +impl AsRef for TransportChunk { + #[inline] + fn as_ref(&self) -> &ArrowRecordBatch { + &self.batch + } +} + +impl std::ops::Deref for TransportChunk { + type Target = ArrowRecordBatch; + + #[inline] + fn deref(&self) -> &ArrowRecordBatch { + &self.batch } } impl From for TransportChunk { + #[inline] fn from(batch: ArrowRecordBatch) -> Self { - Self::new( - batch.schema(), - Arrow2Chunk::new( - batch - .columns() - .iter() - .map(|column| column.clone().into()) - .collect(), - ), - ) + Self { batch } } } -impl TryFrom for ArrowRecordBatch { - type Error = arrow::error::ArrowError; - - fn try_from(chunk: TransportChunk) -> Result { - let TransportChunk { schema, data } = chunk; - Self::try_new( - schema, - data.columns() - .iter() - .map(|column| column.clone().into()) - .collect(), - ) +impl From for ArrowRecordBatch { + #[inline] + fn from(chunk: TransportChunk) -> Self { + chunk.batch } } @@ -303,17 +274,14 @@ impl TransportChunk { impl TransportChunk { #[inline] pub fn id(&self) -> ChunkResult { - if let Some(id) = self.schema.metadata.get(Self::CHUNK_METADATA_KEY_ID) { + if let Some(id) = self.metadata().get(Self::CHUNK_METADATA_KEY_ID) { let id = u128::from_str_radix(id, 16).map_err(|err| ChunkError::Malformed { reason: format!("cannot deserialize chunk id: {err}"), })?; Ok(ChunkId::from_u128(id)) } else { Err(crate::ChunkError::Malformed { - reason: format!( - "chunk id missing from metadata ({:?})", - self.schema.metadata - ), + reason: format!("chunk id missing from metadata ({:?})", self.metadata()), }) } } @@ -321,7 +289,7 @@ impl TransportChunk { #[inline] pub fn entity_path(&self) -> ChunkResult { match self - .schema + .schema_ref() .metadata .get(Self::CHUNK_METADATA_KEY_ENTITY_PATH) { @@ -329,32 +297,29 @@ impl TransportChunk { None => Err(crate::ChunkError::Malformed { reason: format!( "entity path missing from metadata ({:?})", - self.schema.metadata + self.schema_ref().metadata ), }), } } + /// The size in bytes of the data, once loaded in memory, in chunk-level. + /// + /// This is stored in the metadata. Returns `None` if that key is not set. #[inline] pub fn heap_size_bytes(&self) -> Option { - self.schema - .metadata + self.metadata() .get(Self::CHUNK_METADATA_KEY_HEAP_SIZE_BYTES) .and_then(|s| s.parse::().ok()) } #[inline] - pub fn schema(&self) -> ArrowSchemaRef { - self.schema.clone() + pub fn fields(&self) -> &ArrowFields { + &self.schema_ref().fields } - #[inline] - pub fn schema_ref(&self) -> &ArrowSchemaRef { - &self.schema - } - - pub fn insert_metadata(&mut self, key: String, value: String) { - Arc::make_mut(&mut self.schema).metadata.insert(key, value); + pub fn metadata(&self) -> &std::collections::HashMap { + &self.batch.schema_ref().metadata } /// Looks in the chunk metadata for the `IS_SORTED` marker. @@ -363,17 +328,10 @@ impl TransportChunk { /// This is fine, although wasteful. #[inline] pub fn is_sorted(&self) -> bool { - self.schema - .metadata + self.metadata() .contains_key(Self::CHUNK_METADATA_MARKER_IS_SORTED_BY_ROW_ID) } - /// Access specific column - #[inline] - pub fn column(&self, index: usize) -> Option<&dyn Arrow2Array> { - self.data.get(index).map(|c| c.as_ref()) - } - /// Iterates all columns of the specified `kind`. /// /// See: @@ -384,69 +342,48 @@ impl TransportChunk { fn columns_of_kind<'a>( &'a self, kind: &'a str, - ) -> impl Iterator)> + 'a { - self.schema - .fields - .iter() - .enumerate() - .filter_map(|(i, field)| { - let actual_kind = field.metadata().get(Self::FIELD_METADATA_KEY_KIND); - (actual_kind.map(|s| s.as_str()) == Some(kind)) - .then(|| { - self.data - .columns() - .get(i) - .map(|column| (field.as_ref(), column)) - }) - .flatten() - }) - } - - #[inline] - pub fn fields_and_columns( - &self, - ) -> impl Iterator)> + '_ { - self.schema - .fields - .iter() - .enumerate() - .filter_map(|(i, field)| { - self.data - .columns() - .get(i) - .map(|column| (field.as_ref(), column)) - }) + ) -> impl Iterator + 'a { + self.fields().iter().enumerate().filter_map(|(i, field)| { + let actual_kind = field.metadata().get(Self::FIELD_METADATA_KEY_KIND); + (actual_kind.map(|s| s.as_str()) == Some(kind)) + .then(|| { + self.batch + .columns() + .get(i) + .map(|column| (field.as_ref(), column)) + }) + .flatten() + }) } #[inline] - pub fn columns(&self) -> Vec<&dyn Arrow2Array> { - self.data.iter().map(|c| c.as_ref()).collect() + pub fn fields_and_columns(&self) -> impl Iterator + '_ { + self.fields().iter().enumerate().filter_map(|(i, field)| { + self.batch + .columns() + .get(i) + .map(|column| (field.as_ref(), column)) + }) } /// Iterates all control columns present in this chunk. #[inline] - pub fn controls(&self) -> impl Iterator)> { + pub fn controls(&self) -> impl Iterator { self.columns_of_kind(Self::FIELD_METADATA_VALUE_KIND_CONTROL) } /// Iterates all data columns present in this chunk. #[inline] - pub fn components(&self) -> impl Iterator)> { + pub fn components(&self) -> impl Iterator { self.columns_of_kind(Self::FIELD_METADATA_VALUE_KIND_DATA) } /// Iterates all timeline columns present in this chunk. #[inline] - pub fn timelines(&self) -> impl Iterator)> { + pub fn timelines(&self) -> impl Iterator { self.columns_of_kind(Self::FIELD_METADATA_VALUE_KIND_TIME) } - /// How many columns in total? Includes control, time, and component columns. - #[inline] - pub fn num_columns(&self) -> usize { - self.data.columns().len() - } - #[inline] pub fn num_controls(&self) -> usize { self.controls().count() @@ -461,18 +398,13 @@ impl TransportChunk { pub fn num_components(&self) -> usize { self.components().count() } - - #[inline] - pub fn num_rows(&self) -> usize { - self.data.len() - } } impl Chunk { /// Prepare the [`Chunk`] for transport. /// /// It is probably a good idea to sort the chunk first. - pub fn to_transport(&self) -> ChunkResult { + pub fn to_record_batch(&self) -> ChunkResult { self.sanity_check()?; re_tracing::profile_function!(format!( @@ -493,7 +425,7 @@ impl Chunk { let mut fields: Vec = vec![]; let mut metadata = std::collections::HashMap::default(); - let mut columns: Vec> = + let mut columns: Vec = Vec::with_capacity(1 /* row_ids */ + timelines.len() + components.len()); // Chunk-level metadata @@ -533,7 +465,7 @@ impl Chunk { }), ), ); - columns.push(into_arrow_ref(row_ids.clone()).into()); + columns.push(into_arrow_ref(row_ids.clone())); } // Timelines @@ -572,7 +504,7 @@ impl Chunk { for (field, times) in timelines { fields.push(field); - columns.push(times.into()); + columns.push(times); } } @@ -584,9 +516,11 @@ impl Chunk { .values() .flat_map(|per_desc| per_desc.iter()) .map(|(component_desc, list_array)| { + let list_array = ArrowListArray::from(list_array.clone()); + let field = ArrowField::new( component_desc.component_name.to_string(), - list_array.data_type().clone().into(), + list_array.data_type().clone(), true, ) .with_metadata({ @@ -597,9 +531,7 @@ impl Chunk { metadata }); - let data = list_array.clone().boxed(); - - (field, data) + (field, as_array_ref(list_array)) }) .collect_vec(); @@ -614,11 +546,19 @@ impl Chunk { let schema = ArrowSchema::new_with_metadata(fields, metadata); - Ok(TransportChunk::new(schema, Arrow2Chunk::new(columns))) + Ok(ArrowRecordBatch::try_new(schema.into(), columns)?) + } + + /// Prepare the [`Chunk`] for transport. + /// + /// It is probably a good idea to sort the chunk first. + pub fn to_transport(&self) -> ChunkResult { + let record_batch = self.to_record_batch()?; + Ok(TransportChunk::from(record_batch)) } pub fn from_record_batch(batch: ArrowRecordBatch) -> ChunkResult { - Self::from_transport(&batch.into()) + Self::from_transport(&TransportChunk::from(batch)) } pub fn from_transport(transport: &TransportChunk) -> ChunkResult { @@ -647,7 +587,7 @@ impl Chunk { (field.name() == RowId::descriptor().component_name.as_str()).then_some(column) }) else { return Err(ChunkError::Malformed { - reason: format!("missing row_id column ({:?})", transport.schema), + reason: format!("missing row_id column ({:?})", transport.schema_ref()), }); }; @@ -671,9 +611,9 @@ impl Chunk { for (field, column) in transport.timelines() { // See also [`Timeline::datatype`] - let timeline = match column.data_type().to_logical_type() { - Arrow2Datatype::Int64 => Timeline::new_sequence(field.name().as_str()), - Arrow2Datatype::Timestamp(Arrow2TimeUnit::Nanosecond, None) => { + let timeline = match column.data_type() { + ArrowDatatype::Int64 => Timeline::new_sequence(field.name().as_str()), + ArrowDatatype::Timestamp(ArrowTimeUnit::Nanosecond, None) => { Timeline::new_temporal(field.name().as_str()) } _ => { @@ -717,7 +657,7 @@ impl Chunk { for (field, column) in transport.components() { let column = column - .downcast_array2_ref::>() + .downcast_array_ref::() .ok_or_else(|| ChunkError::Malformed { reason: format!( "The outer array in a chunked component batch must be a sparse list, got {:?}", @@ -728,7 +668,7 @@ impl Chunk { let component_desc = TransportChunk::component_descriptor_from_field(field); if components - .insert_descriptor_arrow2(component_desc, column.clone()) + .insert_descriptor(component_desc, column.clone()) .is_some() { return Err(ChunkError::Malformed { @@ -782,7 +722,7 @@ impl Chunk { Ok(re_log_types::ArrowMsg { chunk_id: re_tuid::Tuid::from_u128(self.id().as_u128()), timepoint_max: self.timepoint_max(), - batch: transport.try_into()?, + batch: transport.into(), on_release: None, }) } @@ -871,11 +811,7 @@ mod tests { for _ in 0..3 { let chunk_in_transport = chunk_before.to_transport()?; - #[cfg(feature = "arrow")] - let chunk_after = - Chunk::from_record_batch(chunk_in_transport.try_to_arrow_record_batch()?)?; - #[cfg(not(feature = "arrow"))] - let chunk_after = Chunk::from_transport(&chunk_in_transport)?; + let chunk_after = Chunk::from_record_batch(chunk_in_transport.clone().into())?; assert_eq!( chunk_in_transport.entity_path()?, @@ -926,12 +862,7 @@ mod tests { eprintln!("{chunk_in_transport}"); eprintln!("{chunk_after}"); - #[cfg(not(feature = "arrow"))] - { - // This will fail when round-tripping all the way to record-batch - // the below check should always pass regardless. - assert_eq!(chunk_before, chunk_after); - } + assert_eq!(chunk_before, chunk_after); assert!(chunk_before.are_equal_ignoring_extension_types(&chunk_after)); diff --git a/crates/store/re_chunk_store/src/dataframe.rs b/crates/store/re_chunk_store/src/dataframe.rs index 0484798837cb..3ff35d366dca 100644 --- a/crates/store/re_chunk_store/src/dataframe.rs +++ b/crates/store/re_chunk_store/src/dataframe.rs @@ -4,6 +4,7 @@ use std::collections::{BTreeMap, BTreeSet}; use std::ops::Deref; use std::ops::DerefMut; +use arrow::datatypes::Field as ArrowField; use arrow2::{ array::ListArray as ArrowListArray, datatypes::{DataType as Arrow2Datatype, Field as Arrow2Field}, @@ -43,7 +44,7 @@ impl ColumnDescriptor { } #[inline] - pub fn datatype(&self) -> Arrow2Datatype { + pub fn arrow2_datatype(&self) -> Arrow2Datatype { match self { Self::Time(descr) => descr.datatype.clone(), Self::Component(descr) => descr.returned_datatype(), @@ -51,13 +52,21 @@ impl ColumnDescriptor { } #[inline] - pub fn to_arrow_field(&self) -> Arrow2Field { + pub fn to_arrow_field(&self) -> ArrowField { match self { Self::Time(descr) => descr.to_arrow_field(), Self::Component(descr) => descr.to_arrow_field(), } } + #[inline] + pub fn to_arrow2_field(&self) -> Arrow2Field { + match self { + Self::Time(descr) => descr.to_arrow2_field(), + Self::Component(descr) => descr.to_arrow2_field(), + } + } + #[inline] pub fn short_name(&self) -> String { match self { @@ -150,7 +159,12 @@ impl TimeColumnDescriptor { } #[inline] - pub fn to_arrow_field(&self) -> Arrow2Field { + pub fn to_arrow_field(&self) -> ArrowField { + self.to_arrow2_field().into() + } + + #[inline] + pub fn to_arrow2_field(&self) -> Arrow2Field { let Self { timeline, datatype } = self; let nullable = true; // Time column must be nullable since static data doesn't have a time. Arrow2Field::new(timeline.name().to_string(), datatype.clone(), nullable) @@ -351,7 +365,12 @@ impl ComponentColumnDescriptor { } #[inline] - pub fn to_arrow_field(&self) -> Arrow2Field { + pub fn to_arrow_field(&self) -> ArrowField { + self.to_arrow2_field().into() + } + + #[inline] + pub fn to_arrow2_field(&self) -> Arrow2Field { let entity_path = &self.entity_path; let descriptor = ComponentDescriptor { archetype_name: self.archetype_name, diff --git a/crates/store/re_dataframe/Cargo.toml b/crates/store/re_dataframe/Cargo.toml index cd62b928e2b0..8574d7690baf 100644 --- a/crates/store/re_dataframe/Cargo.toml +++ b/crates/store/re_dataframe/Cargo.toml @@ -29,6 +29,7 @@ default = [] re_arrow_util.workspace = true re_chunk.workspace = true re_chunk_store.workspace = true +re_format_arrow.workspace = true re_log.workspace = true re_log_encoding.workspace = true re_log_types.workspace = true diff --git a/crates/store/re_dataframe/examples/query.rs b/crates/store/re_dataframe/examples/query.rs index f187319c2147..9589452ed691 100644 --- a/crates/store/re_dataframe/examples/query.rs +++ b/crates/store/re_dataframe/examples/query.rs @@ -6,6 +6,7 @@ use re_dataframe::{ ChunkStoreConfig, EntityPathFilter, QueryEngine, QueryExpression, ResolvedTimeRange, SparseFillStrategy, StoreKind, TimeInt, Timeline, }; +use re_format_arrow::format_record_batch; use re_log_encoding::VersionPolicy; fn main() -> anyhow::Result<()> { @@ -70,7 +71,7 @@ fn main() -> anyhow::Result<()> { let query_handle = engine.query(query.clone()); // eprintln!("{:#?}", query_handle.selected_contents()); for batch in query_handle.into_batch_iter() { - eprintln!("{batch}"); + eprintln!("{}", format_record_batch(&batch)); } } diff --git a/crates/store/re_dataframe/src/engine.rs b/crates/store/re_dataframe/src/engine.rs index 69a9ea6bf6ee..71d15b35506a 100644 --- a/crates/store/re_dataframe/src/engine.rs +++ b/crates/store/re_dataframe/src/engine.rs @@ -1,6 +1,6 @@ use std::collections::BTreeMap; -use re_chunk::{EntityPath, TransportChunk}; +use re_chunk::EntityPath; use re_chunk_store::{ ChunkStore, ChunkStoreConfig, ChunkStoreHandle, ColumnDescriptor, QueryExpression, }; @@ -13,14 +13,6 @@ use crate::QueryHandle; #[allow(unused_imports)] use re_chunk_store::ComponentColumnDescriptor; -// --- - -// TODO(#3741): `arrow2` has no concept of a `RecordBatch`, so for now we just use our trustworthy -// `TransportChunk` type until we migrate to `arrow-rs`. -// `TransportChunk` maps 1:1 to `RecordBatch` so the switch (and the compatibility layer in the meantime) -// will be trivial. -pub type RecordBatch = TransportChunk; - // --- Queries --- /// A handle to our user-facing query engine. diff --git a/crates/store/re_dataframe/src/lib.rs b/crates/store/re_dataframe/src/lib.rs index 58e2d4c4dddf..7453cf74d66b 100644 --- a/crates/store/re_dataframe/src/lib.rs +++ b/crates/store/re_dataframe/src/lib.rs @@ -3,15 +3,11 @@ mod engine; mod query; -pub use self::engine::{QueryEngine, RecordBatch}; +pub use self::engine::QueryEngine; pub use self::query::QueryHandle; #[doc(no_inline)] -pub use self::external::arrow2::chunk::Chunk as Arrow2Chunk; -#[doc(no_inline)] -pub use self::external::re_chunk::{ - concat_record_batches::concatenate_record_batches, TransportChunk, -}; +pub use self::external::re_chunk::TransportChunk; #[doc(no_inline)] pub use self::external::re_chunk_store::{ ChunkStoreConfig, ChunkStoreHandle, ColumnSelector, ComponentColumnSelector, Index, IndexRange, diff --git a/crates/store/re_dataframe/src/query.rs b/crates/store/re_dataframe/src/query.rs index b57579be1f04..e3b3313fa6d2 100644 --- a/crates/store/re_dataframe/src/query.rs +++ b/crates/store/re_dataframe/src/query.rs @@ -6,19 +6,21 @@ use std::{ }, }; -use arrow::buffer::ScalarBuffer as ArrowScalarBuffer; +use arrow::{ + array::RecordBatch as ArrowRecordBatch, buffer::ScalarBuffer as ArrowScalarBuffer, + datatypes::Fields as ArrowFields, datatypes::Schema as ArrowSchema, + datatypes::SchemaRef as ArrowSchemaRef, +}; use arrow2::{ array::{ Array as Arrow2Array, BooleanArray as Arrow2BooleanArray, PrimitiveArray as Arrow2PrimitiveArray, }, - chunk::Chunk as Arrow2Chunk, - datatypes::Schema as Arrow2Schema, Either, }; use itertools::Itertools; - use nohash_hasher::{IntMap, IntSet}; + use re_arrow_util::Arrow2ArrayDowncastRef as _; use re_chunk::{ external::arrow::array::ArrayRef, Chunk, ComponentName, EntityPath, RangeQuery, RowId, TimeInt, @@ -33,8 +35,6 @@ use re_log_types::ResolvedTimeRange; use re_query::{QueryCache, StorageEngineLike}; use re_types_core::{components::ClearIsRecursive, ComponentDescriptor}; -use crate::RecordBatch; - // --- // TODO(cmc): (no specific order) (should we make issues for these?) @@ -107,7 +107,7 @@ struct QueryHandleState { /// The Arrow schema that corresponds to the `selected_contents`. /// /// All returned rows will have this schema. - arrow_schema: Arrow2Schema, + arrow_schema: ArrowSchemaRef, /// All the [`Chunk`]s included in the view contents. /// @@ -191,13 +191,13 @@ impl QueryHandle { // 3. Compute the Arrow schema of the selected components. // // Every result returned using this `QueryHandle` will match this schema exactly. - let arrow_schema = Arrow2Schema { - fields: selected_contents + let arrow_schema = ArrowSchemaRef::from(ArrowSchema::new_with_metadata( + selected_contents .iter() .map(|(_, descr)| descr.to_arrow_field()) - .collect_vec(), - metadata: Default::default(), - }; + .collect::(), + Default::default(), + )); // 4. Perform the query and keep track of all the relevant chunks. let query = { @@ -256,7 +256,7 @@ impl QueryHandle { // Only way this could fail is if the number of rows did not match. #[allow(clippy::unwrap_used)] chunk - .add_component( + .add_component_arrow2( re_types_core::ComponentDescriptor { component_name: descr.component_name, archetype_name: descr.archetype_name, @@ -669,7 +669,7 @@ impl QueryHandle { /// /// Columns that do not yield any data will still be present in the results, filled with null values. #[inline] - pub fn schema(&self) -> &Arrow2Schema { + pub fn schema(&self) -> &ArrowSchemaRef { &self.init().arrow_schema } @@ -794,7 +794,7 @@ impl QueryHandle { #[inline] pub fn next_row(&self) -> Option> { self.engine - .with(|store, cache| self._next_row(store, cache)) + .with(|store, cache| self._next_row_arrow2(store, cache)) .map(|vec| vec.into_iter().map(|a| a.into()).collect()) } @@ -826,7 +826,7 @@ impl QueryHandle { #[inline] fn next_row_arrow2(&self) -> Option>> { self.engine - .with(|store, cache| self._next_row(store, cache)) + .with(|store, cache| self._next_row_arrow2(store, cache)) } /// Asynchronously returns the next row's worth of data. @@ -845,7 +845,7 @@ impl QueryHandle { /// } /// ``` #[cfg(not(target_arch = "wasm32"))] - pub fn next_row_async( + pub fn next_row_async_arrow2( &self, ) -> impl std::future::Future>>> where @@ -853,7 +853,7 @@ impl QueryHandle { { let res: Option> = self .engine - .try_with(|store, cache| self._next_row(store, cache)); + .try_with(|store, cache| self._next_row_arrow2(store, cache)); let engine = self.engine.clone(); std::future::poll_fn(move |cx| { @@ -883,7 +883,7 @@ impl QueryHandle { }) } - pub fn _next_row( + pub fn _next_row_arrow2( &self, store: &ChunkStore, cache: &QueryCache, @@ -1240,7 +1240,7 @@ impl QueryHandle { .map(|(view_idx, column)| match column { ColumnDescriptor::Time(descr) => { max_value_per_index.get(&descr.timeline()).map_or_else( - || arrow2::array::new_null_array(column.datatype(), 1), + || arrow2::array::new_null_array(column.arrow2_datatype(), 1), |(_time, time_sliced)| { descr.typ().make_arrow_array(time_sliced.clone()).into() }, @@ -1251,7 +1251,7 @@ impl QueryHandle { .get(*view_idx) .cloned() .flatten() - .unwrap_or_else(|| arrow2::array::new_null_array(column.datatype(), 1)), + .unwrap_or_else(|| arrow2::array::new_null_array(column.arrow2_datatype(), 1)), }) .collect_vec(); @@ -1260,33 +1260,32 @@ impl QueryHandle { Some(selected_arrays) } - /// Calls [`Self::next_row`] and wraps the result in a [`RecordBatch`]. + /// Calls [`Self::next_row`] and wraps the result in a [`ArrowRecordBatch`]. /// - /// Only use this if you absolutely need a [`RecordBatch`] as this adds a lot of allocation - /// overhead. + /// Only use this if you absolutely need a [`RecordBatch`] as this adds a + /// some overhead for schema validation. /// /// See [`Self::next_row`] for more information. #[inline] - pub fn next_row_batch(&self) -> Option { - Some(RecordBatch::new( - self.schema().clone(), - Arrow2Chunk::new(self.next_row_arrow2()?), - )) + pub fn next_row_batch(&self) -> Option { + let row = self.next_row()?; + ArrowRecordBatch::try_new(self.schema().clone(), row).ok() } #[inline] #[cfg(not(target_arch = "wasm32"))] - pub async fn next_row_batch_async(&self) -> Option + pub async fn next_row_batch_async(&self) -> Option where E: 'static + Send + Clone, { - let row = self.next_row_async().await?; + let row = self.next_row_async_arrow2().await?; // If we managed to get a row, then the state must be initialized already. #[allow(clippy::unwrap_used)] let schema = self.state.get().unwrap().arrow_schema.clone(); - Some(RecordBatch::new(schema, Arrow2Chunk::new(row))) + // TODO(#3741): remove the collect + ArrowRecordBatch::try_new(schema, row.into_iter().map(|a| a.into()).collect()).ok() } } @@ -1305,13 +1304,13 @@ impl QueryHandle { /// Returns an iterator backed by [`Self::next_row_batch`]. #[allow(clippy::should_implement_trait)] // we need an anonymous closure, this won't work - pub fn batch_iter(&self) -> impl Iterator + '_ { + pub fn batch_iter(&self) -> impl Iterator + '_ { std::iter::from_fn(move || self.next_row_batch()) } /// Returns an iterator backed by [`Self::next_row_batch`]. #[allow(clippy::should_implement_trait)] // we need an anonymous closure, this won't work - pub fn into_batch_iter(self) -> impl Iterator { + pub fn into_batch_iter(self) -> impl Iterator { std::iter::from_fn(move || self.next_row_batch()) } } @@ -1323,13 +1322,12 @@ impl QueryHandle { mod tests { use std::sync::Arc; - use re_chunk::{ - concat_record_batches::concatenate_record_batches, Chunk, ChunkId, RowId, TimePoint, - TransportChunk, - }; + use arrow::compute::concat_batches; + use re_chunk::{Chunk, ChunkId, RowId, TimePoint, TransportChunk}; use re_chunk_store::{ ChunkStore, ChunkStoreConfig, ChunkStoreHandle, ResolvedTimeRange, TimeInt, }; + use re_format_arrow::format_record_batch; use re_log_types::{ build_frame_nr, build_log_time, example_components::{MyColor, MyLabel, MyPoint}, @@ -1398,13 +1396,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } // temporal @@ -1420,13 +1418,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } Ok(()) @@ -1454,13 +1452,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); Ok(()) } @@ -1487,13 +1485,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); Ok(()) } @@ -1526,13 +1524,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); Ok(()) } @@ -1568,13 +1566,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } // sparse-filled @@ -1598,13 +1596,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } Ok(()) @@ -1639,13 +1637,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } // non-existing component @@ -1665,13 +1663,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } // MyPoint @@ -1691,13 +1689,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } // MyColor @@ -1717,13 +1715,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } Ok(()) @@ -1759,13 +1757,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } { @@ -1796,13 +1794,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } Ok(()) @@ -1834,13 +1832,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } // only indices (+ duplication) @@ -1867,13 +1865,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } // only components (+ duplication) @@ -1907,13 +1905,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } // static @@ -1968,13 +1966,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } Ok(()) @@ -2037,13 +2035,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } Ok(()) @@ -2077,13 +2075,13 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!(dataframe); + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } // sparse-filled @@ -2101,17 +2099,17 @@ mod tests { query_engine.query(query.clone()).into_iter().count() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), - &query_handle.into_batch_iter().collect_vec(), + let dataframe = concat_batches( + query_handle.schema(), + &query_handle.batch_iter().collect_vec(), )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); // TODO(#7650): Those null values for `MyColor` on 10 and 20 look completely insane, but then again // static clear semantics in general are pretty unhinged right now, especially when // ranges are involved. - // It's extremely niche, our time is better spent somewhere else right now. - assert_snapshot_fixed_width!(dataframe); + + assert_snapshot_fixed_width!(TransportChunk::from(dataframe)); } Ok(()) @@ -2149,12 +2147,12 @@ mod tests { for i in 0..expected_rows.len() { query_handle.seek_to_row(i); - let expected = concatenate_record_batches( - query_handle.schema().clone(), + let expected = concat_batches( + query_handle.schema(), &expected_rows.iter().skip(i).take(3).cloned().collect_vec(), )?; - let got = concatenate_record_batches( - query_handle.schema().clone(), + let got = concat_batches( + query_handle.schema(), &query_handle.batch_iter().take(3).collect_vec(), )?; @@ -2190,12 +2188,12 @@ mod tests { for i in 0..expected_rows.len() { query_handle.seek_to_row(i); - let expected = concatenate_record_batches( - query_handle.schema().clone(), + let expected = concat_batches( + query_handle.schema(), &expected_rows.iter().skip(i).take(3).cloned().collect_vec(), )?; - let got = concatenate_record_batches( - query_handle.schema().clone(), + let got = concat_batches( + query_handle.schema(), &query_handle.batch_iter().take(3).collect_vec(), )?; @@ -2234,12 +2232,12 @@ mod tests { for i in 0..expected_rows.len() { query_handle.seek_to_row(i); - let expected = concatenate_record_batches( - query_handle.schema().clone(), + let expected = concat_batches( + query_handle.schema(), &expected_rows.iter().skip(i).take(3).cloned().collect_vec(), )?; - let got = concatenate_record_batches( - query_handle.schema().clone(), + let got = concat_batches( + query_handle.schema(), &query_handle.batch_iter().take(3).collect_vec(), )?; @@ -2272,12 +2270,12 @@ mod tests { for i in 0..expected_rows.len() { query_handle.seek_to_row(i); - let expected = concatenate_record_batches( - query_handle.schema().clone(), + let expected = concat_batches( + query_handle.schema(), &expected_rows.iter().skip(i).take(3).cloned().collect_vec(), )?; - let got = concatenate_record_batches( - query_handle.schema().clone(), + let got = concat_batches( + query_handle.schema(), &query_handle.batch_iter().take(3).collect_vec(), )?; @@ -2302,7 +2300,7 @@ mod tests { pub struct QueryHandleStream(pub QueryHandle); impl tokio_stream::Stream for QueryHandleStream { - type Item = TransportChunk; + type Item = ArrowRecordBatch; #[inline] fn poll_next( @@ -2341,15 +2339,18 @@ mod tests { .len() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), + let dataframe = concat_batches( + query_handle.schema(), &QueryHandleStream(query_engine.query(query.clone())) .collect::>() .await, )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!("async_barebones_static", dataframe); + assert_snapshot_fixed_width!( + "async_barebones_static", + TransportChunk::from(dataframe) + ); Ok::<_, anyhow::Error>(()) } @@ -2372,15 +2373,18 @@ mod tests { .len() as u64, query_handle.num_rows() ); - let dataframe = concatenate_record_batches( - query_handle.schema().clone(), + let dataframe = concat_batches( + query_handle.schema(), &QueryHandleStream(query_engine.query(query.clone())) .collect::>() .await, )?; - eprintln!("{dataframe}"); + eprintln!("{}", format_record_batch(&dataframe.clone())); - assert_snapshot_fixed_width!("async_barebones_temporal", dataframe); + assert_snapshot_fixed_width!( + "async_barebones_temporal", + TransportChunk::from(dataframe) + ); Ok::<_, anyhow::Error>(()) } diff --git a/crates/store/re_format_arrow/src/lib.rs b/crates/store/re_format_arrow/src/lib.rs index a796f6d91e5a..f9b80c626275 100644 --- a/crates/store/re_format_arrow/src/lib.rs +++ b/crates/store/re_format_arrow/src/lib.rs @@ -212,7 +212,25 @@ fn trim_name(name: &str) -> &str { .trim_start_matches("rerun.") } -pub fn format_dataframe( +/// Nicely format this record batch in a way that fits the terminal. +pub fn format_record_batch(batch: &arrow::array::RecordBatch) -> Table { + format_record_batch_with_width(batch, None) +} + +/// Nicely format this record batch, either with the given fixed width, or with the terminal width (`None`). +pub fn format_record_batch_with_width( + batch: &arrow::array::RecordBatch, + width: Option, +) -> Table { + format_dataframe( + &batch.schema_ref().metadata.clone().into_iter().collect(), // HashMap -> BTreeMap + &batch.schema_ref().fields, + batch.columns(), + width, + ) +} + +fn format_dataframe( metadata: &Metadata, fields: &Fields, columns: &[ArrayRef], diff --git a/crates/store/re_grpc_client/src/lib.rs b/crates/store/re_grpc_client/src/lib.rs index 62ee365c1a9e..63471503527c 100644 --- a/crates/store/re_grpc_client/src/lib.rs +++ b/crates/store/re_grpc_client/src/lib.rs @@ -1,43 +1,49 @@ //! Communications with an Rerun Data Platform gRPC server. -mod address; - -pub use address::{InvalidRedapAddress, RedapAddress}; -use re_arrow_util::Arrow2ArrayDowncastRef as _; -use re_chunk::external::arrow2; -use re_log_encoding::codec::wire::decoder::Decode; -use re_log_types::external::re_types_core::ComponentDescriptor; -use re_protos::remote_store::v0::CatalogFilter; -use re_types::blueprint::archetypes::{ContainerBlueprint, ViewportBlueprint}; -use re_types::blueprint::archetypes::{ViewBlueprint, ViewContents}; -use re_types::blueprint::components::{ContainerKind, RootContainer}; -use re_types::components::RecordingUri; -use re_types::external::uuid; -use re_types::{Archetype, Component}; +use std::{collections::HashMap, error::Error, sync::Arc}; + +use arrow::{ + array::{ + Array as ArrowArray, ArrayRef as ArrowArrayRef, RecordBatch as ArrowRecordBatch, + StringArray as ArrowStringArray, + }, + datatypes::{DataType as ArrowDataType, Field as ArrowField}, +}; use url::Url; -// ---------------------------------------------------------------------------- - -use std::sync::Arc; -use std::{collections::HashMap, error::Error}; - -use arrow::datatypes::{DataType as ArrowDataType, Field as ArrowField}; -use arrow2::array::Utf8Array as Arrow2Utf8Array; -use re_chunk::{ - Arrow2Array, Chunk, ChunkBuilder, ChunkId, EntityPath, RowId, Timeline, TransportChunk, -}; -use re_log_encoding::codec::CodecError; +use re_arrow_util::ArrowArrayDowncastRef as _; +use re_chunk::{Chunk, ChunkBuilder, ChunkId, EntityPath, RowId, Timeline, TransportChunk}; +use re_log_encoding::codec::{wire::decoder::Decode, CodecError}; use re_log_types::{ - ApplicationId, BlueprintActivationCommand, EntityPathFilter, LogMsg, SetStoreInfo, StoreId, - StoreInfo, StoreKind, StoreSource, Time, + external::re_types_core::ComponentDescriptor, ApplicationId, BlueprintActivationCommand, + EntityPathFilter, LogMsg, SetStoreInfo, StoreId, StoreInfo, StoreKind, StoreSource, Time, +}; +use re_protos::{ + common::v0::RecordingId, + remote_store::v0::{ + storage_node_client::StorageNodeClient, CatalogFilter, FetchRecordingRequest, + QueryCatalogRequest, + }, }; -use re_protos::common::v0::RecordingId; -use re_protos::remote_store::v0::{ - storage_node_client::StorageNodeClient, FetchRecordingRequest, QueryCatalogRequest, +use re_types::{ + arrow_helpers::as_array_ref, + blueprint::{ + archetypes::{ContainerBlueprint, ViewBlueprint, ViewContents, ViewportBlueprint}, + components::{ContainerKind, RootContainer}, + }, + components::RecordingUri, + external::uuid, + Archetype, Component, }; // ---------------------------------------------------------------------------- +mod address; + +pub use address::{InvalidRedapAddress, RedapAddress}; + +// ---------------------------------------------------------------------------- + /// Wrapper with a nicer error message #[derive(Debug)] pub struct TonicStatusError(pub tonic::Status); @@ -281,7 +287,7 @@ pub fn store_info_from_catalog_chunk( reason: "no application_id field found".to_owned(), }))?; let app_id = data - .downcast_array2_ref::>() + .downcast_array_ref::() .ok_or(StreamError::ChunkError(re_chunk::ChunkError::Malformed { reason: format!("application_id must be a utf8 array: {:?}", tc.schema_ref()), }))? @@ -294,7 +300,7 @@ pub fn store_info_from_catalog_chunk( reason: "no start_time field found".to_owned(), }))?; let start_time = data - .downcast_array2_ref::() + .downcast_array_ref::() .ok_or(StreamError::ChunkError(re_chunk::ChunkError::Malformed { reason: format!("start_time must be an int64 array: {:?}", tc.schema_ref()), }))? @@ -391,8 +397,8 @@ async fn stream_catalog_async( // - conversion expects "data" columns to be ListArrays, hence we need to convert any individual row column data to ListArray // - conversion expects the input TransportChunk to have a ChunkId so we need to add that piece of metadata - let mut fields = Vec::new(); - let mut arrays = Vec::new(); + let mut fields: Vec = Vec::new(); + let mut columns: Vec = Vec::new(); // add the (row id) control field let (row_id_field, row_id_data) = input.controls().next().ok_or( StreamError::ChunkError(re_chunk::ChunkError::Malformed { @@ -408,12 +414,12 @@ async fn stream_catalog_async( ) .with_metadata(TransportChunk::field_metadata_control_column()), ); - arrays.push(row_id_data.clone()); + columns.push(row_id_data.clone()); // next add any timeline field for (field, data) in input.timelines() { fields.push(field.clone()); - arrays.push(data.clone()); + columns.push(data.clone()); } // now add all the 'data' fields - we slice each column array into individual arrays and then convert the whole lot into a ListArray @@ -428,41 +434,41 @@ async fn stream_catalog_async( ) .with_metadata(TransportChunk::field_metadata_data_column()); - let mut sliced: Vec> = Vec::new(); + let mut sliced: Vec = Vec::new(); for idx in 0..data.len() { - let mut array = data.clone(); - array.slice(idx, 1); - sliced.push(array); + sliced.push(data.clone().slice(idx, 1)); } let data_arrays = sliced.iter().map(|e| Some(e.as_ref())).collect::>(); #[allow(clippy::unwrap_used)] // we know we've given the right field type - let data_field_array: arrow2::array::ListArray = - re_arrow_util::arrow2_util::arrays_to_list_array( - data_field_inner.data_type().clone().into(), + let data_field_array: arrow::array::ListArray = + re_arrow_util::arrow_util::arrays_to_list_array( + data_field_inner.data_type().clone(), &data_arrays, ) .unwrap(); fields.push(data_field); - arrays.push(Box::new(data_field_array)); + columns.push(as_array_ref(data_field_array)); } let schema = { - let metadata = HashMap::from_iter([( - TransportChunk::CHUNK_METADATA_KEY_ENTITY_PATH.to_owned(), - "catalog".to_owned(), - )]); + let metadata = HashMap::from_iter([ + ( + TransportChunk::CHUNK_METADATA_KEY_ENTITY_PATH.to_owned(), + "catalog".to_owned(), + ), + ( + TransportChunk::CHUNK_METADATA_KEY_ID.to_owned(), + ChunkId::new().to_string(), + ), + ]); arrow::datatypes::Schema::new_with_metadata(fields, metadata) }; - // modified and enriched TransportChunk - let mut tc = TransportChunk::new(schema, arrow2::chunk::Chunk::new(arrays)); - tc.insert_metadata( - TransportChunk::CHUNK_METADATA_KEY_ID.to_owned(), - ChunkId::new().to_string(), - ); - let mut chunk = Chunk::from_transport(&tc)?; + let record_batch = ArrowRecordBatch::try_new(schema.into(), columns) + .map_err(re_chunk::ChunkError::from)?; + let mut chunk = Chunk::from_record_batch(record_batch)?; // finally, enrich catalog data with RecordingUri that's based on the ReDap endpoint (that we know) // and the recording id (that we have in the catalog data) @@ -477,20 +483,16 @@ async fn stream_catalog_async( "couldn't get port from {redap_endpoint}" )))?; - let recording_uri_arrays: Vec> = chunk + let recording_uri_arrays: Vec = chunk .iter_slices::("id".into()) .map(|id| { let rec_id = &id[0]; // each component batch is of length 1 i.e. single 'id' value let recording_uri = format!("rerun://{host}:{port}/recording/{rec_id}"); - let recording_uri_data = Arrow2Utf8Array::::from([Some(recording_uri)]); - - Ok::, StreamError>( - Box::new(recording_uri_data) as Box - ) + as_array_ref(ArrowStringArray::from(vec![recording_uri])) }) - .collect::, _>>()?; + .collect(); let recording_id_arrays = recording_uri_arrays .iter() @@ -499,8 +501,8 @@ async fn stream_catalog_async( let rec_id_field = ArrowField::new("item", ArrowDataType::Utf8, true); #[allow(clippy::unwrap_used)] // we know we've given the right field type - let uris = re_arrow_util::arrow2_util::arrays_to_list_array( - rec_id_field.data_type().clone().into(), + let uris = re_arrow_util::arrow_util::arrays_to_list_array( + rec_id_field.data_type().clone(), &recording_id_arrays, ) .unwrap(); diff --git a/crates/store/re_log_encoding/src/codec/wire/decoder.rs b/crates/store/re_log_encoding/src/codec/wire/decoder.rs index 8df9ae1ca0e0..e8f3c83040be 100644 --- a/crates/store/re_log_encoding/src/codec/wire/decoder.rs +++ b/crates/store/re_log_encoding/src/codec/wire/decoder.rs @@ -13,7 +13,7 @@ fn decode( re_protos::common::v0::EncoderVersion::V0 => { let mut reader = std::io::Cursor::new(data); let batch = read_arrow_from_bytes(&mut reader)?; - Ok(batch.into()) + Ok(TransportChunk::from(batch)) } } } diff --git a/crates/store/re_log_encoding/src/codec/wire/encoder.rs b/crates/store/re_log_encoding/src/codec/wire/encoder.rs index 58c8a95dca4c..1c8b657fda50 100644 --- a/crates/store/re_log_encoding/src/codec/wire/encoder.rs +++ b/crates/store/re_log_encoding/src/codec/wire/encoder.rs @@ -1,20 +1,20 @@ -use crate::codec::arrow::write_arrow_to_bytes; -use crate::codec::CodecError; -use re_chunk::TransportChunk; use re_protos::common::v0::RerunChunk; use re_protos::remote_store::v0::DataframePart; +use arrow::array::RecordBatch as ArrowRecordBatch; + +use crate::codec::arrow::write_arrow_to_bytes; +use crate::codec::CodecError; + /// Encode a transport chunk into a byte stream. fn encode( version: re_protos::common::v0::EncoderVersion, - chunk: &TransportChunk, + batch: &ArrowRecordBatch, ) -> Result, CodecError> { - let transport_chunk = - arrow::array::RecordBatch::try_from(chunk.clone()).map_err(CodecError::InvalidChunk)?; match version { re_protos::common::v0::EncoderVersion::V0 => { let mut data: Vec = Vec::new(); - write_arrow_to_bytes(&mut data, &transport_chunk)?; + write_arrow_to_bytes(&mut data, batch)?; Ok(data) } } @@ -25,7 +25,7 @@ pub trait Encode { fn encode(&self) -> Result; } -impl Encode for TransportChunk { +impl Encode for ArrowRecordBatch { fn encode(&self) -> Result { let payload = encode(re_protos::common::v0::EncoderVersion::V0, self)?; Ok(DataframePart { @@ -35,7 +35,7 @@ impl Encode for TransportChunk { } } -impl Encode for TransportChunk { +impl Encode for ArrowRecordBatch { fn encode(&self) -> Result { let payload = encode(re_protos::common::v0::EncoderVersion::V0, self)?; Ok(RerunChunk { diff --git a/crates/store/re_log_types/src/arrow_msg.rs b/crates/store/re_log_types/src/arrow_msg.rs index 6a02c767f5f6..77259a7f9fe5 100644 --- a/crates/store/re_log_types/src/arrow_msg.rs +++ b/crates/store/re_log_types/src/arrow_msg.rs @@ -239,7 +239,7 @@ impl<'de> serde::Deserialize<'de> for ArrowMsg { })?; if chunks.is_empty() { - return Err(serde::de::Error::custom("No Arrow2Chunk found in stream")); + return Err(serde::de::Error::custom("No chunks found in stream")); } if chunks.len() > 1 { return Err(serde::de::Error::custom(format!( diff --git a/crates/top/rerun/Cargo.toml b/crates/top/rerun/Cargo.toml index 5b4ee234beb2..1a3884cc097c 100644 --- a/crates/top/rerun/Cargo.toml +++ b/crates/top/rerun/Cargo.toml @@ -130,6 +130,7 @@ re_chunk.workspace = true re_crash_handler.workspace = true re_entity_db.workspace = true re_error.workspace = true +re_format_arrow.workspace = true re_format.workspace = true re_log_encoding.workspace = true re_log_types.workspace = true @@ -140,6 +141,7 @@ re_tracing.workspace = true re_video.workspace = true anyhow.workspace = true +arrow.workspace = true document-features.workspace = true itertools.workspace = true similar-asserts.workspace = true diff --git a/crates/top/rerun/src/lib.rs b/crates/top/rerun/src/lib.rs index cdfe26a44eb2..9b299c1e0ed6 100644 --- a/crates/top/rerun/src/lib.rs +++ b/crates/top/rerun/src/lib.rs @@ -166,11 +166,13 @@ pub const EXTERNAL_DATA_LOADER_INCOMPATIBLE_EXIT_CODE: i32 = 66; /// Re-exports of other crates. pub mod external { pub use anyhow; + pub use arrow; pub use ::re_build_info; pub use ::re_entity_db; pub use ::re_entity_db::external::*; pub use ::re_format; + pub use ::re_format_arrow; #[cfg(feature = "run")] pub use re_data_source; diff --git a/docs/snippets/all/reference/dataframe_query.rs b/docs/snippets/all/reference/dataframe_query.rs index 2513c46440dc..cbc56c1f2b34 100644 --- a/docs/snippets/all/reference/dataframe_query.rs +++ b/docs/snippets/all/reference/dataframe_query.rs @@ -2,6 +2,7 @@ use rerun::{ dataframe::{QueryEngine, QueryExpression, SparseFillStrategy, Timeline}, + external::re_format_arrow::format_record_batch, ChunkStoreConfig, VersionPolicy, }; @@ -30,7 +31,7 @@ fn main() -> Result<(), Box> { let query_handle = engine.query(query.clone()); for row in query_handle.batch_iter().take(10) { // Each row is a `RecordBatch`, which can be easily passed around across different data ecosystems. - println!("{row}"); + println!("{}", format_record_batch(&row)); } Ok(()) diff --git a/examples/rust/dataframe_query/src/main.rs b/examples/rust/dataframe_query/src/main.rs index d451c830da93..2c27b18d58cb 100644 --- a/examples/rust/dataframe_query/src/main.rs +++ b/examples/rust/dataframe_query/src/main.rs @@ -3,10 +3,9 @@ use itertools::Itertools; use rerun::{ - dataframe::{ - concatenate_record_batches, EntityPathFilter, QueryEngine, QueryExpression, - SparseFillStrategy, Timeline, - }, + dataframe::{EntityPathFilter, QueryEngine, QueryExpression, SparseFillStrategy, Timeline}, + external::arrow, + external::re_format_arrow::format_record_batch, ChunkStoreConfig, StoreKind, VersionPolicy, }; @@ -68,8 +67,8 @@ fn main() -> Result<(), Box> { let query_handle = engine.query(query.clone()); let record_batches = query_handle.batch_iter().take(10).collect_vec(); - let table = concatenate_record_batches(query_handle.schema().clone(), &record_batches)?; - println!("{table}"); + let batch = arrow::compute::concat_batches(query_handle.schema(), &record_batches)?; + println!("{}", format_record_batch(&batch)); } Ok(()) diff --git a/rerun_py/Cargo.toml b/rerun_py/Cargo.toml index 0cc66e0e91a2..646e2b86b1d3 100644 --- a/rerun_py/Cargo.toml +++ b/rerun_py/Cargo.toml @@ -60,7 +60,7 @@ web_viewer = [ [dependencies] re_arrow_util.workspace = true re_build_info.workspace = true -re_chunk = { workspace = true, features = ["arrow"] } +re_chunk.workspace = true re_chunk_store.workspace = true re_dataframe.workspace = true re_grpc_client = { workspace = true, optional = true } diff --git a/rerun_py/src/dataframe.rs b/rerun_py/src/dataframe.rs index 79b8ba2f82d2..01fd441f1fd3 100644 --- a/rerun_py/src/dataframe.rs +++ b/rerun_py/src/dataframe.rs @@ -753,18 +753,10 @@ impl PyRecordingView { py_rerun_warn("RecordingView::select: tried to select static data, but no non-static contents generated an index value on this timeline. No results will be returned. Either include non-static data or consider using `select_static()` instead.")?; } - let schema = query_handle.schema(); - let fields: Vec = - schema.fields.iter().map(|f| f.clone().into()).collect(); - let metadata = schema.metadata.clone().into_iter().collect(); - let schema = arrow::datatypes::Schema::new_with_metadata(fields, metadata); - - let reader = RecordBatchIterator::new( - query_handle - .into_batch_iter() - .map(|batch| batch.try_to_arrow_record_batch()), - std::sync::Arc::new(schema), - ); + let schema = query_handle.schema().clone(); + + let reader = + RecordBatchIterator::new(query_handle.into_batch_iter().map(Ok), schema); Ok(PyArrowType(Box::new(reader))) } #[cfg(feature = "remote")] @@ -850,18 +842,10 @@ impl PyRecordingView { ))); } - let schema = query_handle.schema(); - let fields: Vec = - schema.fields.iter().map(|f| f.clone().into()).collect(); - let metadata = schema.metadata.clone().into_iter().collect(); - let schema = arrow::datatypes::Schema::new_with_metadata(fields, metadata); - - let reader = RecordBatchIterator::new( - query_handle - .into_batch_iter() - .map(|batch| batch.try_to_arrow_record_batch()), - std::sync::Arc::new(schema), - ); + let schema = query_handle.schema().clone(); + + let reader = + RecordBatchIterator::new(query_handle.into_batch_iter().map(Ok), schema); Ok(PyArrowType(Box::new(reader))) } diff --git a/rerun_py/src/remote.rs b/rerun_py/src/remote.rs index bc408ba72570..5959a385b6a9 100644 --- a/rerun_py/src/remote.rs +++ b/rerun_py/src/remote.rs @@ -1,4 +1,4 @@ -#![allow(unsafe_op_in_unsafe_fn)] +#![allow(unsafe_op_in_unsafe_fn)] // False positive due to #[pyfunction] macro use std::collections::BTreeSet; @@ -8,15 +8,16 @@ use arrow::{ ffi_stream::ArrowArrayStreamReader, pyarrow::PyArrowType, }; -// False positive due to #[pyfunction] macro use pyo3::{ exceptions::{PyRuntimeError, PyTypeError, PyValueError}, prelude::*, types::PyDict, Bound, PyResult, }; -use re_arrow_util::Arrow2ArrayDowncastRef as _; -use re_chunk::{Chunk, TransportChunk}; +use tokio_stream::StreamExt; + +use re_arrow_util::ArrowArrayDowncastRef as _; +use re_chunk::Chunk; use re_chunk_store::ChunkStore; use re_dataframe::{ChunkStoreHandle, QueryExpression, SparseFillStrategy, ViewContentsSelector}; use re_grpc_client::TonicStatusError; @@ -32,7 +33,6 @@ use re_protos::{ TypeConversionError, }; use re_sdk::{ApplicationId, ComponentName, StoreId, StoreKind, Time, Timeline}; -use tokio_stream::StreamExt; use crate::dataframe::{ComponentLike, PyRecording, PyRecordingHandle, PyRecordingView, PySchema}; @@ -173,7 +173,7 @@ impl PyStorageNodeClient { .unwrap_or_else(|| ArrowSchema::empty().into()); Ok(RecordBatchIterator::new( - batches.into_iter().map(|tc| tc.try_to_arrow_record_batch()), + batches.into_iter().map(|tc| Ok(tc.into())), schema, )) }); @@ -236,7 +236,7 @@ impl PyStorageNodeClient { let record_batches: Vec> = transport_chunks .into_iter() - .map(|tc| tc.try_to_arrow_record_batch()) + .map(|tc| Ok(tc.into())) .collect(); // TODO(jleibs): surfacing this schema is awkward. This should be more explicit in @@ -321,8 +321,7 @@ impl PyStorageNodeClient { )); } - let metadata_tc = TransportChunk::from_arrow_record_batch(&metadata); - metadata_tc + metadata .encode() .map_err(|err| PyRuntimeError::new_err(err.to_string())) }) @@ -351,7 +350,7 @@ impl PyStorageNodeClient { .find(|(field, _data)| field.name() == "rerun_recording_id") .map(|(_field, data)| data) .ok_or(PyRuntimeError::new_err("No rerun_recording_id"))? - .downcast_array2_ref::>() + .downcast_array_ref::() .ok_or(PyRuntimeError::new_err("Recording Id is not a string"))? .value(0) .to_owned(); @@ -388,11 +387,9 @@ impl PyStorageNodeClient { )); } - let metadata_tc = TransportChunk::from_arrow_record_batch(&metadata); - let request = UpdateCatalogRequest { metadata: Some( - metadata_tc + metadata .encode() .map_err(|err| PyRuntimeError::new_err(err.to_string()))?, ), From 7e6b79dea89133d530e451eab57c4dacf0371d17 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 16 Jan 2025 13:57:04 +0100 Subject: [PATCH 48/57] Less use of `TransportChunk` (#8707) * Part of #3741 --- crates/store/re_chunk/src/transport.rs | 10 ---------- crates/store/re_dataframe/src/query.rs | 2 +- crates/store/re_grpc_client/src/lib.rs | 9 +++++---- .../re_log_encoding/src/codec/wire/decoder.rs | 18 +++++++++-------- .../re_log_encoding/src/codec/wire/mod.rs | 2 +- crates/store/re_log_types/Cargo.toml | 6 +++++- rerun_py/src/remote.rs | 20 +++++++++---------- 7 files changed, 31 insertions(+), 36 deletions(-) diff --git a/crates/store/re_chunk/src/transport.rs b/crates/store/re_chunk/src/transport.rs index 90ea338e21d9..6527da66593d 100644 --- a/crates/store/re_chunk/src/transport.rs +++ b/crates/store/re_chunk/src/transport.rs @@ -356,16 +356,6 @@ impl TransportChunk { }) } - #[inline] - pub fn fields_and_columns(&self) -> impl Iterator + '_ { - self.fields().iter().enumerate().filter_map(|(i, field)| { - self.batch - .columns() - .get(i) - .map(|column| (field.as_ref(), column)) - }) - } - /// Iterates all control columns present in this chunk. #[inline] pub fn controls(&self) -> impl Iterator { diff --git a/crates/store/re_dataframe/src/query.rs b/crates/store/re_dataframe/src/query.rs index e3b3313fa6d2..cd302a51709f 100644 --- a/crates/store/re_dataframe/src/query.rs +++ b/crates/store/re_dataframe/src/query.rs @@ -1262,7 +1262,7 @@ impl QueryHandle { /// Calls [`Self::next_row`] and wraps the result in a [`ArrowRecordBatch`]. /// - /// Only use this if you absolutely need a [`RecordBatch`] as this adds a + /// Only use this if you absolutely need a [`ArrowRecordBatch`] as this adds a /// some overhead for schema validation. /// /// See [`Self::next_row`] for more information. diff --git a/crates/store/re_grpc_client/src/lib.rs b/crates/store/re_grpc_client/src/lib.rs index 63471503527c..487d27098508 100644 --- a/crates/store/re_grpc_client/src/lib.rs +++ b/crates/store/re_grpc_client/src/lib.rs @@ -218,7 +218,8 @@ async fn stream_recording_async( })); } - let store_info = store_info_from_catalog_chunk(&resp[0], &recording_id)?; + let store_info = + store_info_from_catalog_chunk(&TransportChunk::from(resp[0].clone()), &recording_id)?; let store_id = store_info.store_id.clone(); re_log::debug!("Fetching {recording_id}…"); @@ -255,8 +256,8 @@ async fn stream_recording_async( re_log::info!("Starting to read..."); while let Some(result) = resp.next().await { - let tc = result.map_err(TonicStatusError)?; - let chunk = Chunk::from_transport(&tc)?; + let batch = result.map_err(TonicStatusError)?; + let chunk = Chunk::from_record_batch(batch)?; if tx .send(LogMsg::ArrowMsg(store_id.clone(), chunk.to_arrow_msg()?)) @@ -391,7 +392,7 @@ async fn stream_catalog_async( re_log::info!("Starting to read..."); while let Some(result) = resp.next().await { - let input = result.map_err(TonicStatusError)?; + let input = TransportChunk::from(result.map_err(TonicStatusError)?); // Catalog received from the ReDap server isn't suitable for direct conversion to a Rerun Chunk: // - conversion expects "data" columns to be ListArrays, hence we need to convert any individual row column data to ListArray diff --git a/crates/store/re_log_encoding/src/codec/wire/decoder.rs b/crates/store/re_log_encoding/src/codec/wire/decoder.rs index e8f3c83040be..39b7a66542e5 100644 --- a/crates/store/re_log_encoding/src/codec/wire/decoder.rs +++ b/crates/store/re_log_encoding/src/codec/wire/decoder.rs @@ -1,36 +1,38 @@ -use crate::codec::arrow::read_arrow_from_bytes; -use crate::codec::CodecError; -use re_chunk::TransportChunk; +use arrow::array::RecordBatch as ArrowRecordBatch; + use re_protos::common::v0::RerunChunk; use re_protos::remote_store::v0::DataframePart; +use crate::codec::arrow::read_arrow_from_bytes; +use crate::codec::CodecError; + /// Decode transport data from a byte stream. fn decode( version: re_protos::common::v0::EncoderVersion, data: &[u8], -) -> Result { +) -> Result { match version { re_protos::common::v0::EncoderVersion::V0 => { let mut reader = std::io::Cursor::new(data); let batch = read_arrow_from_bytes(&mut reader)?; - Ok(TransportChunk::from(batch)) + Ok(batch) } } } /// Decode an object from a its wire (protobuf) representation. pub trait Decode { - fn decode(&self) -> Result; + fn decode(&self) -> Result; } impl Decode for DataframePart { - fn decode(&self) -> Result { + fn decode(&self) -> Result { decode(self.encoder_version(), &self.payload) } } impl Decode for RerunChunk { - fn decode(&self) -> Result { + fn decode(&self) -> Result { decode(self.encoder_version(), &self.payload) } } diff --git a/crates/store/re_log_encoding/src/codec/wire/mod.rs b/crates/store/re_log_encoding/src/codec/wire/mod.rs index a08cd28a810a..7f2ea2624100 100644 --- a/crates/store/re_log_encoding/src/codec/wire/mod.rs +++ b/crates/store/re_log_encoding/src/codec/wire/mod.rs @@ -62,7 +62,7 @@ mod tests { .unwrap(); let decoded = encoded.decode().unwrap(); - let decoded_chunk = Chunk::from_transport(&decoded).unwrap(); + let decoded_chunk = Chunk::from_record_batch(decoded).unwrap(); assert_eq!(expected_chunk, decoded_chunk); } diff --git a/crates/store/re_log_types/Cargo.toml b/crates/store/re_log_types/Cargo.toml index 2437bbf3e5bf..788f02b97c4a 100644 --- a/crates/store/re_log_types/Cargo.toml +++ b/crates/store/re_log_types/Cargo.toml @@ -58,7 +58,11 @@ re_types_core.workspace = true ahash.workspace = true anyhow.workspace = true arrow = { workspace = true, features = ["ipc"] } -arrow2 = { workspace = true, features = ["io_print", "compute_concatenate"] } +arrow2 = { workspace = true, features = [ + "arrow", + "io_print", + "compute_concatenate", +] } backtrace.workspace = true bytemuck.workspace = true clean-path.workspace = true diff --git a/rerun_py/src/remote.rs b/rerun_py/src/remote.rs index 5959a385b6a9..dd0763ac8e0c 100644 --- a/rerun_py/src/remote.rs +++ b/rerun_py/src/remote.rs @@ -130,7 +130,10 @@ impl PyStorageNodeClient { )); } - re_grpc_client::store_info_from_catalog_chunk(&resp[0], id) + re_grpc_client::store_info_from_catalog_chunk( + &re_chunk::TransportChunk::from(resp[0].clone()), + id, + ) }) .map_err(|err| PyRuntimeError::new_err(err.to_string()))?; @@ -173,7 +176,7 @@ impl PyStorageNodeClient { .unwrap_or_else(|| ArrowSchema::empty().into()); Ok(RecordBatchIterator::new( - batches.into_iter().map(|tc| Ok(tc.into())), + batches.into_iter().map(Ok), schema, )) }); @@ -234,10 +237,7 @@ impl PyStorageNodeClient { .map_err(|err| PyRuntimeError::new_err(err.to_string()))?; let record_batches: Vec> = - transport_chunks - .into_iter() - .map(|tc| Ok(tc.into())) - .collect(); + transport_chunks.into_iter().map(Ok).collect(); // TODO(jleibs): surfacing this schema is awkward. This should be more explicit in // the gRPC APIs somehow. @@ -346,9 +346,7 @@ impl PyStorageNodeClient { .map_err(|err| PyRuntimeError::new_err(err.to_string()))?; let recording_id = metadata - .fields_and_columns() - .find(|(field, _data)| field.name() == "rerun_recording_id") - .map(|(_field, data)| data) + .column_by_name("rerun_recording_id") .ok_or(PyRuntimeError::new_err("No rerun_recording_id"))? .downcast_array_ref::() .ok_or(PyRuntimeError::new_err("Recording Id is not a string"))? @@ -480,13 +478,13 @@ impl PyStorageNodeClient { while let Some(result) = resp.next().await { let response = result.map_err(|err| PyRuntimeError::new_err(err.to_string()))?; - let tc = match response.decode() { + let batch = match response.decode() { Ok(tc) => tc, Err(err) => { return Err(PyRuntimeError::new_err(err.to_string())); } }; - let chunk = Chunk::from_transport(&tc) + let chunk = Chunk::from_record_batch(batch) .map_err(|err| PyRuntimeError::new_err(err.to_string()))?; store From 3deb7af3b48adc543029f2096ee27d1bbd2691d4 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Thu, 16 Jan 2025 17:44:09 +0100 Subject: [PATCH 49/57] Move the blueprint saving logic to `re_viewer_blueprint` (#8717) --- Cargo.lock | 1 - crates/viewer/re_viewer/src/app_state.rs | 2 +- crates/viewer/re_viewport/Cargo.toml | 1 - crates/viewer/re_viewport/src/lib.rs | 1 - crates/viewer/re_viewport/src/viewport_ui.rs | 272 +----------------- .../src/auto_layout.rs | 2 +- .../viewer/re_viewport_blueprint/src/lib.rs | 3 +- .../src/viewport_blueprint.rs | 258 +++++++++++++++++ 8 files changed, 267 insertions(+), 273 deletions(-) rename crates/viewer/{re_viewport => re_viewport_blueprint}/src/auto_layout.rs (99%) diff --git a/Cargo.lock b/Cargo.lock index 250bf25c9fdf..b749629b341f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7067,7 +7067,6 @@ dependencies = [ "ahash", "egui", "egui_tiles", - "itertools 0.13.0", "nohash-hasher", "rayon", "re_context_menu", diff --git a/crates/viewer/re_viewer/src/app_state.rs b/crates/viewer/re_viewer/src/app_state.rs index b2dcbb77dd60..7a2d454b3246 100644 --- a/crates/viewer/re_viewer/src/app_state.rs +++ b/crates/viewer/re_viewer/src/app_state.rs @@ -529,7 +529,7 @@ impl AppState { drag_and_drop_manager.payload_cursor_ui(ctx.egui_ctx); // Process deferred layout operations and apply updates back to blueprint: - viewport_ui.save_to_blueprint_store(&ctx, view_class_registry); + viewport_ui.save_to_blueprint_store(&ctx); if WATERMARK { ui.ctx().paint_watermark(); diff --git a/crates/viewer/re_viewport/Cargo.toml b/crates/viewer/re_viewport/Cargo.toml index fe80f4c3b184..c097b7b4483d 100644 --- a/crates/viewer/re_viewport/Cargo.toml +++ b/crates/viewer/re_viewport/Cargo.toml @@ -39,6 +39,5 @@ re_viewport_blueprint.workspace = true ahash.workspace = true egui_tiles.workspace = true egui.workspace = true -itertools.workspace = true nohash-hasher.workspace = true rayon.workspace = true diff --git a/crates/viewer/re_viewport/src/lib.rs b/crates/viewer/re_viewport/src/lib.rs index 35eaa13fc3db..4bd26c6db689 100644 --- a/crates/viewer/re_viewport/src/lib.rs +++ b/crates/viewer/re_viewport/src/lib.rs @@ -5,7 +5,6 @@ // TODO(#6330): remove unwrap() #![allow(clippy::unwrap_used)] -mod auto_layout; mod system_execution; mod view_highlights; mod viewport_ui; diff --git a/crates/viewer/re_viewport/src/viewport_ui.rs b/crates/viewer/re_viewport/src/viewport_ui.rs index 4c9035e311dc..13294947ff33 100644 --- a/crates/viewer/re_viewport/src/viewport_ui.rs +++ b/crates/viewer/re_viewport/src/viewport_ui.rs @@ -9,9 +9,8 @@ use re_context_menu::{context_menu_ui_for_item, SelectionUpdateBehavior}; use re_log_types::{EntityPath, ResolvedEntityPathRule, RuleEffect}; use re_ui::{design_tokens, ContextExt as _, DesignTokens, Icon, UiExt as _}; use re_viewer_context::{ - blueprint_id_to_tile_id, icon_for_container_kind, Contents, DragAndDropFeedback, - DragAndDropPayload, Item, PublishedViewInfo, SystemExecutionOutput, ViewClassRegistry, ViewId, - ViewQuery, ViewStates, ViewerContext, + icon_for_container_kind, Contents, DragAndDropFeedback, DragAndDropPayload, Item, + PublishedViewInfo, SystemExecutionOutput, ViewId, ViewQuery, ViewStates, ViewerContext, }; use re_viewport_blueprint::{ create_entity_add_info, ViewBlueprint, ViewportBlueprint, ViewportCommand, @@ -19,17 +18,6 @@ use re_viewport_blueprint::{ use crate::system_execution::{execute_systems_for_all_views, execute_systems_for_view}; -fn tree_simplification_options() -> egui_tiles::SimplificationOptions { - egui_tiles::SimplificationOptions { - prune_empty_tabs: false, - all_panes_must_have_tabs: true, - prune_empty_containers: false, - prune_single_child_tabs: false, - prune_single_child_containers: false, - join_nested_linear_containers: true, - } -} - // ---------------------------------------------------------------------------- /// Defines the UI and layout of the Viewport. @@ -306,258 +294,8 @@ impl ViewportUi { self.blueprint.spawn_heuristic_views(ctx); } - /// Process any deferred [`ViewportCommand`] and then save to blueprint store (if needed). - pub fn save_to_blueprint_store( - self, - ctx: &ViewerContext<'_>, - view_class_registry: &ViewClassRegistry, - ) { - re_tracing::profile_function!(); - - let Self { mut blueprint } = self; - - let commands: Vec = blueprint.deferred_commands.lock().drain(..).collect(); - - if commands.is_empty() { - return; // No changes this frame - no need to save to blueprint store. - } - - let mut run_auto_layout = false; - - for command in commands { - apply_viewport_command(ctx, &mut blueprint, command, &mut run_auto_layout); - } - - if run_auto_layout { - blueprint.tree = - super::auto_layout::tree_from_views(view_class_registry, &blueprint.views); - } - - // Simplify before we save the tree. - // `egui_tiles` also runs a simplifying pass when calling `tree.ui`, but that is too late. - // We want the simplified changes saved to the store: - blueprint.tree.simplify(&tree_simplification_options()); - - // TODO(emilk): consider diffing the tree against the state it was in at the start of the frame, - // so that we only save it if it actually changed. - - blueprint.save_tree_as_containers(ctx); - } -} - -fn apply_viewport_command( - ctx: &ViewerContext<'_>, - bp: &mut ViewportBlueprint, - command: ViewportCommand, - run_auto_layout: &mut bool, -) { - re_log::trace!("Processing viewport command: {command:?}"); - match command { - ViewportCommand::SetTree(new_tree) => { - bp.tree = new_tree; - } - - ViewportCommand::AddView { - view, - parent_container, - position_in_parent, - } => { - let view_id = view.id; - - view.save_to_blueprint_store(ctx); - bp.views.insert(view_id, view); - - if bp.auto_layout() { - // No need to add to the tree - we'll create a new tree from scratch instead. - re_log::trace!( - "Running auto-layout after adding a view because auto_layout is turned on" - ); - *run_auto_layout = true; - } else { - // Add the view to the tree: - let parent_id = parent_container.unwrap_or(bp.root_container); - re_log::trace!("Adding view {view_id} to parent {parent_id}"); - let tile_id = bp.tree.tiles.insert_pane(view_id); - let container_tile_id = blueprint_id_to_tile_id(&parent_id); - if let Some(egui_tiles::Tile::Container(container)) = - bp.tree.tiles.get_mut(container_tile_id) - { - re_log::trace!("Inserting new view into root container"); - container.add_child(tile_id); - if let Some(position_in_parent) = position_in_parent { - bp.tree.move_tile_to_container( - tile_id, - container_tile_id, - position_in_parent, - true, - ); - } - } else { - re_log::trace!( - "Parent was not a container (or not found) - will re-run auto-layout" - ); - *run_auto_layout = true; - } - } - } - - ViewportCommand::AddContainer { - container_kind, - parent_container, - } => { - let parent_id = parent_container.unwrap_or(bp.root_container); - - let tile_id = bp - .tree - .tiles - .insert_container(egui_tiles::Container::new(container_kind, vec![])); - - re_log::trace!("Adding container {container_kind:?} to parent {parent_id}"); - - if let Some(egui_tiles::Tile::Container(parent_container)) = - bp.tree.tiles.get_mut(blueprint_id_to_tile_id(&parent_id)) - { - re_log::trace!("Inserting new view into container {parent_id:?}"); - parent_container.add_child(tile_id); - } else { - re_log::trace!("Parent or root was not a container - will re-run auto-layout"); - *run_auto_layout = true; - } - } - - ViewportCommand::SetContainerKind(container_id, container_kind) => { - if let Some(egui_tiles::Tile::Container(container)) = bp - .tree - .tiles - .get_mut(blueprint_id_to_tile_id(&container_id)) - { - re_log::trace!("Mutating container {container_id:?} to {container_kind:?}"); - container.set_kind(container_kind); - } else { - re_log::trace!("No root found - will re-run auto-layout"); - } - } - - ViewportCommand::FocusTab(view_id) => { - let found = bp.tree.make_active(|_, tile| match tile { - egui_tiles::Tile::Pane(this_view_id) => *this_view_id == view_id, - egui_tiles::Tile::Container(_) => false, - }); - re_log::trace!("Found tab to focus on for view ID {view_id}: {found}"); - } - - ViewportCommand::RemoveContents(contents) => { - let tile_id = contents.as_tile_id(); - - for tile in bp.tree.remove_recursively(tile_id) { - re_log::trace!("Removing tile {tile_id:?}"); - match tile { - egui_tiles::Tile::Pane(view_id) => { - re_log::trace!("Removing view {view_id}"); - - // Remove the view from the store - if let Some(view) = bp.views.get(&view_id) { - view.clear(ctx); - } - - // If the view was maximized, clean it up - if bp.maximized == Some(view_id) { - bp.set_maximized(None, ctx); - } - - bp.views.remove(&view_id); - } - egui_tiles::Tile::Container(_) => { - // Empty containers (like this one) will be auto-removed by the tree simplification algorithm, - // that will run later because of this tree edit. - } - } - } - - bp.mark_user_interaction(ctx); - - if Some(tile_id) == bp.tree.root { - bp.tree.root = None; - } - } - - ViewportCommand::SimplifyContainer(container_id, options) => { - re_log::trace!("Simplifying tree with options: {options:?}"); - let tile_id = blueprint_id_to_tile_id(&container_id); - bp.tree.simplify_children_of_tile(tile_id, &options); - } - - ViewportCommand::MakeAllChildrenSameSize(container_id) => { - let tile_id = blueprint_id_to_tile_id(&container_id); - if let Some(egui_tiles::Tile::Container(container)) = bp.tree.tiles.get_mut(tile_id) { - match container { - egui_tiles::Container::Tabs(_) => {} - egui_tiles::Container::Linear(linear) => { - linear.shares = Default::default(); - } - egui_tiles::Container::Grid(grid) => { - grid.col_shares = Default::default(); - grid.row_shares = Default::default(); - } - } - } - } - - ViewportCommand::MoveContents { - contents_to_move, - target_container, - target_position_in_container, - } => { - re_log::trace!( - "Moving {contents_to_move:?} to container {target_container:?} at pos \ - {target_position_in_container}" - ); - - // TODO(ab): the `rev()` is better preserve ordering when moving a group of items. There - // remains some ordering (and possibly insertion point error) edge cases when dragging - // multiple item within the same container. This should be addressed by egui_tiles: - // https://github.com/rerun-io/egui_tiles/issues/90 - for contents in contents_to_move.iter().rev() { - let contents_tile_id = contents.as_tile_id(); - let target_container_tile_id = blueprint_id_to_tile_id(&target_container); - - bp.tree.move_tile_to_container( - contents_tile_id, - target_container_tile_id, - target_position_in_container, - true, - ); - } - } - - ViewportCommand::MoveContentsToNewContainer { - contents_to_move, - new_container_kind, - target_container, - target_position_in_container, - } => { - let new_container_tile_id = bp - .tree - .tiles - .insert_container(egui_tiles::Container::new(new_container_kind, vec![])); - - let target_container_tile_id = blueprint_id_to_tile_id(&target_container); - bp.tree.move_tile_to_container( - new_container_tile_id, - target_container_tile_id, - target_position_in_container, - true, // reflow grid if needed - ); - - for (pos, content) in contents_to_move.into_iter().enumerate() { - bp.tree.move_tile_to_container( - content.as_tile_id(), - new_container_tile_id, - pos, - true, // reflow grid if needed - ); - } - } + pub fn save_to_blueprint_store(self, ctx: &ViewerContext<'_>) { + self.blueprint.save_to_blueprint_store(ctx); } } @@ -877,7 +615,7 @@ impl<'a> egui_tiles::Behavior for TilesDelegate<'a, '_> { /// /// These options are applied on every frame by `egui_tiles`. fn simplification_options(&self) -> egui_tiles::SimplificationOptions { - tree_simplification_options() + re_viewport_blueprint::tree_simplification_options() } // Callbacks: diff --git a/crates/viewer/re_viewport/src/auto_layout.rs b/crates/viewer/re_viewport_blueprint/src/auto_layout.rs similarity index 99% rename from crates/viewer/re_viewport/src/auto_layout.rs rename to crates/viewer/re_viewport_blueprint/src/auto_layout.rs index 6544544fa246..9aee4e47793d 100644 --- a/crates/viewer/re_viewport/src/auto_layout.rs +++ b/crates/viewer/re_viewport_blueprint/src/auto_layout.rs @@ -9,7 +9,7 @@ use itertools::Itertools as _; use re_types::ViewClassIdentifier; use re_viewer_context::ViewId; -use re_viewport_blueprint::ViewBlueprint; +use crate::ViewBlueprint; #[derive(Clone, Debug)] struct SpaceMakeInfo { diff --git a/crates/viewer/re_viewport_blueprint/src/lib.rs b/crates/viewer/re_viewport_blueprint/src/lib.rs index 3068e8c7fb10..442afe92eedd 100644 --- a/crates/viewer/re_viewport_blueprint/src/lib.rs +++ b/crates/viewer/re_viewport_blueprint/src/lib.rs @@ -2,6 +2,7 @@ //! //! This crate provides blueprint (i.e. description) for how to render the viewport. +mod auto_layout; mod container; mod entity_add_info; pub mod ui; @@ -17,7 +18,7 @@ use re_viewer_context::ViewerContext; pub use view::ViewBlueprint; pub use view_contents::ViewContents; pub use view_properties::{entity_path_for_view_property, ViewProperty, ViewPropertyQueryError}; -pub use viewport_blueprint::ViewportBlueprint; +pub use viewport_blueprint::{tree_simplification_options, ViewportBlueprint}; pub use viewport_command::ViewportCommand; /// The entity path of the viewport blueprint in the blueprint store. diff --git a/crates/viewer/re_viewport_blueprint/src/viewport_blueprint.rs b/crates/viewer/re_viewport_blueprint/src/viewport_blueprint.rs index b2594f754134..86a0f8e38dd5 100644 --- a/crates/viewer/re_viewport_blueprint/src/viewport_blueprint.rs +++ b/crates/viewer/re_viewport_blueprint/src/viewport_blueprint.rs @@ -888,6 +888,264 @@ impl ViewportBlueprint { ctx.save_empty_blueprint_component::(&VIEWPORT_PATH.into()); } } + + /// Process any deferred [`ViewportCommand`] and then save to blueprint store (if needed). + pub fn save_to_blueprint_store(mut self, ctx: &ViewerContext<'_>) { + re_tracing::profile_function!(); + + let commands: Vec = self.deferred_commands.lock().drain(..).collect(); + + if commands.is_empty() { + return; // No changes this frame - no need to save to blueprint store. + } + + let mut run_auto_layout = false; + + for command in commands { + apply_viewport_command(ctx, &mut self, command, &mut run_auto_layout); + } + + if run_auto_layout { + self.tree = super::auto_layout::tree_from_views(ctx.view_class_registry, &self.views); + } + + // Simplify before we save the tree. + // `egui_tiles` also runs a simplifying pass when calling `tree.ui`, but that is too late. + // We want the simplified changes saved to the store: + self.tree.simplify(&tree_simplification_options()); + + // TODO(emilk): consider diffing the tree against the state it was in at the start of the frame, + // so that we only save it if it actually changed. + + self.save_tree_as_containers(ctx); + } +} + +pub fn tree_simplification_options() -> egui_tiles::SimplificationOptions { + egui_tiles::SimplificationOptions { + prune_empty_tabs: false, + all_panes_must_have_tabs: true, + prune_empty_containers: false, + prune_single_child_tabs: false, + prune_single_child_containers: false, + join_nested_linear_containers: true, + } +} + +fn apply_viewport_command( + ctx: &ViewerContext<'_>, + bp: &mut ViewportBlueprint, + command: ViewportCommand, + run_auto_layout: &mut bool, +) { + re_log::trace!("Processing viewport command: {command:?}"); + match command { + ViewportCommand::SetTree(new_tree) => { + bp.tree = new_tree; + } + + ViewportCommand::AddView { + view, + parent_container, + position_in_parent, + } => { + let view_id = view.id; + + view.save_to_blueprint_store(ctx); + bp.views.insert(view_id, view); + + if bp.auto_layout() { + // No need to add to the tree - we'll create a new tree from scratch instead. + re_log::trace!( + "Running auto-layout after adding a view because auto_layout is turned on" + ); + *run_auto_layout = true; + } else { + // Add the view to the tree: + let parent_id = parent_container.unwrap_or(bp.root_container); + re_log::trace!("Adding view {view_id} to parent {parent_id}"); + let tile_id = bp.tree.tiles.insert_pane(view_id); + let container_tile_id = blueprint_id_to_tile_id(&parent_id); + if let Some(egui_tiles::Tile::Container(container)) = + bp.tree.tiles.get_mut(container_tile_id) + { + re_log::trace!("Inserting new view into root container"); + container.add_child(tile_id); + if let Some(position_in_parent) = position_in_parent { + bp.tree.move_tile_to_container( + tile_id, + container_tile_id, + position_in_parent, + true, + ); + } + } else { + re_log::trace!( + "Parent was not a container (or not found) - will re-run auto-layout" + ); + *run_auto_layout = true; + } + } + } + + ViewportCommand::AddContainer { + container_kind, + parent_container, + } => { + let parent_id = parent_container.unwrap_or(bp.root_container); + + let tile_id = bp + .tree + .tiles + .insert_container(egui_tiles::Container::new(container_kind, vec![])); + + re_log::trace!("Adding container {container_kind:?} to parent {parent_id}"); + + if let Some(egui_tiles::Tile::Container(parent_container)) = + bp.tree.tiles.get_mut(blueprint_id_to_tile_id(&parent_id)) + { + re_log::trace!("Inserting new view into container {parent_id:?}"); + parent_container.add_child(tile_id); + } else { + re_log::trace!("Parent or root was not a container - will re-run auto-layout"); + *run_auto_layout = true; + } + } + + ViewportCommand::SetContainerKind(container_id, container_kind) => { + if let Some(egui_tiles::Tile::Container(container)) = bp + .tree + .tiles + .get_mut(blueprint_id_to_tile_id(&container_id)) + { + re_log::trace!("Mutating container {container_id:?} to {container_kind:?}"); + container.set_kind(container_kind); + } else { + re_log::trace!("No root found - will re-run auto-layout"); + } + } + + ViewportCommand::FocusTab(view_id) => { + let found = bp.tree.make_active(|_, tile| match tile { + egui_tiles::Tile::Pane(this_view_id) => *this_view_id == view_id, + egui_tiles::Tile::Container(_) => false, + }); + re_log::trace!("Found tab to focus on for view ID {view_id}: {found}"); + } + + ViewportCommand::RemoveContents(contents) => { + let tile_id = contents.as_tile_id(); + + for tile in bp.tree.remove_recursively(tile_id) { + re_log::trace!("Removing tile {tile_id:?}"); + match tile { + egui_tiles::Tile::Pane(view_id) => { + re_log::trace!("Removing view {view_id}"); + + // Remove the view from the store + if let Some(view) = bp.views.get(&view_id) { + view.clear(ctx); + } + + // If the view was maximized, clean it up + if bp.maximized == Some(view_id) { + bp.set_maximized(None, ctx); + } + + bp.views.remove(&view_id); + } + egui_tiles::Tile::Container(_) => { + // Empty containers (like this one) will be auto-removed by the tree simplification algorithm, + // that will run later because of this tree edit. + } + } + } + + bp.mark_user_interaction(ctx); + + if Some(tile_id) == bp.tree.root { + bp.tree.root = None; + } + } + + ViewportCommand::SimplifyContainer(container_id, options) => { + re_log::trace!("Simplifying tree with options: {options:?}"); + let tile_id = blueprint_id_to_tile_id(&container_id); + bp.tree.simplify_children_of_tile(tile_id, &options); + } + + ViewportCommand::MakeAllChildrenSameSize(container_id) => { + let tile_id = blueprint_id_to_tile_id(&container_id); + if let Some(egui_tiles::Tile::Container(container)) = bp.tree.tiles.get_mut(tile_id) { + match container { + egui_tiles::Container::Tabs(_) => {} + egui_tiles::Container::Linear(linear) => { + linear.shares = Default::default(); + } + egui_tiles::Container::Grid(grid) => { + grid.col_shares = Default::default(); + grid.row_shares = Default::default(); + } + } + } + } + + ViewportCommand::MoveContents { + contents_to_move, + target_container, + target_position_in_container, + } => { + re_log::trace!( + "Moving {contents_to_move:?} to container {target_container:?} at pos \ + {target_position_in_container}" + ); + + // TODO(ab): the `rev()` is better preserve ordering when moving a group of items. There + // remains some ordering (and possibly insertion point error) edge cases when dragging + // multiple item within the same container. This should be addressed by egui_tiles: + // https://github.com/rerun-io/egui_tiles/issues/90 + for contents in contents_to_move.iter().rev() { + let contents_tile_id = contents.as_tile_id(); + let target_container_tile_id = blueprint_id_to_tile_id(&target_container); + + bp.tree.move_tile_to_container( + contents_tile_id, + target_container_tile_id, + target_position_in_container, + true, + ); + } + } + + ViewportCommand::MoveContentsToNewContainer { + contents_to_move, + new_container_kind, + target_container, + target_position_in_container, + } => { + let new_container_tile_id = bp + .tree + .tiles + .insert_container(egui_tiles::Container::new(new_container_kind, vec![])); + + let target_container_tile_id = blueprint_id_to_tile_id(&target_container); + bp.tree.move_tile_to_container( + new_container_tile_id, + target_container_tile_id, + target_position_in_container, + true, // reflow grid if needed + ); + + for (pos, content) in contents_to_move.into_iter().enumerate() { + bp.tree.move_tile_to_container( + content.as_tile_id(), + new_container_tile_id, + pos, + true, // reflow grid if needed + ); + } + } + } } fn build_tree_from_views_and_containers<'a>( From b1dc31c4bc60b83f6ad574e1cea00911af5cbd82 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 17 Jan 2025 07:55:32 +0100 Subject: [PATCH 50/57] Add missing feature flags to arrow2, to fix CI (#8720) --- crates/utils/re_arrow_util/Cargo.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/utils/re_arrow_util/Cargo.toml b/crates/utils/re_arrow_util/Cargo.toml index 68a36945c59d..126ecf1d831c 100644 --- a/crates/utils/re_arrow_util/Cargo.toml +++ b/crates/utils/re_arrow_util/Cargo.toml @@ -27,5 +27,9 @@ re_log.workspace = true re_tracing.workspace = true arrow.workspace = true -arrow2.workspace = true +arrow2 = { workspace = true, features = [ + "compute_concatenate", + "compute_filter", + "compute_take", +] } itertools.workspace = true From cae7a6a8d8a65d03b4b8c1013310c09334c83fba Mon Sep 17 00:00:00 2001 From: Clement Rey Date: Fri, 17 Jan 2025 09:21:49 +0100 Subject: [PATCH 51/57] Add `any_values` and `extra_values` snippets for rust (#8718) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the new `SerializedComponentBatch` acting as the core logging type in Rust, we can now emulate Python's `AnyValue`s with little efforts. ```rust fn main() -> Result<(), Box> { let rec = rerun::RecordingStreamBuilder::new("rerun_example_any_values").spawn()?; let confidences = rerun::SerializedComponentBatch::new( Arc::new(arrow::array::Float64Array::from(vec![1.2, 3.4, 5.6])), rerun::ComponentDescriptor::new("confidence"), ); let description = rerun::SerializedComponentBatch::new( Arc::new(arrow::array::StringArray::from(vec!["Bla bla bla…"])), rerun::ComponentDescriptor::new("description"), ); rec.log("any_values", &[confidences, description])?; Ok(()) } ``` --- docs/snippets/INDEX.md | 12 +++++------ docs/snippets/all/tutorials/any_values.rs | 23 +++++++++++++++++++++ docs/snippets/all/tutorials/extra_values.py | 2 +- docs/snippets/all/tutorials/extra_values.rs | 22 ++++++++++++++++++++ docs/snippets/snippets.toml | 5 +++-- lychee.toml | 10 +++++---- 6 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 docs/snippets/all/tutorials/any_values.rs create mode 100644 docs/snippets/all/tutorials/extra_values.rs diff --git a/docs/snippets/INDEX.md b/docs/snippets/INDEX.md index abd75b46af08..ff1d6402e89d 100644 --- a/docs/snippets/INDEX.md +++ b/docs/snippets/INDEX.md @@ -24,9 +24,9 @@ Use it to quickly find copy-pastable snippets of code for any Rerun feature you' | ------- | ------- | ----------- | ------ | ---- | --- | | **Dataframes** | `dataframe_query` | Query and display the first 10 rows of a recording | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/reference/dataframe_query.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/reference/dataframe_query.rs) | | | **Dataframes** | `dataframe_view_query` | Query and display the first 10 rows of a recording in a dataframe view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/reference/dataframe_view_query.py) | | | -| **`AnyValue`** | `any_values` | Log arbitrary data | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/any_values.py) | | | +| **`AnyValue`** | `any_values` | Log arbitrary data | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/any_values.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/any_values.rs) | | | **`AnyValue`** | `any_values_send_columns` | Use `AnyValues` and `send_column` to send entire columns of custom data to Rerun | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/howto/any_values_send_columns.py) | | | -| **`AnyValue`** | `extra_values` | Log extra values with a Points2D | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.py) | | | +| **`AnyValue`** | `extra_values` | Log extra values with a `Points2D` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.rs) | | @@ -124,7 +124,7 @@ _All snippets, organized by the [`Archetype`](https://rerun.io/docs/reference/ty | **[`Points2D`](https://rerun.io/docs/reference/types/archetypes/points2d)** | `concepts/different_data_per_timeline` | Log different data on different timelines | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.cpp) | | **[`Points2D`](https://rerun.io/docs/reference/types/archetypes/points2d)** | `concepts/viscomp-visualizer-override` | Override a visualizer | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/viscomp-visualizer-override.py) | | | | **[`Points2D`](https://rerun.io/docs/reference/types/archetypes/points2d)** | `concepts/viscomp-visualizer-override-multiple` | Override a visualizer | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/viscomp-visualizer-override-multiple.py) | | | -| **[`Points2D`](https://rerun.io/docs/reference/types/archetypes/points2d)** | `tutorials/extra_values` | Log extra values with a Points2D | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.py) | | | +| **[`Points2D`](https://rerun.io/docs/reference/types/archetypes/points2d)** | `tutorials/extra_values` | Log extra values with a `Points2D` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.rs) | | | **[`Points2D`](https://rerun.io/docs/reference/types/archetypes/points2d)** | `views/spatial2d` | Use a blueprint to customize a Spatial2DView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/spatial2d.py) | | | | **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `archetypes/points3d_ui_radius` | Log some points with ui points & scene unit radii | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_ui_radius.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_ui_radius.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_ui_radius.cpp) | | **[`Points3D`](https://rerun.io/docs/reference/types/archetypes/points3d)** | `archetypes/points3d_simple` | Log some very simple points | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_simple.cpp) | @@ -307,7 +307,7 @@ _All snippets, organized by the [`View`](https://rerun.io/docs/reference/types/v | **[`Spatial2DView`](https://rerun.io/docs/reference/types/views/spatial2d_view)** | `concepts/viscomp-component-override` | Override a component | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/viscomp-component-override.py) | | | | **[`Spatial2DView`](https://rerun.io/docs/reference/types/views/spatial2d_view)** | `concepts/viscomp-visualizer-override` | Override a visualizer | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/viscomp-visualizer-override.py) | | | | **[`Spatial2DView`](https://rerun.io/docs/reference/types/views/spatial2d_view)** | `concepts/viscomp-visualizer-override-multiple` | Override a visualizer | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/viscomp-visualizer-override-multiple.py) | | | -| **[`Spatial2DView`](https://rerun.io/docs/reference/types/views/spatial2d_view)** | `tutorials/extra_values` | Log extra values with a Points2D | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.py) | | | +| **[`Spatial2DView`](https://rerun.io/docs/reference/types/views/spatial2d_view)** | `tutorials/extra_values` | Log extra values with a `Points2D` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.rs) | | | **[`Spatial2DView`](https://rerun.io/docs/reference/types/views/spatial2d_view)** | `views/spatial2d` | Use a blueprint to customize a Spatial2DView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/spatial2d.py) | | | | **[`Spatial3DView`](https://rerun.io/docs/reference/types/views/spatial3d_view)** | `archetypes/transform3d_hierarchy` | Logs a transforms transform hierarchy | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_hierarchy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_hierarchy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_hierarchy.cpp) | | **[`Spatial3DView`](https://rerun.io/docs/reference/types/views/spatial3d_view)** | `views/spatial3d` | Use a blueprint to customize a Spatial3DView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/spatial3d.py) | | | @@ -343,7 +343,7 @@ _All snippets, organized by the blueprint-related [`Archetype`](https://rerun.io | **`VisualBounds2D`** | `archetypes/points2d_simple` | Log some very simple points | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_simple.cpp) | | **`VisualBounds2D`** | `archetypes/points2d_ui_radius` | Log some points with ui points & scene unit radii | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_ui_radius.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_ui_radius.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_ui_radius.cpp) | | **`VisualBounds2D`** | `concepts/different_data_per_timeline` | Log different data on different timelines | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.cpp) | -| **`VisualBounds2D`** | `tutorials/extra_values` | Log extra values with a Points2D | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.py) | | | +| **`VisualBounds2D`** | `tutorials/extra_values` | Log extra values with a `Points2D` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.rs) | | | **`VisualBounds2D`** | `views/graph` | Use a blueprint to customize a graph view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/graph.py) | | | | **`VisualBounds2D`** | `views/spatial2d` | Use a blueprint to customize a Spatial2DView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/spatial2d.py) | | | @@ -367,7 +367,7 @@ _All snippets, organized by the blueprint-related [`Component`](https://rerun.io | **`VisualBounds2D`** | `archetypes/points2d_simple` | Log some very simple points | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_simple.cpp) | | **`VisualBounds2D`** | `archetypes/points2d_ui_radius` | Log some points with ui points & scene unit radii | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_ui_radius.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_ui_radius.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points2d_ui_radius.cpp) | | **`VisualBounds2D`** | `concepts/different_data_per_timeline` | Log different data on different timelines | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/different_data_per_timeline.cpp) | -| **`VisualBounds2D`** | `tutorials/extra_values` | Log extra values with a Points2D | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.py) | | | +| **`VisualBounds2D`** | `tutorials/extra_values` | Log extra values with a `Points2D` | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.rs) | | | **`VisualBounds2D`** | `views/graph` | Use a blueprint to customize a graph view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/graph.py) | | | | **`VisualBounds2D`** | `views/spatial2d` | Use a blueprint to customize a Spatial2DView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/spatial2d.py) | | | | **`VisualizerOverrides`** | `concepts/viscomp-visualizer-override` | Override a visualizer | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/concepts/viscomp-visualizer-override.py) | | | diff --git a/docs/snippets/all/tutorials/any_values.rs b/docs/snippets/all/tutorials/any_values.rs new file mode 100644 index 000000000000..198484d16fa8 --- /dev/null +++ b/docs/snippets/all/tutorials/any_values.rs @@ -0,0 +1,23 @@ +//! Log arbitrary data. + +use std::sync::Arc; + +use rerun::external::arrow; + +fn main() -> Result<(), Box> { + let rec = rerun::RecordingStreamBuilder::new("rerun_example_any_values").spawn()?; + + let confidences = rerun::SerializedComponentBatch::new( + Arc::new(arrow::array::Float64Array::from(vec![1.2, 3.4, 5.6])), + rerun::ComponentDescriptor::new("confidence"), + ); + + let description = rerun::SerializedComponentBatch::new( + Arc::new(arrow::array::StringArray::from(vec!["Bla bla bla…"])), + rerun::ComponentDescriptor::new("description"), + ); + + rec.log("any_values", &[confidences, description])?; + + Ok(()) +} diff --git a/docs/snippets/all/tutorials/extra_values.py b/docs/snippets/all/tutorials/extra_values.py index d8d65fea4af4..9c4809e31f03 100644 --- a/docs/snippets/all/tutorials/extra_values.py +++ b/docs/snippets/all/tutorials/extra_values.py @@ -1,4 +1,4 @@ -"""Log extra values with a Points2D.""" +"""Log extra values with a `Points2D`.""" import rerun as rr import rerun.blueprint as rrb diff --git a/docs/snippets/all/tutorials/extra_values.rs b/docs/snippets/all/tutorials/extra_values.rs new file mode 100644 index 000000000000..cda43cf26fd6 --- /dev/null +++ b/docs/snippets/all/tutorials/extra_values.rs @@ -0,0 +1,22 @@ +//! Log extra values with a `Points2D`. + +use std::sync::Arc; + +use rerun::external::arrow; + +fn main() -> Result<(), Box> { + let rec = rerun::RecordingStreamBuilder::new("rerun_example_extra_values").spawn()?; + + let points = rerun::Points2D::new([(-1.0, -1.0), (-1.0, 1.0), (1.0, -1.0), (1.0, 1.0)]); + let confidences = rerun::SerializedComponentBatch::new( + Arc::new(arrow::array::Float64Array::from(vec![0.3, 0.4, 0.5, 0.6])), + rerun::ComponentDescriptor::new("confidence"), + ); + + rec.log( + "extra_values", + &[&points as &dyn rerun::AsComponents, &confidences], + )?; + + Ok(()) +} diff --git a/docs/snippets/snippets.toml b/docs/snippets/snippets.toml index 3001e5c1b9dc..429c138395f6 100644 --- a/docs/snippets/snippets.toml +++ b/docs/snippets/snippets.toml @@ -134,7 +134,6 @@ ] "tutorials/any_values" = [ # Not yet implemented "cpp", - "rust", ] "tutorials/custom-application-id" = [ # Not a complete examples "cpp", @@ -151,7 +150,9 @@ "rust", "py", ] -"tutorials/extra_values" = ["cpp", "rust"] # Missing examples +"tutorials/extra_values" = [ # Missing examples + "cpp", +] "tutorials/log-file" = [ # Not a complete examples "cpp", "rust", diff --git a/lychee.toml b/lychee.toml index dbe1ae32f097..26cd9309d017 100644 --- a/lychee.toml +++ b/lychee.toml @@ -154,13 +154,15 @@ exclude = [ # '^file:///', # Ignore local file links. They need to be tested, but it's useful for external links we have to ping. # Snippets that haven't been released yet. - 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py', - 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py', 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.cpp', - 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp', + 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.py', 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates.rs', + 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp', + 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py', 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs', - 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.py', 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.cpp', + 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.py', 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/transform3d_partial_updates.rs', + 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/any_values.rs', + 'https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/extra_values.rs', ] From fb14c334dd2236acd85823c816f4e9e8466aaf73 Mon Sep 17 00:00:00 2001 From: Olivier Le Doeuff Date: Fri, 17 Jan 2025 11:23:46 +0100 Subject: [PATCH 52/57] doc: Update `annotation-context.rs` to use correct API (#8708) Co-authored-by: Antoine Beyeler Co-authored-by: Clement Rey --- docs/content/concepts/annotation-context.md | 2 +- .../all/tutorials/annotation-context.rs | 56 ------------------- .../all/tutorials/annotation_context.cpp | 38 +++++++++++++ ...ation-context.py => annotation_context.py} | 4 +- .../all/tutorials/annotation_context.rs | 40 +++++++++++++ docs/snippets/snippets.toml | 5 -- 6 files changed, 82 insertions(+), 63 deletions(-) delete mode 100644 docs/snippets/all/tutorials/annotation-context.rs create mode 100644 docs/snippets/all/tutorials/annotation_context.cpp rename docs/snippets/all/tutorials/{annotation-context.py => annotation_context.py} (89%) create mode 100644 docs/snippets/all/tutorials/annotation_context.rs diff --git a/docs/content/concepts/annotation-context.md b/docs/content/concepts/annotation-context.md index cd89d4cee311..a70f22d224d3 100644 --- a/docs/content/concepts/annotation-context.md +++ b/docs/content/concepts/annotation-context.md @@ -56,7 +56,7 @@ Annotation contexts are logged with: * Python: 🐍[`rr.AnnotationContext`](https://ref.rerun.io/docs/python/stable/common/archetypes/#rerun.archetypes.AnnotationContext) * Rust: 🦀[`rerun::AnnotationContext`](https://docs.rs/rerun/latest/rerun/archetypes/struct.AnnotationContext.html#) -snippet: tutorials/annotation-context +snippet: tutorials/annotation_context ## Affected entities diff --git a/docs/snippets/all/tutorials/annotation-context.rs b/docs/snippets/all/tutorials/annotation-context.rs deleted file mode 100644 index fa5bab0a4c96..000000000000 --- a/docs/snippets/all/tutorials/annotation-context.rs +++ /dev/null @@ -1,56 +0,0 @@ -// Annotation context with two classes, using two labeled classes, of which ones defines a color. -MsgSender::new("masks") // Applies to all entities below "masks". - .with_static(true) - .with_component(&[AnnotationContext { - class_map: [ - ClassDescription { - info: AnnotationInfo { - id: 0, - label: Some(Label("Background".into())), - color: None, - }, - ..Default::default() - }, - ClassDescription { - info: AnnotationInfo { - id: 0, - label: Some(Label("Person".into())), - color: Some(Color(0xFF000000)), - }, - ..Default::default() - }, - ] - .into_iter() - .map(|class| (ClassId(class.info.id), class)) - .collect(), - }])? - .send(rec)?; - -// Annotation context with simple keypoints & keypoint connections. -MsgSender::new("detections") // Applies to all entities below "detections". - .with_static(true) - .with_component(&[AnnotationContext { - class_map: std::iter::once(( - ClassId(0), - ClassDescription { - info: AnnotationInfo { - id: 0, - label: Some(Label("Snake".into())), - color: None, - }, - keypoint_map: (0..10) - .map(|i| AnnotationInfo { - id: i, - label: None, - color: Some(Color::from_rgb(0, (255 / 9 * i) as u8, 0)), - }) - .map(|keypoint| (KeypointId(keypoint.id), keypoint)) - .collect(), - keypoint_connections: (0..9) - .map(|i| (KeypointId(i), KeypointId(i + 1))) - .collect(), - }, - )) - .collect(), - }])? - .send(rec)?; diff --git a/docs/snippets/all/tutorials/annotation_context.cpp b/docs/snippets/all/tutorials/annotation_context.cpp new file mode 100644 index 000000000000..d4dde5c3f0ba --- /dev/null +++ b/docs/snippets/all/tutorials/annotation_context.cpp @@ -0,0 +1,38 @@ +#include + +int main() { + const auto rec = rerun::RecordingStream("rerun_example_annotation_context_connections"); + rec.spawn().exit_on_failure(); + + // Annotation context with two classes, using two labeled classes, of which ones defines a + // color. + rec.log_static( + "masks", + rerun::AnnotationContext({ + rerun::AnnotationInfo(0, "Background"), + rerun::AnnotationInfo(1, "Person", rerun::Rgba32(255, 0, 0)), + }) + ); + + // Annotation context with simple keypoints & keypoint connections. + std::vector keypoint_annotations; + for (uint16_t i = 0; i < 10; ++i) { + keypoint_annotations.push_back( + rerun::AnnotationInfo(i, rerun::Rgba32(0, static_cast(28 * i), 0)) + ); + } + + std::vector keypoint_connections; + for (uint16_t i = 0; i < 9; ++i) { + keypoint_connections.push_back(rerun::KeypointPair(i, i + 1)); + } + + rec.log_static( + "detections", // Applies to all entities below "detections". + rerun::AnnotationContext({rerun::ClassDescription( + rerun::AnnotationInfo(0, "Snake"), + keypoint_annotations, + keypoint_connections + )}) + ); +} diff --git a/docs/snippets/all/tutorials/annotation-context.py b/docs/snippets/all/tutorials/annotation_context.py similarity index 89% rename from docs/snippets/all/tutorials/annotation-context.py rename to docs/snippets/all/tutorials/annotation_context.py index 4931b28db951..62c4d6d94472 100644 --- a/docs/snippets/all/tutorials/annotation-context.py +++ b/docs/snippets/all/tutorials/annotation_context.py @@ -1,5 +1,7 @@ import rerun as rr +rr.init("rerun_example_annotation_context_connections") + # Annotation context with two classes, using two labeled classes, of which ones defines a color. rr.log( "masks", # Applies to all entities below "masks". @@ -17,7 +19,7 @@ "detections", # Applies to all entities below "detections". rr.ClassDescription( info=rr.AnnotationInfo(0, label="Snake"), - keypoint_annotations=[rr.AnnotationInfo(id=i, color=(0, 255 / 9 * i, 0)) for i in range(10)], + keypoint_annotations=[rr.AnnotationInfo(id=i, color=(0, 28 * i, 0)) for i in range(10)], keypoint_connections=[(i, i + 1) for i in range(9)], ), static=True, diff --git a/docs/snippets/all/tutorials/annotation_context.rs b/docs/snippets/all/tutorials/annotation_context.rs new file mode 100644 index 000000000000..9c105d574749 --- /dev/null +++ b/docs/snippets/all/tutorials/annotation_context.rs @@ -0,0 +1,40 @@ +use rerun::{ + datatypes::{ClassDescriptionMapElem, KeypointId}, + AnnotationContext, AnnotationInfo, ClassDescription, Rgba32, +}; + +fn main() -> Result<(), Box> { + let rec = rerun::RecordingStreamBuilder::new("rerun_example_annotation_context_connections") + .spawn()?; + + // Annotation context with two classes, using two labeled classes, of which ones defines a + // color. + rec.log_static( + "masks", // Applies to all entities below "masks". + &AnnotationContext::new([ + ClassDescriptionMapElem::from((0, "Background")), + ClassDescriptionMapElem::from((1, "Person", Rgba32::from_rgb(255, 0, 0))), + ]), + )?; + + // Annotation context with simple keypoints & keypoint connections. + rec.log_static( + "detections", // Applies to all entities below "detections". + &AnnotationContext::new([ClassDescription { + info: (0, "Snake").into(), + keypoint_annotations: (0..10) + .map(|i| AnnotationInfo { + id: i, + label: None, + color: Some(Rgba32::from_rgb(0, (28 * i) as u8, 0)), + }) + .collect(), + keypoint_connections: (0..9) + .map(|i| (KeypointId(i), KeypointId(i + 1))) + .map(Into::into) + .collect(), + }]), + )?; + + Ok(()) +} diff --git a/docs/snippets/snippets.toml b/docs/snippets/snippets.toml index 429c138395f6..98df865bfb43 100644 --- a/docs/snippets/snippets.toml +++ b/docs/snippets/snippets.toml @@ -127,11 +127,6 @@ "rust", "py", ] -"tutorials/annotation-context" = [ # Not a complete example - "cpp", - "rust", - "py", -] "tutorials/any_values" = [ # Not yet implemented "cpp", ] From 4db780c76e0d9990cb7118b20f3e4ac68f96aa33 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Fri, 17 Jan 2025 11:30:31 +0100 Subject: [PATCH 53/57] Pin ci machines with Vulkan setup to Ubuntu 22.04 (#8721) `ubuntu-latest` got updated to imply Ubuntu 24. This makes our software rasterizer script fail with ``` ERROR: [Loader Message] Code 0 : libLLVM-15.so.1: cannot open shared object file: No such file or directory ERROR: libLLVM-15.so.1: cannot open shared object file: No such file or directory ``` when running vulkaninfo. Surely we can fix this by installing the necessary dependencies, but for now let's just pin this to the previous OS version. --- .github/workflows/contrib_checks.yml | 6 ++++-- .github/workflows/reusable_checks_rust.yml | 3 ++- crates/utils/re_video/src/decode/mod.rs | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/contrib_checks.yml b/.github/workflows/contrib_checks.yml index 44f68ed6d9ab..ddaad0e4dc06 100644 --- a/.github/workflows/contrib_checks.yml +++ b/.github/workflows/contrib_checks.yml @@ -76,7 +76,8 @@ jobs: no-codegen-changes: name: Check if running codegen would produce any changes - runs-on: ubuntu-latest-16-cores + # TODO(andreas): setup-vulkan doesn't work on 24.4 right now due to missing .so + runs-on: ubuntu-22.04-large steps: # Note: We explicitly don't override `ref` here. We need to see if changes would be made # in a context where we have merged with main. Otherwise we might miss changes such as one @@ -92,7 +93,8 @@ jobs: rs-lints: name: Rust lints (fmt, check, clippy, tests, doc) - runs-on: ubuntu-latest-16-cores + # TODO(andreas): setup-vulkan doesn't work on 24.4 right now due to missing .so + runs-on: ubuntu-22.04-16core steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/reusable_checks_rust.yml b/.github/workflows/reusable_checks_rust.yml index 5d42487f45b3..3140ac967af1 100644 --- a/.github/workflows/reusable_checks_rust.yml +++ b/.github/workflows/reusable_checks_rust.yml @@ -52,7 +52,8 @@ jobs: rs-lints: name: Rust lints (fmt, check, clippy, tests, doc) - runs-on: ubuntu-latest-16-cores + # TODO(andreas): setup-vulkan doesn't work on 24.4 right now due to missing .so + runs-on: ubuntu-22.04-large steps: - uses: actions/checkout@v4 with: diff --git a/crates/utils/re_video/src/decode/mod.rs b/crates/utils/re_video/src/decode/mod.rs index b8f4f3db1322..52e092b71d3a 100644 --- a/crates/utils/re_video/src/decode/mod.rs +++ b/crates/utils/re_video/src/decode/mod.rs @@ -337,7 +337,7 @@ pub enum PixelFormat { Yuv { layout: YuvPixelLayout, range: YuvRange, - // TODO(andreas): color primaries should also apply to RGB data, + // TODO(andreas): Color primaries should also apply to RGB data, // but for now we just always assume RGB to be BT.709 ~= sRGB. coefficients: YuvMatrixCoefficients, // Note that we don't handle chroma sample location at all so far. From a0c8c368096acc6c193a43c98decc88f13048ebc Mon Sep 17 00:00:00 2001 From: Antoine Beyeler <49431240+abey79@users.noreply.github.com> Date: Fri, 17 Jan 2025 11:33:43 +0100 Subject: [PATCH 54/57] Fix CI (#8722) --- docs/snippets/INDEX.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/snippets/INDEX.md b/docs/snippets/INDEX.md index ff1d6402e89d..c34be42a0af0 100644 --- a/docs/snippets/INDEX.md +++ b/docs/snippets/INDEX.md @@ -39,11 +39,11 @@ _All snippets, organized by the [`Archetype`](https://rerun.io/docs/reference/ty | Archetype | Snippet | Description | Python | Rust | C++ | | --------- | ------- | ----------- | ------ | ---- | --- | +| **[`AnnotationContext`](https://rerun.io/docs/reference/types/archetypes/annotation_context)** | `tutorials/annotation_context` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation_context.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation_context.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation_context.cpp) | | **[`AnnotationContext`](https://rerun.io/docs/reference/types/archetypes/annotation_context)** | `archetypes/annotation_context_segmentation` | Log a segmentation image with annotations | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_segmentation.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_segmentation.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_segmentation.cpp) | | **[`AnnotationContext`](https://rerun.io/docs/reference/types/archetypes/annotation_context)** | `archetypes/annotation_context_rects` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_rects.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_rects.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_rects.cpp) | | **[`AnnotationContext`](https://rerun.io/docs/reference/types/archetypes/annotation_context)** | `archetypes/annotation_context_connections` | Log annotation context with connections between keypoints | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_connections.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_connections.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_connections.cpp) | | **[`AnnotationContext`](https://rerun.io/docs/reference/types/archetypes/annotation_context)** | `archetypes/segmentation_image_simple` | Create and log a segmentation image | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/segmentation_image_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/segmentation_image_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/segmentation_image_simple.cpp) | -| **[`AnnotationContext`](https://rerun.io/docs/reference/types/archetypes/annotation_context)** | `tutorials/annotation-context` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation-context.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation-context.rs) | | | **[`Arrows2D`](https://rerun.io/docs/reference/types/archetypes/arrows2d)** | `archetypes/arrows2d_simple` | Log a batch of 2D arrows | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/arrows2d_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/arrows2d_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/arrows2d_simple.cpp) | | **[`Arrows3D`](https://rerun.io/docs/reference/types/archetypes/arrows3d)** | `archetypes/arrows3d_simple` | Log a batch of 3D arrows | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/arrows3d_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/arrows3d_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/arrows3d_simple.cpp) | | **[`Arrows3D`](https://rerun.io/docs/reference/types/archetypes/arrows3d)** | `archetypes/clear_recursive` | Log and then clear data recursively | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/clear_recursive.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/clear_recursive.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/clear_recursive.cpp) | @@ -196,11 +196,11 @@ _All snippets, organized by the [`Component`](https://rerun.io/docs/reference/ty | Component | Snippet | Description | Python | Rust | C++ | | --------- | ------- | ----------- | ------ | ---- | --- | +| **[`AnnotationContext`](https://rerun.io/docs/reference/types/components/annotation_context)** | `tutorials/annotation_context` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation_context.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation_context.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation_context.cpp) | | **[`AnnotationContext`](https://rerun.io/docs/reference/types/components/annotation_context)** | `archetypes/annotation_context_segmentation` | Log a segmentation image with annotations | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_segmentation.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_segmentation.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_segmentation.cpp) | | **[`AnnotationContext`](https://rerun.io/docs/reference/types/components/annotation_context)** | `archetypes/annotation_context_rects` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_rects.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_rects.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_rects.cpp) | | **[`AnnotationContext`](https://rerun.io/docs/reference/types/components/annotation_context)** | `archetypes/annotation_context_connections` | Log annotation context with connections between keypoints | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_connections.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_connections.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/annotation_context_connections.cpp) | | **[`AnnotationContext`](https://rerun.io/docs/reference/types/components/annotation_context)** | `archetypes/segmentation_image_simple` | Create and log a segmentation image | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/segmentation_image_simple.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/segmentation_image_simple.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/segmentation_image_simple.cpp) | -| **[`AnnotationContext`](https://rerun.io/docs/reference/types/components/annotation_context)** | `tutorials/annotation-context` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation-context.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation-context.rs) | | | **[`ClassId`](https://rerun.io/docs/reference/types/components/class_id)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | | **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `archetypes/points3d_partial_updates_legacy` | Demonstrates usage of the new partial updates APIs | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_partial_updates_legacy.cpp) | | **[`Color`](https://rerun.io/docs/reference/types/components/color)** | `archetypes/points3d_send_columns` | Use the `send_columns` API to send several point clouds over time in a single call | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_send_columns.py) | | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/archetypes/points3d_send_columns.cpp) | @@ -327,7 +327,7 @@ _All snippets, organized by the blueprint-related [`Archetype`](https://rerun.io | Archetype | Snippet | Description | Python | Rust | C++ | | --------- | ------- | ----------- | ------ | ---- | --- | -| **`Background`** | `tutorials/annotation-context` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation-context.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation-context.rs) | | +| **`Background`** | `tutorials/annotation_context` | | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation_context.py) | [🦀](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation_context.rs) | [🌊](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/tutorials/annotation_context.cpp) | | **`DataframeQuery`** | `reference/dataframe_view_query` | Query and display the first 10 rows of a recording in a dataframe view | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/reference/dataframe_view_query.py) | | | | **`DataframeQuery`** | `views/dataframe` | Use a blueprint to customize a DataframeView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/dataframe.py) | | | | **`LineGrid3D`** | `views/spatial3d` | Use a blueprint to customize a Spatial3DView | [🐍](https://github.com/rerun-io/rerun/blob/main/docs/snippets/all/views/spatial3d.py) | | | From fdf065f693d42e3287277c1b152aa79853158371 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 17 Jan 2025 11:56:40 +0100 Subject: [PATCH 55/57] Even less arrow2 (#8719) * Part of #3741 Just one small piece at a time --- Cargo.lock | 5 +- crates/store/re_chunk/src/helpers.rs | 54 ++++------- crates/store/re_chunk/src/slice.rs | 36 ++++---- crates/store/re_chunk_store/Cargo.toml | 3 +- crates/store/re_chunk_store/src/dataframe.rs | 88 +++++++----------- .../src/protobuf_conversions.rs | 33 +++---- crates/store/re_chunk_store/src/store.rs | 9 -- crates/store/re_dataframe/src/query.rs | 92 ++++++------------- .../re_protos/proto/rerun/v0/common.proto | 36 +++++--- .../re_protos/proto/rerun/v0/log_msg.proto | 2 +- .../store/re_protos/src/v0/rerun.common.v0.rs | 36 +++++--- .../re_protos/src/v0/rerun.log_msg.v0.rs | 2 +- crates/store/re_query/Cargo.toml | 1 + crates/store/re_query/examples/latest_at.rs | 14 +-- crates/store/re_query/src/latest_at.rs | 28 ++---- rerun_py/Cargo.toml | 1 - rerun_py/src/arrow.rs | 71 +++++++------- rerun_py/src/python_bridge.rs | 4 +- rerun_py/src/video.rs | 8 +- 19 files changed, 206 insertions(+), 317 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b749629b341f..bd18f4c592f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5605,8 +5605,6 @@ dependencies = [ "hashbrown 0.14.5", "num-traits", "rustc_version", - "serde", - "serde_derive", "simdutf8", ] @@ -5748,7 +5746,6 @@ dependencies = [ "re_tracing", "re_types", "re_types_core", - "serde_json", "similar-asserts", "thiserror 1.0.65", "tinyvec", @@ -6234,6 +6231,7 @@ version = "0.22.0-alpha.1+dev" dependencies = [ "ahash", "anyhow", + "arrow", "backtrace", "bytemuck", "criterion", @@ -7418,7 +7416,6 @@ dependencies = [ "pyo3", "pyo3-build-config", "rand", - "re_arrow2", "re_arrow_util", "re_build_info", "re_build_tools", diff --git a/crates/store/re_chunk/src/helpers.rs b/crates/store/re_chunk/src/helpers.rs index 710eba1b6eab..cfeb427c29e1 100644 --- a/crates/store/re_chunk/src/helpers.rs +++ b/crates/store/re_chunk/src/helpers.rs @@ -1,7 +1,7 @@ use std::sync::Arc; -use arrow::array::ArrayRef; -use arrow2::array::Array as Arrow2Array; +use arrow::array::ArrayRef as ArrowArrayRef; +use arrow2::array::Array as _; use re_log_types::{TimeInt, Timeline}; use re_types_core::{Component, ComponentName}; @@ -21,26 +21,13 @@ impl Chunk { &self, component_name: &ComponentName, row_index: usize, - ) -> Option> { - self.component_batch_raw_arrow2(component_name, row_index) - .map(|res| res.map(|array| array.into())) - } - - /// Returns the raw data for the specified component. - /// - /// Returns an error if the row index is out of bounds. - #[inline] - fn component_batch_raw_arrow2( - &self, - component_name: &ComponentName, - row_index: usize, - ) -> Option>> { + ) -> Option> { self.get_first_component(component_name) .and_then(|list_array| { if list_array.len() > row_index { list_array .is_valid(row_index) - .then(|| Ok(list_array.value(row_index))) + .then(|| Ok(list_array.value(row_index).into())) } else { Some(Err(crate::ChunkError::IndexOutOfBounds { kind: "row".to_owned(), @@ -78,7 +65,7 @@ impl Chunk { component_name: &ComponentName, row_index: usize, instance_index: usize, - ) -> Option> { + ) -> Option> { let res = self.component_batch_raw(component_name, row_index)?; let array = match res { @@ -131,7 +118,7 @@ impl Chunk { &self, component_name: &ComponentName, row_index: usize, - ) -> Option> { + ) -> Option> { let res = self.component_batch_raw(component_name, row_index)?; let array = match res { @@ -276,20 +263,11 @@ impl UnitChunkShared { /// Returns the raw data for the specified component. #[inline] - pub fn component_batch_raw(&self, component_name: &ComponentName) -> Option { - self.component_batch_raw_arrow2(component_name) - .map(|array| array.into()) - } - - /// Returns the raw data for the specified component. - #[inline] - pub fn component_batch_raw_arrow2( - &self, - component_name: &ComponentName, - ) -> Option> { + pub fn component_batch_raw(&self, component_name: &ComponentName) -> Option { debug_assert!(self.num_rows() == 1); self.get_first_component(component_name) .and_then(|list_array| list_array.is_valid(0).then(|| list_array.value(0))) + .map(|array| array.into()) } /// Returns the deserialized data for the specified component. @@ -311,10 +289,10 @@ impl UnitChunkShared { &self, component_name: &ComponentName, instance_index: usize, - ) -> Option>> { - let array = self.component_batch_raw_arrow2(component_name)?; + ) -> Option> { + let array = self.component_batch_raw(component_name)?; if array.len() > instance_index { - Some(Ok(array.sliced(instance_index, 1))) + Some(Ok(array.slice(instance_index, 1))) } else { Some(Err(crate::ChunkError::IndexOutOfBounds { kind: "instance".to_owned(), @@ -335,7 +313,7 @@ impl UnitChunkShared { let res = self.component_instance_raw(&C::name(), instance_index)?; let array = match res { - Ok(array) => ArrayRef::from(array), + Ok(array) => array, Err(err) => return Some(Err(err)), }; @@ -354,10 +332,10 @@ impl UnitChunkShared { pub fn component_mono_raw( &self, component_name: &ComponentName, - ) -> Option>> { - let array = self.component_batch_raw_arrow2(component_name)?; + ) -> Option> { + let array = self.component_batch_raw(component_name)?; if array.len() == 1 { - Some(Ok(array.sliced(0, 1))) + Some(Ok(array.slice(0, 1))) } else { Some(Err(crate::ChunkError::IndexOutOfBounds { kind: "mono".to_owned(), @@ -375,7 +353,7 @@ impl UnitChunkShared { let res = self.component_mono_raw(&C::name())?; let array = match res { - Ok(array) => ArrayRef::from(array), + Ok(array) => array, Err(err) => return Some(Err(err)), }; diff --git a/crates/store/re_chunk/src/slice.rs b/crates/store/re_chunk/src/slice.rs index dc233225bf34..6add6bbad8fa 100644 --- a/crates/store/re_chunk/src/slice.rs +++ b/crates/store/re_chunk/src/slice.rs @@ -1,13 +1,11 @@ +use arrow::array::ArrayRef as ArrowArrayRef; use arrow2::array::{ Array as Arrow2Array, BooleanArray as Arrow2BooleanArray, ListArray as Arrow2ListArray, }; - use itertools::Itertools; use nohash_hasher::IntSet; -use re_arrow_util::arrow2_util; -use re_arrow_util::arrow_util; -use re_arrow_util::Arrow2ArrayDowncastRef as _; +use re_arrow_util::{arrow2_util, arrow_util, Arrow2ArrayDowncastRef as _}; use re_log_types::Timeline; use re_types_core::{ComponentDescriptor, ComponentName}; @@ -28,7 +26,7 @@ impl Chunk { &self, row_id: RowId, component_desc: &ComponentDescriptor, - ) -> Option> { + ) -> Option { let list_array = self .components .get(&component_desc.component_name) @@ -51,11 +49,15 @@ impl Chunk { let found_it = times.get(index) == Some(&row_id_time_ns) && incs.get(index) == Some(&row_id_inc); - (found_it && list_array.is_valid(index)).then(|| list_array.value(index)) + (found_it && list_array.is_valid(index)).then(|| list_array.value(index).into()) } else { self.row_ids() .find_position(|id| *id == row_id) - .and_then(|(index, _)| list_array.is_valid(index).then(|| list_array.value(index))) + .and_then(|(index, _)| { + list_array + .is_valid(index) + .then(|| list_array.value(index).into()) + }) } } @@ -1002,8 +1004,8 @@ mod tests { assert!(!chunk.is_sorted()); for (row_id, component_desc, expected) in expectations { - let expected = expected - .and_then(|expected| re_types_core::LoggableBatch::to_arrow2(expected).ok()); + let expected = + expected.and_then(|expected| re_types_core::LoggableBatch::to_arrow(expected).ok()); eprintln!("{component_desc} @ {row_id}"); similar_asserts::assert_eq!(expected, chunk.cell(*row_id, component_desc)); } @@ -1012,8 +1014,8 @@ mod tests { assert!(chunk.is_sorted()); for (row_id, component_desc, expected) in expectations { - let expected = expected - .and_then(|expected| re_types_core::LoggableBatch::to_arrow2(expected).ok()); + let expected = + expected.and_then(|expected| re_types_core::LoggableBatch::to_arrow(expected).ok()); eprintln!("{component_desc} @ {row_id}"); similar_asserts::assert_eq!(expected, chunk.cell(*row_id, component_desc)); } @@ -1131,7 +1133,7 @@ mod tests { for (row_id, component_desc, expected) in expectations { let expected = expected - .and_then(|expected| re_types_core::LoggableBatch::to_arrow2(expected).ok()); + .and_then(|expected| re_types_core::LoggableBatch::to_arrow(expected).ok()); eprintln!("{component_desc} @ {row_id}"); similar_asserts::assert_eq!(expected, chunk.cell(*row_id, component_desc)); } @@ -1162,7 +1164,7 @@ mod tests { for (row_id, component_desc, expected) in expectations { let expected = expected - .and_then(|expected| re_types_core::LoggableBatch::to_arrow2(expected).ok()); + .and_then(|expected| re_types_core::LoggableBatch::to_arrow(expected).ok()); eprintln!("{component_desc} @ {row_id}"); similar_asserts::assert_eq!(expected, chunk.cell(*row_id, component_desc)); } @@ -1258,7 +1260,7 @@ mod tests { for (row_id, component_name, expected) in expectations { let expected = expected - .and_then(|expected| re_types_core::LoggableBatch::to_arrow2(expected).ok()); + .and_then(|expected| re_types_core::LoggableBatch::to_arrow(expected).ok()); eprintln!("{component_name} @ {row_id}"); similar_asserts::assert_eq!(expected, chunk.cell(*row_id, component_name)); } @@ -1277,7 +1279,7 @@ mod tests { for (row_id, component_name, expected) in expectations { let expected = expected - .and_then(|expected| re_types_core::LoggableBatch::to_arrow2(expected).ok()); + .and_then(|expected| re_types_core::LoggableBatch::to_arrow(expected).ok()); eprintln!("{component_name} @ {row_id}"); similar_asserts::assert_eq!(expected, chunk.cell(*row_id, component_name)); } @@ -1404,7 +1406,7 @@ mod tests { for (row_id, component_name, expected) in expectations { let expected = expected - .and_then(|expected| re_types_core::LoggableBatch::to_arrow2(expected).ok()); + .and_then(|expected| re_types_core::LoggableBatch::to_arrow(expected).ok()); eprintln!("{component_name} @ {row_id}"); similar_asserts::assert_eq!(expected, chunk.cell(*row_id, component_name)); } @@ -1551,7 +1553,7 @@ mod tests { for (row_id, component_name, expected) in expectations { let expected = expected - .and_then(|expected| re_types_core::LoggableBatch::to_arrow2(expected).ok()); + .and_then(|expected| re_types_core::LoggableBatch::to_arrow(expected).ok()); eprintln!("{component_name} @ {row_id}"); similar_asserts::assert_eq!(expected, chunk.cell(*row_id, component_name)); } diff --git a/crates/store/re_chunk_store/Cargo.toml b/crates/store/re_chunk_store/Cargo.toml index eb9a6c598e3a..bb712e49da6a 100644 --- a/crates/store/re_chunk_store/Cargo.toml +++ b/crates/store/re_chunk_store/Cargo.toml @@ -43,14 +43,13 @@ re_types_core.workspace = true ahash.workspace = true anyhow.workspace = true arrow.workspace = true -arrow2 = { workspace = true, features = ["compute_concatenate", "serde_types"] } +arrow2 = { workspace = true, features = ["compute_concatenate"] } document-features.workspace = true indent.workspace = true itertools.workspace = true nohash-hasher.workspace = true once_cell.workspace = true parking_lot = { workspace = true, features = ["arc_lock"] } -serde_json.workspace = true thiserror.workspace = true web-time.workspace = true diff --git a/crates/store/re_chunk_store/src/dataframe.rs b/crates/store/re_chunk_store/src/dataframe.rs index 3ff35d366dca..d1b9bd183b94 100644 --- a/crates/store/re_chunk_store/src/dataframe.rs +++ b/crates/store/re_chunk_store/src/dataframe.rs @@ -1,13 +1,13 @@ //! All the APIs used specifically for `re_dataframe`. -use std::collections::{BTreeMap, BTreeSet}; -use std::ops::Deref; -use std::ops::DerefMut; +use std::{ + collections::{BTreeMap, BTreeSet}, + ops::{Deref, DerefMut}, +}; -use arrow::datatypes::Field as ArrowField; -use arrow2::{ +use arrow::{ array::ListArray as ArrowListArray, - datatypes::{DataType as Arrow2Datatype, Field as Arrow2Field}, + datatypes::{DataType as ArrowDatatype, Field as ArrowField}, }; use itertools::Itertools; @@ -44,7 +44,7 @@ impl ColumnDescriptor { } #[inline] - pub fn arrow2_datatype(&self) -> Arrow2Datatype { + pub fn arrow_datatype(&self) -> ArrowDatatype { match self { Self::Time(descr) => descr.datatype.clone(), Self::Component(descr) => descr.returned_datatype(), @@ -59,14 +59,6 @@ impl ColumnDescriptor { } } - #[inline] - pub fn to_arrow2_field(&self) -> Arrow2Field { - match self { - Self::Time(descr) => descr.to_arrow2_field(), - Self::Component(descr) => descr.to_arrow2_field(), - } - } - #[inline] pub fn short_name(&self) -> String { match self { @@ -91,7 +83,7 @@ pub struct TimeColumnDescriptor { pub timeline: Timeline, /// The Arrow datatype of the column. - pub datatype: Arrow2Datatype, + pub datatype: ArrowDatatype, } impl PartialOrd for TimeColumnDescriptor { @@ -120,7 +112,7 @@ impl TimeColumnDescriptor { // TODO(cmc): I picked a sequence here because I have to pick something. // It doesn't matter, only the name will remain in the Arrow schema anyhow. timeline: Timeline::new_sequence(name), - datatype: Arrow2Datatype::Null, + datatype: ArrowDatatype::Null, } } @@ -140,35 +132,25 @@ impl TimeColumnDescriptor { } #[inline] - pub fn datatype(&self) -> &Arrow2Datatype { + pub fn datatype(&self) -> &ArrowDatatype { &self.datatype } - fn metadata(&self) -> arrow2::datatypes::Metadata { - let Self { - timeline, - datatype: _, - } = self; + #[inline] + pub fn to_arrow_field(&self) -> ArrowField { + let Self { timeline, datatype } = self; - std::iter::once(Some(( + let nullable = true; // Time column must be nullable since static data doesn't have a time. + + let metadata = std::iter::once(Some(( "sorbet.index_name".to_owned(), timeline.name().to_string(), ))) .flatten() - .collect() - } + .collect(); - #[inline] - pub fn to_arrow_field(&self) -> ArrowField { - self.to_arrow2_field().into() - } - - #[inline] - pub fn to_arrow2_field(&self) -> Arrow2Field { - let Self { timeline, datatype } = self; - let nullable = true; // Time column must be nullable since static data doesn't have a time. - Arrow2Field::new(timeline.name().to_string(), datatype.clone(), nullable) - .with_metadata(self.metadata()) + ArrowField::new(timeline.name().to_string(), datatype.clone(), nullable) + .with_metadata(metadata) } } @@ -208,7 +190,7 @@ pub struct ComponentColumnDescriptor { /// This is the log-time datatype corresponding to how this data is encoded /// in a chunk. Currently this will always be an [`ArrowListArray`], but as /// we introduce mono-type optimization, this might be a native type instead. - pub store_datatype: Arrow2Datatype, + pub store_datatype: ArrowDatatype, /// Whether this column represents static data. pub is_static: bool, @@ -320,7 +302,7 @@ impl ComponentColumnDescriptor { &self.entity_path == entity_path && self.component_name.matches(component_name) } - fn metadata(&self) -> arrow2::datatypes::Metadata { + fn metadata(&self) -> std::collections::HashMap { let Self { entity_path, archetype_name, @@ -360,17 +342,12 @@ impl ComponentColumnDescriptor { } #[inline] - pub fn returned_datatype(&self) -> Arrow2Datatype { + pub fn returned_datatype(&self) -> ArrowDatatype { self.store_datatype.clone() } #[inline] pub fn to_arrow_field(&self) -> ArrowField { - self.to_arrow2_field().into() - } - - #[inline] - pub fn to_arrow2_field(&self) -> Arrow2Field { let entity_path = &self.entity_path; let descriptor = ComponentDescriptor { archetype_name: self.archetype_name, @@ -378,7 +355,7 @@ impl ComponentColumnDescriptor { component_name: self.component_name, }; - Arrow2Field::new( + ArrowField::new( // NOTE: Uncomment this to expose fully-qualified names in the Dataframe APIs! // I'm not doing that right now, to avoid breaking changes (and we need to talk about // what the syntax for these fully-qualified paths need to look like first). @@ -754,7 +731,7 @@ impl ChunkStore { let timelines = self.all_timelines_sorted().into_iter().map(|timeline| { ColumnDescriptor::Time(TimeColumnDescriptor { timeline, - datatype: timeline.datatype().into(), + datatype: timeline.datatype(), }) }); @@ -769,7 +746,7 @@ impl ChunkStore { .filter_map(|(entity_path, component_descr)| { let metadata = self.lookup_column_metadata(entity_path, &component_descr.component_name)?; - let datatype = self.lookup_datatype_arrow2(&component_descr.component_name)?; + let datatype = self.lookup_datatype(&component_descr.component_name)?; Some(((entity_path, component_descr), (metadata, datatype))) }) @@ -789,7 +766,9 @@ impl ChunkStore { // NOTE: The data is always a at least a list, whether it's latest-at or range. // It might be wrapped further in e.g. a dict, but at the very least // it's a list. - store_datatype: ArrowListArray::::default_datatype(datatype.clone()), + store_datatype: ArrowListArray::DATA_TYPE_CONSTRUCTOR( + ArrowField::new("item", datatype.clone(), true).into(), + ), is_static, is_indicator, is_tombstone, @@ -828,7 +807,7 @@ impl ChunkStore { TimeColumnDescriptor { timeline, - datatype: timeline.datatype().into(), + datatype: timeline.datatype(), } } @@ -879,16 +858,17 @@ impl ChunkStore { }); let datatype = self - .lookup_datatype_arrow2(&component_name) - .cloned() - .unwrap_or(Arrow2Datatype::Null); + .lookup_datatype(&component_name) + .unwrap_or(ArrowDatatype::Null); ComponentColumnDescriptor { entity_path: selector.entity_path.clone(), archetype_name: component_descr.and_then(|descr| descr.archetype_name), archetype_field_name: component_descr.and_then(|descr| descr.archetype_field_name), component_name, - store_datatype: ArrowListArray::::default_datatype(datatype.clone()), + store_datatype: ArrowListArray::DATA_TYPE_CONSTRUCTOR( + ArrowField::new("item", datatype, true).into(), + ), is_static, is_indicator, is_tombstone, diff --git a/crates/store/re_chunk_store/src/protobuf_conversions.rs b/crates/store/re_chunk_store/src/protobuf_conversions.rs index 020cc3523106..1cf1ec3cd25e 100644 --- a/crates/store/re_chunk_store/src/protobuf_conversions.rs +++ b/crates/store/re_chunk_store/src/protobuf_conversions.rs @@ -270,9 +270,7 @@ impl TryFrom for re_protos::common::v0::ColumnDescripto timeline: Some(re_protos::common::v0::Timeline { name: time_descriptor.timeline.name().to_string(), }), - datatype: serde_json::to_string(&time_descriptor.datatype).map_err( - |err| invalid_field!(Self, "time column descriptor", err), - )?, + datatype: time_descriptor.datatype.to_string(), // TODO(emilk): use arrow IPC instead }, ), ), @@ -289,10 +287,7 @@ impl TryFrom for re_protos::common::v0::ColumnDescripto .archetype_field_name .map(|afn| afn.to_string()), component_name: component_descriptor.component_name.to_string(), - datatype: serde_json::to_string(&component_descriptor.store_datatype) - .map_err(|err| { - invalid_field!(Self, "component column descriptor", err) - })?, + datatype: component_descriptor.store_datatype.to_string(), // TODO(emilk): use arrow IPC instead is_static: component_descriptor.is_static, is_tombstone: component_descriptor.is_tombstone, is_semantically_empty: component_descriptor.is_semantically_empty, @@ -325,7 +320,7 @@ impl TryFrom for crate::ColumnDescripto "timeline", ))? .into(), - datatype: serde_json::from_str(&time_descriptor.datatype).map_err(|err| { + datatype: time_descriptor.datatype.parse().map_err(|err| { invalid_field!( re_protos::common::v0::ColumnDescriptor, "time column descriptor", @@ -346,15 +341,13 @@ impl TryFrom for crate::ColumnDescripto archetype_name: component_descriptor.archetype_name.map(Into::into), archetype_field_name: component_descriptor.archetype_field_name.map(Into::into), component_name: component_descriptor.component_name.into(), - store_datatype: serde_json::from_str(&component_descriptor.datatype).map_err( - |err| { - invalid_field!( - re_protos::common::v0::ColumnDescriptor, - "component column descriptor", - err - ) - }, - )?, + store_datatype: component_descriptor.datatype.parse().map_err(|err| { + invalid_field!( + re_protos::common::v0::ColumnDescriptor, + "component column descriptor", + err + ) + })?, is_static: component_descriptor.is_static, is_tombstone: component_descriptor.is_tombstone, is_semantically_empty: component_descriptor.is_semantically_empty, @@ -447,8 +440,8 @@ mod tests { fn test_time_column_descriptor_conversion() { let time_descriptor = crate::TimeColumnDescriptor { timeline: crate::Timeline::log_time(), - datatype: arrow2::datatypes::DataType::Timestamp( - arrow2::datatypes::TimeUnit::Nanosecond, + datatype: arrow::datatypes::DataType::Timestamp( + arrow::datatypes::TimeUnit::Nanosecond, None, ), }; @@ -472,7 +465,7 @@ mod tests { archetype_name: Some("archetype".to_owned().into()), archetype_field_name: Some("field".to_owned().into()), component_name: re_chunk::ComponentName::new("component"), - store_datatype: arrow2::datatypes::DataType::Int64, + store_datatype: arrow::datatypes::DataType::Int64, is_static: true, is_tombstone: false, is_semantically_empty: false, diff --git a/crates/store/re_chunk_store/src/store.rs b/crates/store/re_chunk_store/src/store.rs index a5afbfa9f7a9..36d67a4a8702 100644 --- a/crates/store/re_chunk_store/src/store.rs +++ b/crates/store/re_chunk_store/src/store.rs @@ -646,15 +646,6 @@ impl ChunkStore { .map(|dt| dt.clone().into()) } - /// Lookup the _latest_ arrow [`Arrow2DataType`] used by a specific [`re_types_core::Component`]. - #[inline] - pub fn lookup_datatype_arrow2( - &self, - component_name: &ComponentName, - ) -> Option<&Arrow2DataType> { - self.type_registry.get(component_name) - } - /// Lookup the [`ColumnMetadata`] for a specific [`EntityPath`] and [`re_types_core::Component`]. pub fn lookup_column_metadata( &self, diff --git a/crates/store/re_dataframe/src/query.rs b/crates/store/re_dataframe/src/query.rs index cd302a51709f..6f0c4947f6c0 100644 --- a/crates/store/re_dataframe/src/query.rs +++ b/crates/store/re_dataframe/src/query.rs @@ -7,9 +7,12 @@ use std::{ }; use arrow::{ - array::RecordBatch as ArrowRecordBatch, buffer::ScalarBuffer as ArrowScalarBuffer, - datatypes::Fields as ArrowFields, datatypes::Schema as ArrowSchema, - datatypes::SchemaRef as ArrowSchemaRef, + array::{ArrayRef as ArrowArrayRef, RecordBatch as ArrowRecordBatch}, + buffer::ScalarBuffer as ArrowScalarBuffer, + datatypes::{ + DataType as ArrowDataType, Fields as ArrowFields, Schema as ArrowSchema, + SchemaRef as ArrowSchemaRef, + }, }; use arrow2::{ array::{ @@ -242,13 +245,10 @@ impl QueryHandle { if let Some(clear_chunks) = clear_chunks.get(&descr.entity_path) { chunks.extend(clear_chunks.iter().map(|chunk| { let child_datatype = match &descr.store_datatype { - arrow2::datatypes::DataType::List(field) - | arrow2::datatypes::DataType::LargeList(field) => { + ArrowDataType::List(field) | ArrowDataType::LargeList(field) => { field.data_type().clone() } - arrow2::datatypes::DataType::Dictionary(_, datatype, _) => { - (**datatype).clone() - } + ArrowDataType::Dictionary(_, datatype) => (**datatype).clone(), datatype => datatype.clone(), }; @@ -256,14 +256,14 @@ impl QueryHandle { // Only way this could fail is if the number of rows did not match. #[allow(clippy::unwrap_used)] chunk - .add_component_arrow2( + .add_component( re_types_core::ComponentDescriptor { component_name: descr.component_name, archetype_name: descr.archetype_name, archetype_field_name: descr.archetype_field_name, }, - re_arrow_util::arrow2_util::new_list_array_of_empties( - child_datatype, + re_arrow_util::arrow_util::new_list_array_of_empties( + &child_datatype, chunk.num_rows(), ), ) @@ -429,7 +429,7 @@ impl QueryHandle { component_name: ComponentName::from( selected_component_name.clone(), ), - store_datatype: arrow2::datatypes::DataType::Null, + store_datatype: ArrowDataType::Null, is_static: false, is_indicator: false, is_tombstone: false, @@ -794,39 +794,7 @@ impl QueryHandle { #[inline] pub fn next_row(&self) -> Option> { self.engine - .with(|store, cache| self._next_row_arrow2(store, cache)) - .map(|vec| vec.into_iter().map(|a| a.into()).collect()) - } - - /// Returns the next row's worth of data. - /// - /// The returned vector of Arrow arrays strictly follows the schema specified by [`Self::schema`]. - /// Columns that do not yield any data will still be present in the results, filled with null values. - /// - /// Each cell in the result corresponds to the latest _locally_ known value at that particular point in - /// the index, for each respective `ColumnDescriptor`. - /// See [`QueryExpression::sparse_fill_strategy`] to go beyond local resolution. - /// - /// Example: - /// ```ignore - /// while let Some(row) = query_handle.next_row() { - /// // … - /// } - /// ``` - /// - /// ## Pagination - /// - /// Use [`Self::seek_to_row`]: - /// ```ignore - /// query_handle.seek_to_row(42); - /// for row in query_handle.into_iter().take(len) { - /// // … - /// } - /// ``` - #[inline] - fn next_row_arrow2(&self) -> Option>> { - self.engine - .with(|store, cache| self._next_row_arrow2(store, cache)) + .with(|store, cache| self._next_row(store, cache)) } /// Asynchronously returns the next row's worth of data. @@ -845,15 +813,13 @@ impl QueryHandle { /// } /// ``` #[cfg(not(target_arch = "wasm32"))] - pub fn next_row_async_arrow2( - &self, - ) -> impl std::future::Future>>> + pub fn next_row_async(&self) -> impl std::future::Future>> where E: 'static + Send + Clone, { let res: Option> = self .engine - .try_with(|store, cache| self._next_row_arrow2(store, cache)); + .try_with(|store, cache| self._next_row(store, cache)); let engine = self.engine.clone(); std::future::poll_fn(move |cx| { @@ -883,11 +849,7 @@ impl QueryHandle { }) } - pub fn _next_row_arrow2( - &self, - store: &ChunkStore, - cache: &QueryCache, - ) -> Option>> { + pub fn _next_row(&self, store: &ChunkStore, cache: &QueryCache) -> Option> { re_tracing::profile_function!(); /// Temporary state used to resolve the streaming join for the current iteration. @@ -1240,10 +1202,8 @@ impl QueryHandle { .map(|(view_idx, column)| match column { ColumnDescriptor::Time(descr) => { max_value_per_index.get(&descr.timeline()).map_or_else( - || arrow2::array::new_null_array(column.arrow2_datatype(), 1), - |(_time, time_sliced)| { - descr.typ().make_arrow_array(time_sliced.clone()).into() - }, + || arrow::array::new_null_array(&column.arrow_datatype(), 1), + |(_time, time_sliced)| descr.typ().make_arrow_array(time_sliced.clone()), ) } @@ -1251,7 +1211,8 @@ impl QueryHandle { .get(*view_idx) .cloned() .flatten() - .unwrap_or_else(|| arrow2::array::new_null_array(column.arrow2_datatype(), 1)), + .map(|a| a.into()) + .unwrap_or_else(|| arrow::array::new_null_array(&column.arrow_datatype(), 1)), }) .collect_vec(); @@ -1278,28 +1239,27 @@ impl QueryHandle { where E: 'static + Send + Clone, { - let row = self.next_row_async_arrow2().await?; + let row = self.next_row_async().await?; // If we managed to get a row, then the state must be initialized already. #[allow(clippy::unwrap_used)] let schema = self.state.get().unwrap().arrow_schema.clone(); - // TODO(#3741): remove the collect - ArrowRecordBatch::try_new(schema, row.into_iter().map(|a| a.into()).collect()).ok() + ArrowRecordBatch::try_new(schema, row).ok() } } impl QueryHandle { /// Returns an iterator backed by [`Self::next_row`]. #[allow(clippy::should_implement_trait)] // we need an anonymous closure, this won't work - pub fn iter(&self) -> impl Iterator>> + '_ { - std::iter::from_fn(move || self.next_row_arrow2()) + pub fn iter(&self) -> impl Iterator> + '_ { + std::iter::from_fn(move || self.next_row()) } /// Returns an iterator backed by [`Self::next_row`]. #[allow(clippy::should_implement_trait)] // we need an anonymous closure, this won't work - pub fn into_iter(self) -> impl Iterator>> { - std::iter::from_fn(move || self.next_row_arrow2()) + pub fn into_iter(self) -> impl Iterator> { + std::iter::from_fn(move || self.next_row()) } /// Returns an iterator backed by [`Self::next_row_batch`]. diff --git a/crates/store/re_protos/proto/rerun/v0/common.proto b/crates/store/re_protos/proto/rerun/v0/common.proto index 3d6521e1ecf5..e435ae86b431 100644 --- a/crates/store/re_protos/proto/rerun/v0/common.proto +++ b/crates/store/re_protos/proto/rerun/v0/common.proto @@ -92,10 +92,10 @@ message Query { // Only rows where this column contains non-null data be kept in the final dataset. ComponentColumnSelector filtered_is_not_null = 9; - /// The specific _columns_ to sample from the final view contents. - /// The order of the samples will be respected in the final result. + // The specific _columns_ to sample from the final view contents. + // The order of the samples will be respected in the final result. /// - /// If unspecified, it means - everything. + // If unspecified, it means - everything. ColumnSelection column_selection = 10; // Specifies how null values should be filled in the returned dataframe. @@ -110,31 +110,37 @@ message ColumnDescriptor { } message TimeColumnDescriptor { - /// The timeline this column is associated with. + // The timeline this column is associated with. Timeline timeline = 1; - /// The Arrow datatype of the column. + // The Arrow datatype of the column. + /// + // Currently this is just the `Display` of the `arrow-rs` `DataType`. + // TODO(emilk): use arrow IPC instead. string datatype = 2; } -/// Describes a data/component column, such as `Position3D`. +// Describes a data/component column, such as `Position3D`. message ComponentColumnDescriptor { - /// The path of the entity. + // The path of the entity. EntityPath entity_path = 1; - /// Optional name of the `Archetype` associated with this data. + // Optional name of the `Archetype` associated with this data. optional string archetype_name = 2; - /// Optional name of the field within `Archetype` associated with this data. + // Optional name of the field within `Archetype` associated with this data. optional string archetype_field_name = 3; - /// Semantic name associated with this data. + // Semantic name associated with this data. string component_name = 4; - /// The Arrow datatype of the column. + // The Arrow datatype of the column. + /// + // Currently this is just the `Display` of the `arrow-rs` `DataType`. + // TODO(emilk): use arrow IPC instead. string datatype = 5; - /// Whether the column is a static column. + // Whether the column is a static column. bool is_static = 6; - /// Whether the column is a tombstone column. + // Whether the column is a tombstone column. bool is_tombstone = 7; - /// Whether the column is an indicator column. + // Whether the column is an indicator column. bool is_indicator = 8; - /// Whether the column is semantically empty. + // Whether the column is semantically empty. bool is_semantically_empty = 9; } diff --git a/crates/store/re_protos/proto/rerun/v0/log_msg.proto b/crates/store/re_protos/proto/rerun/v0/log_msg.proto index fef64bcc3dcb..607c946c718e 100644 --- a/crates/store/re_protos/proto/rerun/v0/log_msg.proto +++ b/crates/store/re_protos/proto/rerun/v0/log_msg.proto @@ -86,7 +86,7 @@ message StoreInfo { // Unique ID of the recording. rerun.common.v0.StoreId store_id = 2; - /// True if the recording is one of the official Rerun examples. + // True if the recording is one of the official Rerun examples. bool is_official_example = 3; // When the recording started. diff --git a/crates/store/re_protos/src/v0/rerun.common.v0.rs b/crates/store/re_protos/src/v0/rerun.common.v0.rs index eabb6cc3118e..00467a9af6f1 100644 --- a/crates/store/re_protos/src/v0/rerun.common.v0.rs +++ b/crates/store/re_protos/src/v0/rerun.common.v0.rs @@ -140,10 +140,10 @@ pub struct Query { /// Only rows where this column contains non-null data be kept in the final dataset. #[prost(message, optional, tag = "9")] pub filtered_is_not_null: ::core::option::Option, - /// / The specific _columns_ to sample from the final view contents. - /// / The order of the samples will be respected in the final result. + /// The specific _columns_ to sample from the final view contents. + /// The order of the samples will be respected in the final result. /// / - /// / If unspecified, it means - everything. + /// If unspecified, it means - everything. #[prost(message, optional, tag = "10")] pub column_selection: ::core::option::Option, /// Specifies how null values should be filled in the returned dataframe. @@ -187,10 +187,13 @@ impl ::prost::Name for ColumnDescriptor { } #[derive(Clone, PartialEq, ::prost::Message)] pub struct TimeColumnDescriptor { - /// / The timeline this column is associated with. + /// The timeline this column is associated with. #[prost(message, optional, tag = "1")] pub timeline: ::core::option::Option, - /// / The Arrow datatype of the column. + /// The Arrow datatype of the column. + /// / + /// Currently this is just the `Display` of the `arrow-rs` `DataType`. + /// TODO(emilk): use arrow IPC instead. #[prost(string, tag = "2")] pub datatype: ::prost::alloc::string::String, } @@ -204,34 +207,37 @@ impl ::prost::Name for TimeColumnDescriptor { "/rerun.common.v0.TimeColumnDescriptor".into() } } -/// / Describes a data/component column, such as `Position3D`. +/// Describes a data/component column, such as `Position3D`. #[derive(Clone, PartialEq, ::prost::Message)] pub struct ComponentColumnDescriptor { - /// / The path of the entity. + /// The path of the entity. #[prost(message, optional, tag = "1")] pub entity_path: ::core::option::Option, - /// / Optional name of the `Archetype` associated with this data. + /// Optional name of the `Archetype` associated with this data. #[prost(string, optional, tag = "2")] pub archetype_name: ::core::option::Option<::prost::alloc::string::String>, - /// / Optional name of the field within `Archetype` associated with this data. + /// Optional name of the field within `Archetype` associated with this data. #[prost(string, optional, tag = "3")] pub archetype_field_name: ::core::option::Option<::prost::alloc::string::String>, - /// / Semantic name associated with this data. + /// Semantic name associated with this data. #[prost(string, tag = "4")] pub component_name: ::prost::alloc::string::String, - /// / The Arrow datatype of the column. + /// The Arrow datatype of the column. + /// / + /// Currently this is just the `Display` of the `arrow-rs` `DataType`. + /// TODO(emilk): use arrow IPC instead. #[prost(string, tag = "5")] pub datatype: ::prost::alloc::string::String, - /// / Whether the column is a static column. + /// Whether the column is a static column. #[prost(bool, tag = "6")] pub is_static: bool, - /// / Whether the column is a tombstone column. + /// Whether the column is a tombstone column. #[prost(bool, tag = "7")] pub is_tombstone: bool, - /// / Whether the column is an indicator column. + /// Whether the column is an indicator column. #[prost(bool, tag = "8")] pub is_indicator: bool, - /// / Whether the column is semantically empty. + /// Whether the column is semantically empty. #[prost(bool, tag = "9")] pub is_semantically_empty: bool, } diff --git a/crates/store/re_protos/src/v0/rerun.log_msg.v0.rs b/crates/store/re_protos/src/v0/rerun.log_msg.v0.rs index 88dcae5534a3..c7df324f1cfc 100644 --- a/crates/store/re_protos/src/v0/rerun.log_msg.v0.rs +++ b/crates/store/re_protos/src/v0/rerun.log_msg.v0.rs @@ -114,7 +114,7 @@ pub struct StoreInfo { /// Unique ID of the recording. #[prost(message, optional, tag = "2")] pub store_id: ::core::option::Option, - /// / True if the recording is one of the official Rerun examples. + /// True if the recording is one of the official Rerun examples. #[prost(bool, tag = "3")] pub is_official_example: bool, /// When the recording started. diff --git a/crates/store/re_query/Cargo.toml b/crates/store/re_query/Cargo.toml index c41b0c74bb32..ef481d48214e 100644 --- a/crates/store/re_query/Cargo.toml +++ b/crates/store/re_query/Cargo.toml @@ -42,6 +42,7 @@ re_types_core.workspace = true # External dependencies: ahash.workspace = true anyhow.workspace = true +arrow.workspace = true arrow2.workspace = true backtrace.workspace = true indent.workspace = true diff --git a/crates/store/re_query/examples/latest_at.rs b/crates/store/re_query/examples/latest_at.rs index 749858f089d5..0991ac6b8884 100644 --- a/crates/store/re_query/examples/latest_at.rs +++ b/crates/store/re_query/examples/latest_at.rs @@ -1,10 +1,10 @@ use std::sync::Arc; use anyhow::Context; -use arrow2::array::PrimitiveArray as Arrow2PrimitiveArray; +use arrow::array::UInt32Array as ArrowUInt32Array; use itertools::Itertools; -use re_arrow_util::Arrow2ArrayDowncastRef as _; +use re_arrow_util::ArrowArrayDowncastRef as _; use re_chunk::{Chunk, RowId}; use re_chunk_store::{ChunkStore, ChunkStoreHandle, LatestAtQuery}; use re_log_types::example_components::{MyColor, MyLabel, MyPoint, MyPoints}; @@ -75,16 +75,12 @@ fn main() -> anyhow::Result<()> { // data directly: let colors = colors .context("missing")? - .component_batch_raw_arrow2(&MyColor::name()) + .component_batch_raw(&MyColor::name()) .context("invalid")?; let colors = colors - .downcast_array2_ref::>() + .downcast_array_ref::() .context("invalid")?; - let colors = colors - .values() - .as_slice() - .iter() - .map(|&color| MyColor(color)); + let colors = colors.values().iter().map(|&color| MyColor(color)); // And finally apply your instance-level joining logic, if any: let color_default_fn = || MyColor(0xFF00FFFF); diff --git a/crates/store/re_query/src/latest_at.rs b/crates/store/re_query/src/latest_at.rs index 922cd3a648b1..cba551d4d681 100644 --- a/crates/store/re_query/src/latest_at.rs +++ b/crates/store/re_query/src/latest_at.rs @@ -4,7 +4,7 @@ use std::{ sync::Arc, }; -use arrow2::array::Array as Arrow2Array; +use arrow::array::ArrayRef as ArrowArrayRef; use nohash_hasher::IntMap; use parking_lot::RwLock; @@ -321,17 +321,6 @@ impl LatestAtResults { .component_batch_raw(component_name) } - /// Returns the raw data for the specified component. - #[inline] - pub fn component_batch_raw_arrow2( - &self, - component_name: &ComponentName, - ) -> Option> { - self.components - .get(component_name) - .and_then(|unit| unit.component_batch_raw_arrow2(component_name)) - } - /// Returns the deserialized data for the specified component. /// /// Logs at the specified `log_level` if the data cannot be deserialized. @@ -372,7 +361,7 @@ impl LatestAtResults { log_level: re_log::Level, component_name: &ComponentName, instance_index: usize, - ) -> Option> { + ) -> Option { self.components.get(component_name).and_then(|unit| { self.ok_or_log_err( log_level, @@ -390,7 +379,7 @@ impl LatestAtResults { &self, component_name: &ComponentName, instance_index: usize, - ) -> Option> { + ) -> Option { self.component_instance_raw_with_log_level( re_log::Level::Error, component_name, @@ -404,7 +393,7 @@ impl LatestAtResults { &self, component_name: &ComponentName, instance_index: usize, - ) -> Option> { + ) -> Option { self.components.get(component_name).and_then(|unit| { unit.component_instance_raw(component_name, instance_index)? .ok() @@ -458,7 +447,7 @@ impl LatestAtResults { &self, log_level: re_log::Level, component_name: &ComponentName, - ) -> Option> { + ) -> Option { self.components.get(component_name).and_then(|unit| { self.ok_or_log_err( log_level, @@ -472,10 +461,7 @@ impl LatestAtResults { /// /// Returns an error if the underlying batch is not of unit length. #[inline] - pub fn component_mono_raw( - &self, - component_name: &ComponentName, - ) -> Option> { + pub fn component_mono_raw(&self, component_name: &ComponentName) -> Option { self.component_mono_raw_with_log_level(re_log::Level::Error, component_name) } @@ -486,7 +472,7 @@ impl LatestAtResults { pub fn component_mono_raw_quiet( &self, component_name: &ComponentName, - ) -> Option> { + ) -> Option { self.components .get(component_name) .and_then(|unit| unit.component_mono_raw(component_name)?.ok()) diff --git a/rerun_py/Cargo.toml b/rerun_py/Cargo.toml index 646e2b86b1d3..35c728da2a64 100644 --- a/rerun_py/Cargo.toml +++ b/rerun_py/Cargo.toml @@ -75,7 +75,6 @@ re_ws_comms = { workspace = true, optional = true } arrow = { workspace = true, features = ["pyarrow"] } -arrow2 = { workspace = true, features = ["io_ipc", "io_print", "arrow"] } crossbeam.workspace = true document-features.workspace = true itertools.workspace = true diff --git a/rerun_py/src/arrow.rs b/rerun_py/src/arrow.rs index 16dc761d3066..ef690e40db95 100644 --- a/rerun_py/src/arrow.rs +++ b/rerun_py/src/arrow.rs @@ -3,21 +3,21 @@ use std::borrow::Cow; use arrow::{ - array::{make_array, ArrayData, ArrayRef as ArrowArrayRef}, + array::{ + make_array, ArrayData as ArrowArrayData, ArrayRef as ArrowArrayRef, + ListArray as ArrowListArray, + }, + buffer::OffsetBuffer as ArrowOffsetBuffer, + datatypes::Field as ArrowField, pyarrow::PyArrowType, }; -use arrow2::{ - array::{Array, ListArray}, - datatypes::Field, - offset::Offsets, -}; use pyo3::{ exceptions::PyRuntimeError, types::{PyAnyMethods, PyDict, PyDictMethods, PyString}, Bound, PyAny, PyResult, }; -use re_arrow_util::Arrow2ArrayDowncastRef as _; +use re_arrow_util::ArrowArrayDowncastRef as _; use re_chunk::{Chunk, ChunkError, ChunkId, PendingRow, RowId, TimeColumn, TransportChunk}; use re_log_types::TimePoint; use re_sdk::{external::nohash_hasher::IntMap, ComponentDescriptor, EntityPath, Timeline}; @@ -51,29 +51,26 @@ pub fn descriptor_to_rust(component_descr: &Bound<'_, PyAny>) -> PyResult, component_descr: &ComponentDescriptor, -) -> PyResult<(Box, Field)> { - let py_array: PyArrowType = arrow_array.extract()?; - let arr1_array = make_array(py_array.0); - - let data = arr1_array.to_data(); - let arr2_array = arrow2::array::from_data(&data); +) -> PyResult<(ArrowArrayRef, ArrowField)> { + let py_array: PyArrowType = arrow_array.extract()?; + let array = make_array(py_array.0); - let datatype = arr2_array.data_type().to_logical_type().clone(); + let datatype = array.data_type(); let metadata = TransportChunk::field_metadata_component_descriptor(component_descr); - let field = Field::new( + let field = ArrowField::new( component_descr.component_name.to_string(), datatype.clone(), true, ) - .with_metadata(metadata.into_iter().collect()); // TODO(#3741) + .with_metadata(metadata); - Ok((arr2_array, field)) + Ok((array, field)) } /// Build a [`PendingRow`] given a '**kwargs'-style dictionary of component arrays. @@ -90,7 +87,7 @@ pub fn build_row_from_components( let component_descr = descriptor_to_rust(&component_descr)?; let (list_array, _field) = array_to_rust(&array, &component_descr)?; - components.insert(component_descr, list_array.into()); + components.insert(component_descr, list_array); } Ok(PendingRow { @@ -110,7 +107,7 @@ pub fn build_chunk_from_components( let chunk_id = ChunkId::new(); // Extract the timeline data - let (arrays, fields): (Vec>, Vec) = itertools::process_results( + let (arrays, fields): (Vec, Vec) = itertools::process_results( timelines.iter().map(|(name, array)| { let py_name = name.downcast::()?; let name: std::borrow::Cow<'_, str> = py_name.extract()?; @@ -126,18 +123,18 @@ pub fn build_chunk_from_components( let timeline_data = TimeColumn::read_array(&ArrowArrayRef::from(array)).map_err(|err| { ChunkError::Malformed { - reason: format!("Invalid timeline {}: {err}", field.name), + reason: format!("Invalid timeline {}: {err}", field.name()), } })?; let timeline = match field.data_type() { - arrow2::datatypes::DataType::Int64 => { - Ok(Timeline::new_sequence(field.name.clone())) + arrow::datatypes::DataType::Int64 => { + Ok(Timeline::new_sequence(field.name().clone())) } - arrow2::datatypes::DataType::Timestamp(_, _) => { - Ok(Timeline::new_temporal(field.name.clone())) + arrow::datatypes::DataType::Timestamp(_, _) => { + Ok(Timeline::new_temporal(field.name().clone())) } _ => Err(ChunkError::Malformed { - reason: format!("Invalid data_type for timeline: {}", field.name), + reason: format!("Invalid data_type for timeline: {}", field.name()), }), }?; Ok((timeline, timeline_data)) @@ -151,7 +148,7 @@ pub fn build_chunk_from_components( .collect(); // Extract the component data - let (arrays, fields): (Vec>, Vec) = itertools::process_results( + let (arrays, fields): (Vec, Vec) = itertools::process_results( components_per_descr.iter().map(|(component_descr, array)| { array_to_rust(&array, &descriptor_to_rust(&component_descr)?) }), @@ -162,22 +159,20 @@ pub fn build_chunk_from_components( .into_iter() .zip(fields) .map(|(value, field)| { - let batch = if let Some(batch) = value.downcast_array2_ref::>() { + let batch = if let Some(batch) = value.downcast_array_ref::() { batch.clone() } else { - let offsets = Offsets::try_from_lengths(std::iter::repeat(1).take(value.len())) - .map_err(|err| ChunkError::Malformed { - reason: format!("Failed to create offsets: {err}"), - })?; - let data_type = ListArray::::default_datatype(value.data_type().clone()); - ListArray::::try_new(data_type, offsets.into(), value, None).map_err( - |err| ChunkError::Malformed { + let offsets = + ArrowOffsetBuffer::from_lengths(std::iter::repeat(1).take(value.len())); + let field = ArrowField::new("item", value.data_type().clone(), true).into(); + ArrowListArray::try_new(field, offsets, value, None).map_err(|err| { + ChunkError::Malformed { reason: format!("Failed to wrap in List array: {err}"), - }, - )? + } + })? }; - Ok((ComponentDescriptor::new(field.name), batch)) + Ok((ComponentDescriptor::new(field.name().clone()), batch)) }) .collect(); diff --git a/rerun_py/src/python_bridge.rs b/rerun_py/src/python_bridge.rs index a0b4a97a1674..8298c2f5108b 100644 --- a/rerun_py/src/python_bridge.rs +++ b/rerun_py/src/python_bridge.rs @@ -1136,9 +1136,9 @@ fn log_arrow_msg( /// ------ /// entity_path: `str` /// The entity path to log the chunk to. -/// timelines: `Dict[str, Arrow2PrimitiveArray]` +/// timelines: `Dict[str, arrow::Int64Array]` /// A dictionary mapping timeline names to their values. -/// components: `Dict[str, ArrowListArray]` +/// components: `Dict[str, arrow::ListArray]` /// A dictionary mapping component names to their values. #[pyfunction] #[pyo3(signature = ( diff --git a/rerun_py/src/video.rs b/rerun_py/src/video.rs index 0ada08d02c29..5a5c0e39222b 100644 --- a/rerun_py/src/video.rs +++ b/rerun_py/src/video.rs @@ -2,7 +2,7 @@ use pyo3::{exceptions::PyRuntimeError, pyfunction, Bound, PyAny, PyResult}; -use re_arrow_util::Arrow2ArrayDowncastRef as _; +use re_arrow_util::ArrowArrayDowncastRef as _; use re_sdk::ComponentDescriptor; use re_video::VideoLoadError; @@ -28,8 +28,8 @@ pub fn asset_video_read_frame_timestamps_ns( let video_bytes_arrow_array = array_to_rust(video_bytes_arrow_array, &component_descr)?.0; let video_bytes_arrow_uint8_array = video_bytes_arrow_array - .downcast_array2_ref::>() - .and_then(|arr| arr.values().downcast_array2_ref::()) + .downcast_array_ref::() + .and_then(|arr| arr.values().downcast_array_ref::()) .ok_or_else(|| { PyRuntimeError::new_err(format!( "Expected arrow array to be a list with a single uint8 array, instead it has the datatype {:?}", @@ -37,7 +37,7 @@ pub fn asset_video_read_frame_timestamps_ns( )) })?; - let video_bytes = video_bytes_arrow_uint8_array.values().as_slice(); + let video_bytes = video_bytes_arrow_uint8_array.values().as_ref(); let Some(media_type) = media_type.or_else(|| infer::Infer::new().get(video_bytes).map(|v| v.mime_type())) From 828e317c51cb887d4bee25d3155d3314fba2572e Mon Sep 17 00:00:00 2001 From: Zeljko Mihaljcic <7150613+zehiko@users.noreply.github.com> Date: Fri, 17 Jan 2025 13:30:34 +0100 Subject: [PATCH 56/57] define Catalog fields name in the protobuf spec crate and use them in the catalog view (#8710) This fixes the broken catalog view, regression was caused by recent renaming of fields on the SN side. Also there was 1 tiny change related to arrow migration (representation of Timestamp array) that needed to be changed as well. --- crates/store/re_grpc_client/src/lib.rs | 25 ++++++++++++++++--------- crates/store/re_protos/src/lib.rs | 12 ++++++++++++ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/crates/store/re_grpc_client/src/lib.rs b/crates/store/re_grpc_client/src/lib.rs index 487d27098508..be5fa4ba2f99 100644 --- a/crates/store/re_grpc_client/src/lib.rs +++ b/crates/store/re_grpc_client/src/lib.rs @@ -22,7 +22,8 @@ use re_protos::{ common::v0::RecordingId, remote_store::v0::{ storage_node_client::StorageNodeClient, CatalogFilter, FetchRecordingRequest, - QueryCatalogRequest, + QueryCatalogRequest, CATALOG_APP_ID_FIELD_NAME, CATALOG_ID_FIELD_NAME, + CATALOG_START_TIME_FIELD_NAME, }, }; use re_types::{ @@ -283,27 +284,33 @@ pub fn store_info_from_catalog_chunk( let (_field, data) = tc .components() - .find(|(f, _)| f.name() == "application_id") + .find(|(f, _)| f.name() == CATALOG_APP_ID_FIELD_NAME) .ok_or(StreamError::ChunkError(re_chunk::ChunkError::Malformed { - reason: "no application_id field found".to_owned(), + reason: "no {CATALOG_APP_ID_FIELD_NAME} field found".to_owned(), }))?; let app_id = data .downcast_array_ref::() .ok_or(StreamError::ChunkError(re_chunk::ChunkError::Malformed { - reason: format!("application_id must be a utf8 array: {:?}", tc.schema_ref()), + reason: format!( + "{CATALOG_APP_ID_FIELD_NAME} must be a utf8 array: {:?}", + tc.schema_ref() + ), }))? .value(0); let (_field, data) = tc .components() - .find(|(f, _)| f.name() == "start_time") + .find(|(f, _)| f.name() == CATALOG_START_TIME_FIELD_NAME) .ok_or(StreamError::ChunkError(re_chunk::ChunkError::Malformed { - reason: "no start_time field found".to_owned(), + reason: "no {CATALOG_START_TIME_FIELD_NAME}} field found".to_owned(), }))?; let start_time = data - .downcast_array_ref::() + .downcast_array_ref::() .ok_or(StreamError::ChunkError(re_chunk::ChunkError::Malformed { - reason: format!("start_time must be an int64 array: {:?}", tc.schema_ref()), + reason: format!( + "{CATALOG_START_TIME_FIELD_NAME} must be a Timestamp array: {:?}", + tc.schema_ref() + ), }))? .value(0); @@ -485,7 +492,7 @@ async fn stream_catalog_async( )))?; let recording_uri_arrays: Vec = chunk - .iter_slices::("id".into()) + .iter_slices::(CATALOG_ID_FIELD_NAME.into()) .map(|id| { let rec_id = &id[0]; // each component batch is of length 1 i.e. single 'id' value diff --git a/crates/store/re_protos/src/lib.rs b/crates/store/re_protos/src/lib.rs index e41036697752..df3a13b66375 100644 --- a/crates/store/re_protos/src/lib.rs +++ b/crates/store/re_protos/src/lib.rs @@ -48,8 +48,20 @@ pub mod log_msg { /// Generated types for the remote store gRPC service API v0. pub mod remote_store { + pub mod v0 { pub use crate::v0::rerun_remote_store_v0::*; + + /// Recording catalog mandatory field names. All mandatory metadata fields are prefixed + /// with "rerun_" to avoid conflicts with user-defined fields. + pub const CATALOG_ID_FIELD_NAME: &str = "rerun_recording_id"; + pub const CATALOG_APP_ID_FIELD_NAME: &str = "rerun_application_id"; + pub const CATALOG_START_TIME_FIELD_NAME: &str = "rerun_start_time"; + pub const CATALOG_DESCRIPTION_FIELD_NAME: &str = "rerun_description"; + pub const CATALOG_RECORDING_TYPE_FIELD_NAME: &str = "rerun_recording_type"; + pub const CATALOG_STORAGE_URL_FIELD_NAME: &str = "rerun_storage_url"; + pub const CATALOG_REGISTRATION_TIME_FIELD_NAME: &str = "rerun_registration_time"; + pub const CATALOG_ROW_ID_FIELD_NAME: &str = "rerun_row_id"; } } From 18ce378eac0502a394e5351b1b2597c1c565f8b6 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Fri, 17 Jan 2025 18:38:17 +0100 Subject: [PATCH 57/57] Port over most Rust types to use eager serialization (#8703) --- .../re_data_loader/src/loader_archetype.rs | 4 +- crates/store/re_entity_db/tests/clear.rs | 21 +- .../re_log_types/src/example_components.rs | 53 ++- crates/store/re_log_types/src/lib.rs | 45 ++ .../rerun/archetypes/annotation_context.fbs | 1 + .../definitions/rerun/archetypes/arrows2d.fbs | 1 + .../definitions/rerun/archetypes/arrows3d.fbs | 1 + .../definitions/rerun/archetypes/asset3d.fbs | 1 + .../rerun/archetypes/asset_video.fbs | 1 + .../rerun/archetypes/bar_chart.fbs | 1 + .../definitions/rerun/archetypes/boxes2d.fbs | 1 + .../definitions/rerun/archetypes/boxes3d.fbs | 1 + .../rerun/archetypes/capsules3d.fbs | 1 + .../definitions/rerun/archetypes/clear.fbs | 3 +- .../rerun/archetypes/depth_image.fbs | 1 + .../rerun/archetypes/ellipsoids3d.fbs | 1 + .../rerun/archetypes/encoded_image.fbs | 1 + .../rerun/archetypes/geo_line_strings.fbs | 1 + .../rerun/archetypes/geo_points.fbs | 1 + .../rerun/archetypes/graph_edges.fbs | 3 +- .../rerun/archetypes/graph_nodes.fbs | 1 + .../definitions/rerun/archetypes/image.fbs | 1 + .../rerun/archetypes/instance_poses3d.fbs | 1 + .../definitions/rerun/archetypes/mesh3d.fbs | 1 + .../definitions/rerun/archetypes/pinhole.fbs | 1 + .../definitions/rerun/archetypes/points2d.fbs | 1 + .../definitions/rerun/archetypes/scalar.fbs | 1 + .../rerun/archetypes/segmentation_image.fbs | 1 + .../rerun/archetypes/series_line.fbs | 1 + .../rerun/archetypes/series_point.fbs | 1 + .../definitions/rerun/archetypes/tensor.fbs | 1 + .../rerun/archetypes/text_document.fbs | 3 +- .../definitions/rerun/archetypes/text_log.fbs | 3 +- .../archetypes/video_frame_reference.fbs | 1 + .../rerun/archetypes/view_coordinates.fbs | 1 + .../store/re_types/src/archetypes/arrows2d.rs | 299 ++++++-------- .../store/re_types/src/archetypes/arrows3d.rs | 267 +++++------- .../re_types/src/archetypes/bar_chart.rs | 94 ++--- .../re_types/src/archetypes/capsules3d.rs | 357 +++++++--------- .../re_types/src/archetypes/capsules3d_ext.rs | 1 + .../re_types/src/archetypes/depth_image.rs | 263 +++++------- .../src/archetypes/depth_image_ext.rs | 20 +- .../re_types/src/archetypes/ellipsoids3d.rs | 384 +++++++----------- .../re_types/src/archetypes/encoded_image.rs | 159 ++++---- .../src/archetypes/encoded_image_ext.rs | 18 +- .../src/archetypes/geo_line_strings.rs | 135 +++--- .../re_types/src/archetypes/geo_points.rs | 170 ++++---- .../re_types/src/archetypes/graph_edges.rs | 99 ++--- .../src/archetypes/graph_edges_ext.rs | 10 +- .../re_types/src/archetypes/graph_nodes.rs | 234 +++++------ .../src/archetypes/instance_poses3d.rs | 207 ++++------ .../store/re_types/src/archetypes/points2d.rs | 304 ++++++-------- .../store/re_types/src/archetypes/scalar.rs | 72 ++-- .../src/archetypes/segmentation_image.rs | 166 ++++---- .../src/archetypes/segmentation_image_ext.rs | 7 +- .../re_types/src/archetypes/series_line.rs | 148 +++---- .../re_types/src/archetypes/series_point.rs | 147 +++---- .../re_types/src/archetypes/text_document.rs | 96 +++-- .../src/archetypes/text_document_ext.rs | 12 +- .../store/re_types/src/archetypes/text_log.rs | 125 +++--- .../src/archetypes/video_frame_reference.rs | 111 ++--- crates/store/re_types/tests/types/arrows3d.rs | 46 ++- crates/store/re_types/tests/types/clear.rs | 12 +- .../store/re_types/tests/types/depth_image.rs | 22 +- crates/store/re_types/tests/types/points2d.rs | 52 ++- .../tests/types/segmentation_image.rs | 17 +- .../re_types/tests/types/text_document.rs | 11 +- .../re_types_core/src/archetypes/clear.rs | 76 ++-- crates/store/re_types_core/src/lib.rs | 3 +- crates/viewer/re_data_ui/src/instance_path.rs | 6 +- crates/viewer/re_view_spatial/src/lib.rs | 3 +- 71 files changed, 1928 insertions(+), 2387 deletions(-) diff --git a/crates/store/re_data_loader/src/loader_archetype.rs b/crates/store/re_data_loader/src/loader_archetype.rs index 3e830c8ab776..bb302d5865d6 100644 --- a/crates/store/re_data_loader/src/loader_archetype.rs +++ b/crates/store/re_data_loader/src/loader_archetype.rs @@ -3,7 +3,7 @@ use re_log_types::{EntityPath, TimeInt, TimePoint}; use re_types::archetypes::{AssetVideo, VideoFrameReference}; use re_types::components::VideoTimestamp; use re_types::Archetype; -use re_types::{components::MediaType, ComponentBatch}; +use re_types::ComponentBatch; use arrow2::Either; @@ -162,7 +162,7 @@ fn load_image( let mut arch = re_types::archetypes::EncodedImage::from_file_contents(contents); if let Ok(format) = image::ImageFormat::from_path(filepath) { - arch.media_type = Some(MediaType::from(format.to_mime_type())); + arch = arch.with_media_type(format.to_mime_type()); } Chunk::builder(entity_path) diff --git a/crates/store/re_entity_db/tests/clear.rs b/crates/store/re_entity_db/tests/clear.rs index dbbb4a78927b..6b03995c0a3b 100644 --- a/crates/store/re_entity_db/tests/clear.rs +++ b/crates/store/re_entity_db/tests/clear.rs @@ -10,6 +10,7 @@ use re_log_types::{ example_components::{MyColor, MyIndex, MyPoint}, EntityPath, StoreId, TimeInt, TimePoint, Timeline, }; +use re_types::ComponentBatch; use re_types_core::{archetypes::Clear, components::ClearIsRecursive, AsComponents}; // --- @@ -137,7 +138,10 @@ fn clears() -> anyhow::Result<()> { let (_, _, got_clear) = query_latest_component::(&db, &entity_path_parent, &query) .unwrap(); - similar_asserts::assert_eq!(clear.is_recursive, got_clear); + similar_asserts::assert_eq!( + clear.is_recursive.map(|batch| batch.array), + got_clear.serialized().map(|batch| batch.array) + ); // child1 assert!(query_latest_component::(&db, &entity_path_child1, &query).is_some()); @@ -171,7 +175,10 @@ fn clears() -> anyhow::Result<()> { let (_, _, got_clear) = query_latest_component::(&db, &entity_path_parent, &query) .unwrap(); - similar_asserts::assert_eq!(clear.is_recursive, got_clear); + similar_asserts::assert_eq!( + clear.is_recursive.map(|batch| batch.array), + got_clear.serialized().map(|batch| batch.array) + ); // child1 assert!(query_latest_component::(&db, &entity_path_child1, &query).is_none()); @@ -356,7 +363,10 @@ fn clears_respect_index_order() -> anyhow::Result<()> { // the `Clear` component itself doesn't get cleared! let (_, _, got_clear) = query_latest_component::(&db, &entity_path, &query).unwrap(); - similar_asserts::assert_eq!(clear.is_recursive, got_clear); + similar_asserts::assert_eq!( + clear.is_recursive.map(|batch| batch.array), + got_clear.serialized().map(|batch| batch.array) + ); } let clear = Clear::recursive(); @@ -378,7 +388,10 @@ fn clears_respect_index_order() -> anyhow::Result<()> { // the `Clear` component itself doesn't get cleared! let (_, _, got_clear) = query_latest_component::(&db, &entity_path, &query).unwrap(); - similar_asserts::assert_eq!(clear.is_recursive, got_clear); + similar_asserts::assert_eq!( + clear.is_recursive.map(|batch| batch.array), + got_clear.serialized().map(|batch| batch.array) + ); } Ok(()) diff --git a/crates/store/re_log_types/src/example_components.rs b/crates/store/re_log_types/src/example_components.rs index 06e1da14a4c8..a0566ae99b49 100644 --- a/crates/store/re_log_types/src/example_components.rs +++ b/crates/store/re_log_types/src/example_components.rs @@ -4,17 +4,66 @@ use std::sync::Arc; use re_arrow_util::ArrowArrayDowncastRef as _; use re_byte_size::SizeBytes; -use re_types_core::{Component, ComponentDescriptor, DeserializationError, Loggable}; +use re_types_core::{ + Component, ComponentDescriptor, DeserializationError, Loggable, SerializedComponentBatch, +}; // ---------------------------------------------------------------------------- #[derive(Debug)] -pub struct MyPoints; +pub struct MyPoints { + pub points: Option, + pub colors: Option, + pub labels: Option, +} impl MyPoints { pub const NUM_COMPONENTS: usize = 5; } +impl MyPoints { + pub fn descriptor_points() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("example.MyPoints".into()), + archetype_field_name: Some("points".into()), + component_name: MyPoint::name(), + } + } + + pub fn descriptor_colors() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("example.MyPoints".into()), + archetype_field_name: Some("colors".into()), + component_name: MyColor::name(), + } + } + + pub fn descriptor_labels() -> ComponentDescriptor { + ComponentDescriptor { + archetype_name: Some("example.MyPoints".into()), + archetype_field_name: Some("labels".into()), + component_name: MyLabel::name(), + } + } + + pub fn clear_fields() -> Self { + Self { + points: Some(SerializedComponentBatch::new( + MyPoint::arrow_empty(), + Self::descriptor_points(), + )), + colors: Some(SerializedComponentBatch::new( + MyColor::arrow_empty(), + Self::descriptor_colors(), + )), + labels: Some(SerializedComponentBatch::new( + MyLabel::arrow_empty(), + Self::descriptor_labels(), + )), + } + } +} + impl re_types_core::Archetype for MyPoints { type Indicator = re_types_core::GenericIndicatorComponent; diff --git a/crates/store/re_log_types/src/lib.rs b/crates/store/re_log_types/src/lib.rs index cb4509f9594b..8d8e98199194 100644 --- a/crates/store/re_log_types/src/lib.rs +++ b/crates/store/re_log_types/src/lib.rs @@ -808,6 +808,51 @@ pub fn strip_arrow_extension_types_from_batch(batch: &mut ArrowRecordBatch) { } } +// ---------------------------------------------------------------------------- + +/// Runtime asserts that an archetype has the given components. +/// +/// In particular, this is useful to statically check that an archetype +/// has a specific component. +/// +/// ``` +/// # #[macro_use] extern crate re_log_types; +/// # use re_log_types::example_components::*; +/// debug_assert_archetype_has_components!(MyPoints, colors: MyColor); +/// ``` +/// +/// This will panic because the type is wrong: +/// +/// ```should_panic +/// # #[macro_use] extern crate re_log_types; +/// # use re_log_types::example_components::*; +/// debug_assert_archetype_has_components!(MyPoints, colors: MyPoint); +/// ``` +/// +/// This will fail to compile because the field is missing: +/// +/// ```compile_fail +/// # #[macro_use] extern crate re_log_types; +/// # use re_log_types::example_components::*; +/// debug_assert_archetype_has_components!(MyPoints, colours: MyColor); +/// ``` +/// +#[macro_export] +macro_rules! debug_assert_archetype_has_components { + ($arch:ty, $($field:ident: $field_typ:ty),+ $(,)?) => { + #[cfg(debug_assertions)] + { + use re_log_types::external::re_types_core::{Component as _}; + let archetype = <$arch>::clear_fields(); + $( + assert_eq!(archetype.$field.map(|batch| batch.descriptor.component_name), Some(<$field_typ>::name())); + )+ + } + }; +} + +// ---------------------------------------------------------------------------- + #[cfg(test)] mod tests { use super::*; diff --git a/crates/store/re_types/definitions/rerun/archetypes/annotation_context.fbs b/crates/store/re_types/definitions/rerun/archetypes/annotation_context.fbs index 069859ac3617..bd7442723f31 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/annotation_context.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/annotation_context.fbs @@ -15,6 +15,7 @@ namespace rerun.archetypes; /// \example archetypes/annotation_context_segmentation title="Segmentation" image="https://static.rerun.io/annotation_context_segmentation/6c9e88fc9d44a08031cadd444c2e58a985cc1208/1200w.png"" /// \example archetypes/annotation_context_connections !api title="Connections" image="https://static.rerun.io/annotation_context_connections/4a8422bc154699c5334f574ff01b55c5cd1748e3/1200w.png" table AnnotationContext ( + // TODO(#7245): "attr.rust.archetype_eager", "attr.rust.derive": "Eq, PartialEq", "attr.docs.view_types": "Spatial2DView, Spatial3DView" ) { diff --git a/crates/store/re_types/definitions/rerun/archetypes/arrows2d.fbs b/crates/store/re_types/definitions/rerun/archetypes/arrows2d.fbs index 20f87c0e6a8b..56854ae5b6a4 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/arrows2d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/arrows2d.fbs @@ -7,6 +7,7 @@ namespace rerun.archetypes; /// /// \example archetypes/arrows2d_simple title="Simple batch of 2D arrows" image="https://static.rerun.io/arrow2d_simple/59f044ccc03f7bc66ee802288f75706618b29a6e/1200w.png" table Arrows2D ( + "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq", "attr.rust.new_pub_crate", "attr.cpp.no_field_ctors", diff --git a/crates/store/re_types/definitions/rerun/archetypes/arrows3d.fbs b/crates/store/re_types/definitions/rerun/archetypes/arrows3d.fbs index 24b3ea1e336e..b07c94130e93 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/arrows3d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/arrows3d.fbs @@ -6,6 +6,7 @@ namespace rerun.archetypes; /// /// \example archetypes/arrows3d_simple title="Simple batch of 3D arrows" image="https://static.rerun.io/arrow3d_simple/55e2f794a520bbf7527d7b828b0264732146c5d0/1200w.png" table Arrows3D ( + "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq", "attr.rust.new_pub_crate", "attr.cpp.no_field_ctors", diff --git a/crates/store/re_types/definitions/rerun/archetypes/asset3d.fbs b/crates/store/re_types/definitions/rerun/archetypes/asset3d.fbs index b0625fbf2ff6..d230ad0fb42a 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/asset3d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/asset3d.fbs @@ -11,6 +11,7 @@ namespace rerun.archetypes; /// /// \example archetypes/asset3d_simple title="Simple 3D asset" image="https://static.rerun.io/asset3d_simple/af238578188d3fd0de3e330212120e2842a8ddb2/1200w.png" table Asset3D ( + // TODO(#7245): "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq, Eq", "attr.docs.category": "Spatial 3D", "attr.docs.view_types": "Spatial3DView, Spatial2DView: if logged above active projection" diff --git a/crates/store/re_types/definitions/rerun/archetypes/asset_video.fbs b/crates/store/re_types/definitions/rerun/archetypes/asset_video.fbs index bf4fcbb7fcb3..2d5209ac1c45 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/asset_video.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/asset_video.fbs @@ -12,6 +12,7 @@ namespace rerun.archetypes; /// \example archetypes/video_auto_frames title="Video with automatically determined frames" image="https://static.rerun.io/video_manual_frames/320a44e1e06b8b3a3161ecbbeae3e04d1ccb9589/1200w.png" /// \example archetypes/video_manual_frames title="Demonstrates manual use of video frame references" image="https://static.rerun.io/video_manual_frames/9f41c00f84a98cc3f26875fba7c1d2fa2bad7151/1200w.png" table AssetVideo ( + // TODO(#7245): "attr.rust.archetype_eager", "attr.docs.category": "Video", "attr.docs.view_types": "Spatial2DView, Spatial3DView: if logged under a projection" ) { diff --git a/crates/store/re_types/definitions/rerun/archetypes/bar_chart.fbs b/crates/store/re_types/definitions/rerun/archetypes/bar_chart.fbs index 77037d719cea..60dcc0775d9b 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/bar_chart.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/bar_chart.fbs @@ -8,6 +8,7 @@ namespace rerun.archetypes; /// /// \example archetypes/bar_chart title="Simple bar chart" image="https://static.rerun.io/barchart_simple/cf6014b18265edfcaa562c06526c0716b296b193/1200w.png" table BarChart ( + "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq", "attr.docs.category": "Plotting", "attr.docs.view_types": "BarChartView" diff --git a/crates/store/re_types/definitions/rerun/archetypes/boxes2d.fbs b/crates/store/re_types/definitions/rerun/archetypes/boxes2d.fbs index fc8c1b96eb24..8c2ca8bd82e6 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/boxes2d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/boxes2d.fbs @@ -6,6 +6,7 @@ namespace rerun.archetypes; /// /// \example archetypes/boxes2d_simple title="Simple 2D boxes" image="https://static.rerun.io/box2d_simple/ac4424f3cf747382867649610cbd749c45b2020b/1200w.png" table Boxes2D ( + // TODO(#7245): "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq", "attr.rust.new_pub_crate", "attr.cpp.no_field_ctors", diff --git a/crates/store/re_types/definitions/rerun/archetypes/boxes3d.fbs b/crates/store/re_types/definitions/rerun/archetypes/boxes3d.fbs index bb2552778c40..a690eb659903 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/boxes3d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/boxes3d.fbs @@ -11,6 +11,7 @@ namespace rerun.archetypes; /// \example archetypes/boxes3d_simple !api title="Simple 3D boxes" image="https://static.rerun.io/box3d_simple/d6a3f38d2e3360fbacac52bb43e44762635be9c8/1200w.png" /// \example archetypes/boxes3d_batch title="Batch of 3D boxes" image="https://static.rerun.io/box3d_batch/5aac5b5d29c9f2ecd572c93f6970fcec17f4984b/1200w.png" table Boxes3D ( + // TODO(#7245): "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq", "attr.rust.new_pub_crate", "attr.cpp.no_field_ctors", diff --git a/crates/store/re_types/definitions/rerun/archetypes/capsules3d.fbs b/crates/store/re_types/definitions/rerun/archetypes/capsules3d.fbs index 2b7f4434b272..5c5ffc5f8f60 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/capsules3d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/capsules3d.fbs @@ -14,6 +14,7 @@ namespace rerun.archetypes; // TODO(#1361): This archetype should eventually generalize to cylinders without caps, truncated // cones, and tapered capsules -- all common shapes based on expanding a line segment circularly. table Capsules3D ( + "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq", "attr.rust.new_pub_crate", "attr.cpp.no_field_ctors", diff --git a/crates/store/re_types/definitions/rerun/archetypes/clear.fbs b/crates/store/re_types/definitions/rerun/archetypes/clear.fbs index ad8ec3f81759..91a21227110e 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/clear.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/clear.fbs @@ -17,7 +17,8 @@ namespace rerun.archetypes; /// \example archetypes/clear_simple title="Flat" image="https://static.rerun.io/clear_simple/2f5df95fcc53e9f0552f65670aef7f94830c5c1a/1200w.png" /// \example archetypes/clear_recursive !api "Recursive" table Clear ( - "attr.rust.derive": "PartialEq, Eq", + "attr.rust.archetype_eager", + "attr.rust.derive": "PartialEq", "attr.rust.override_crate": "re_types_core", "attr.docs.view_types": "Spatial2DView, Spatial3DView, TimeSeriesView" ) { diff --git a/crates/store/re_types/definitions/rerun/archetypes/depth_image.fbs b/crates/store/re_types/definitions/rerun/archetypes/depth_image.fbs index 24d63fa7c9e3..754d6883615b 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/depth_image.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/depth_image.fbs @@ -12,6 +12,7 @@ namespace rerun.archetypes; /// \example archetypes/depth_image_simple !api title="Simple example" image="https://static.rerun.io/depth_image_simple/77a6fa4f938a742bdc7c5350f668c4f31eed4d01/1200w.png" /// \example archetypes/depth_image_3d title="Depth to 3D example" image="https://static.rerun.io/depth_image_3d/924e9d4d6a39d63d4fdece82582855fdaa62d15e/1200w.png" table DepthImage ( + "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq", "attr.cpp.no_field_ctors", "attr.docs.category": "Image & tensor", diff --git a/crates/store/re_types/definitions/rerun/archetypes/ellipsoids3d.fbs b/crates/store/re_types/definitions/rerun/archetypes/ellipsoids3d.fbs index 469ff7009186..49a775ca6e24 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/ellipsoids3d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/ellipsoids3d.fbs @@ -14,6 +14,7 @@ namespace rerun.archetypes; /// /// \example archetypes/ellipsoids3d_simple title="Covariance ellipsoid" image="https://static.rerun.io/elliopsoid3d_simple/bd5d46e61b80ae44792b52ee07d750a7137002ea/1200w.png" table Ellipsoids3D ( + "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq", "attr.rust.new_pub_crate", "attr.cpp.no_field_ctors", diff --git a/crates/store/re_types/definitions/rerun/archetypes/encoded_image.fbs b/crates/store/re_types/definitions/rerun/archetypes/encoded_image.fbs index 654b846e77ff..9b3ce810d01b 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/encoded_image.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/encoded_image.fbs @@ -10,6 +10,7 @@ namespace rerun.archetypes; /// /// \example archetypes/encoded_image table EncodedImage ( + "attr.rust.archetype_eager", "attr.cpp.no_field_ctors", "attr.docs.category": "Image & tensor", "attr.docs.view_types": "Spatial2DView, Spatial3DView: if logged under a projection", diff --git a/crates/store/re_types/definitions/rerun/archetypes/geo_line_strings.fbs b/crates/store/re_types/definitions/rerun/archetypes/geo_line_strings.fbs index 37eb4e831e8e..9c34f0d269cf 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/geo_line_strings.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/geo_line_strings.fbs @@ -8,6 +8,7 @@ namespace rerun.archetypes; /// /// \example archetypes/geo_line_strings_simple title="Log a geospatial line string" image="https://static.rerun.io/geo_line_strings_simple/5669983eb10906ace303755b5b5039cad75b917f/1200w.png" table GeoLineStrings ( + "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq", "attr.rust.new_pub_crate", "attr.docs.category": "Geospatial", diff --git a/crates/store/re_types/definitions/rerun/archetypes/geo_points.fbs b/crates/store/re_types/definitions/rerun/archetypes/geo_points.fbs index 2c23035f084b..2824f5cae568 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/geo_points.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/geo_points.fbs @@ -4,6 +4,7 @@ namespace rerun.archetypes; /// /// \example archetypes/geo_points_simple title="Log a geospatial point" image="https://static.rerun.io/geopoint_simple/b86ce83e5871837587bd33a0ad639358b96e9010/1200w.png" table GeoPoints ( + "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq", "attr.rust.new_pub_crate", "attr.docs.category": "Geospatial", diff --git a/crates/store/re_types/definitions/rerun/archetypes/graph_edges.fbs b/crates/store/re_types/definitions/rerun/archetypes/graph_edges.fbs index c85a4e58e4bb..bc946fed67d6 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/graph_edges.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/graph_edges.fbs @@ -9,9 +9,10 @@ namespace rerun.archetypes; /// \example archetypes/graph_undirected !api title="Simple undirected graph" image="https://static.rerun.io/graph_undirected/15f46bec77452a8c6220558e4403b99cac188e2e/1200w.png" /// \example archetypes/graph_directed title="Simple directed graph" image="https://static.rerun.io/graph_directed/ca29a37b65e1e0b6482251dce401982a0bc568fa/1200w.png" table GraphEdges ( + "attr.rust.archetype_eager", "attr.docs.category": "Graph", "attr.docs.view_types": "GraphView", - "attr.rust.derive": "PartialEq, Eq" + "attr.rust.derive": "PartialEq" ) { // --- Required --- diff --git a/crates/store/re_types/definitions/rerun/archetypes/graph_nodes.fbs b/crates/store/re_types/definitions/rerun/archetypes/graph_nodes.fbs index d169b97bd25b..beca6808d500 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/graph_nodes.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/graph_nodes.fbs @@ -7,6 +7,7 @@ namespace rerun.archetypes; /// \example archetypes/graph_undirected !api title="Simple undirected graph" image="https://static.rerun.io/graph_undirected/15f46bec77452a8c6220558e4403b99cac188e2e/1200w.png" /// \example archetypes/graph_directed title="Simple directed graph" image="https://static.rerun.io/graph_directed/ca29a37b65e1e0b6482251dce401982a0bc568fa/1200w.png" table GraphNodes ( + "attr.rust.archetype_eager", "attr.docs.category": "Graph", "attr.docs.view_types": "GraphView", "attr.rust.derive": "PartialEq" diff --git a/crates/store/re_types/definitions/rerun/archetypes/image.fbs b/crates/store/re_types/definitions/rerun/archetypes/image.fbs index 0617aac1d6ce..bd73ee273b01 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/image.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/image.fbs @@ -24,6 +24,7 @@ namespace rerun.archetypes; /// \example archetypes/image_formats title="Logging images with various formats" image="https://static.rerun.io/image_formats/7b8a162fcfd266f303980439beea997dc8544c24/full.png" /// \example archetypes/image_send_columns !api title="Image from file, PIL & OpenCV" image="https://static.rerun.io/image_advanced/81fc8a255488615510790ee41be314e054978d51/full.png" table Image ( + // TODO(#7245): "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq", "attr.cpp.no_field_ctors", "attr.docs.category": "Image & tensor", diff --git a/crates/store/re_types/definitions/rerun/archetypes/instance_poses3d.fbs b/crates/store/re_types/definitions/rerun/archetypes/instance_poses3d.fbs index d7ffbabe01ea..2ed7104b8f85 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/instance_poses3d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/instance_poses3d.fbs @@ -19,6 +19,7 @@ namespace rerun.archetypes; /// \example archetypes/instance_poses3d_combined title="Regular & instance transforms in tandem" image="https://static.rerun.io/leaf_transform3d/41674f0082d6de489f8a1cd1583f60f6b5820ddf/1200w.png" /// \example archetypes/mesh3d_instancing !api title="3D mesh with instancing" image="https://static.rerun.io/mesh3d_leaf_transforms3d/c2d0ee033129da53168f5705625a9b033f3a3d61/1200w.png" table InstancePoses3D ( + "attr.rust.archetype_eager", "attr.docs.category": "Spatial 3D", "attr.docs.view_types": "Spatial3DView, Spatial2DView: if logged above active projection", "attr.rust.derive": " PartialEq" diff --git a/crates/store/re_types/definitions/rerun/archetypes/mesh3d.fbs b/crates/store/re_types/definitions/rerun/archetypes/mesh3d.fbs index 8b003db691bb..a3472cefb4b9 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/mesh3d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/mesh3d.fbs @@ -13,6 +13,7 @@ namespace rerun.archetypes; /// \example archetypes/mesh3d_partial_updates !api title="3D mesh with partial updates" image="https://static.rerun.io/mesh3d_partial_updates/7de33d26220585691a403098c953cd46f94c3262/1200w.png" /// \example archetypes/mesh3d_instancing title="3D mesh with instancing" image="https://static.rerun.io/mesh3d_leaf_transforms3d/c2d0ee033129da53168f5705625a9b033f3a3d61/1200w.png" table Mesh3D ( + // TODO(#7245): "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq", "attr.docs.category": "Spatial 3D", "attr.docs.view_types": "Spatial3DView, Spatial2DView: if logged above active projection" diff --git a/crates/store/re_types/definitions/rerun/archetypes/pinhole.fbs b/crates/store/re_types/definitions/rerun/archetypes/pinhole.fbs index e5071aacb00f..bd13d712c4f8 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/pinhole.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/pinhole.fbs @@ -6,6 +6,7 @@ namespace rerun.archetypes; /// \example archetypes/pinhole_simple title="Simple pinhole camera" image="https://static.rerun.io/pinhole_simple/9af9441a94bcd9fd54e1fea44fb0c59ff381a7f2/1200w.png" /// \example archetypes/pinhole_perspective title="Perspective pinhole camera" image="https://static.rerun.io/pinhole_perspective/317e2de6d212b238dcdad5b67037e9e2a2afafa0/1200w.png" table Pinhole ( + // TODO(#7245): "attr.rust.archetype_eager" "attr.rust.derive": "PartialEq", "attr.docs.category": "Spatial 3D", "attr.docs.view_types": "Spatial2DView, Spatial2DView" diff --git a/crates/store/re_types/definitions/rerun/archetypes/points2d.fbs b/crates/store/re_types/definitions/rerun/archetypes/points2d.fbs index 33bffc2991d2..8f1e33c093c3 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/points2d.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/points2d.fbs @@ -10,6 +10,7 @@ namespace rerun.archetypes; /// \example archetypes/points2d_random title="Randomly distributed 2D points with varying color and radius" image="https://static.rerun.io/point2d_random/8e8ac75373677bd72bd3f56a15e44fcab309a168/1200w.png" /// \example archetypes/points2d_ui_radius title="Log points with radii given in UI points" image="https://static.rerun.io/point2d_ui_radius/ce804fc77300d89c348b4ab5960395171497b7ac/1200w.png" table Points2D ( + "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq", "attr.docs.category": "Spatial 2D", "attr.docs.view_types": "Spatial2DView, Spatial3DView: if logged under a projection" diff --git a/crates/store/re_types/definitions/rerun/archetypes/scalar.fbs b/crates/store/re_types/definitions/rerun/archetypes/scalar.fbs index 70e700176e8c..773a3a8a7331 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/scalar.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/scalar.fbs @@ -16,6 +16,7 @@ namespace rerun.archetypes; /// \example archetypes/scalar_multiple_plots !api title="Multiple time series plots" image="https://static.rerun.io/scalar_multiple/15845c2a348f875248fbd694e03eabd922741c4c/1200w.png" /// \example archetypes/scalar_send_columns !api title="Multiple scalars in a single `send_columns` call" image="https://static.rerun.io/scalar_send_columns/b4bf172256f521f4851dfec5c2c6e3143f5d6923/1200w.png" table Scalar ( + "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq", "attr.docs.category": "Plotting", "attr.docs.view_types": "TimeSeriesView" diff --git a/crates/store/re_types/definitions/rerun/archetypes/segmentation_image.fbs b/crates/store/re_types/definitions/rerun/archetypes/segmentation_image.fbs index 8aa0e2048c28..e4097e683b74 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/segmentation_image.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/segmentation_image.fbs @@ -16,6 +16,7 @@ namespace rerun.archetypes; /// /// \example archetypes/segmentation_image_simple title="Simple segmentation image" image="https://static.rerun.io/segmentation_image_simple/f8aac62abcf4c59c5d62f9ebc2d86fd0285c1736/1200w.png" table SegmentationImage ( + "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq", "attr.cpp.no_field_ctors", "attr.docs.category": "Image & tensor", diff --git a/crates/store/re_types/definitions/rerun/archetypes/series_line.fbs b/crates/store/re_types/definitions/rerun/archetypes/series_line.fbs index afbcc4921963..73defca058b3 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/series_line.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/series_line.fbs @@ -10,6 +10,7 @@ namespace rerun.archetypes; /// /// \example archetypes/series_line_style title="Line series" image="https://static.rerun.io/series_line_style/d2616d98b1e46bdb85849b8669154fdf058e3453/1200w.png" table SeriesLine ( + "attr.rust.archetype_eager", "attr.docs.category": "Plotting", "attr.docs.view_types": "TimeSeriesView" ) { diff --git a/crates/store/re_types/definitions/rerun/archetypes/series_point.fbs b/crates/store/re_types/definitions/rerun/archetypes/series_point.fbs index bf918e89867e..f3d475c46136 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/series_point.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/series_point.fbs @@ -10,6 +10,7 @@ namespace rerun.archetypes; /// /// \example archetypes/series_point_style title="Point series" image="https://static.rerun.io/series_point_style/82207a705da6c086b28ce161db1db9e8b12258b7/1200w.png" table SeriesPoint ( + "attr.rust.archetype_eager", "attr.docs.category": "Plotting", "attr.docs.view_types": "TimeSeriesView" ) { diff --git a/crates/store/re_types/definitions/rerun/archetypes/tensor.fbs b/crates/store/re_types/definitions/rerun/archetypes/tensor.fbs index 00ea0344f112..0976fa1fe0bb 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/tensor.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/tensor.fbs @@ -13,6 +13,7 @@ namespace rerun.archetypes; /// /// \example archetypes/tensor_simple title="Simple tensor" image="https://static.rerun.io/tensor_simple/baacb07712f7b706e3c80e696f70616c6c20b367/1200w.png" table Tensor ( + // TODO(#7245): "attr.rust.archetype_eager", "attr.rust.derive": "PartialEq", "attr.docs.category": "Image & tensor", "attr.docs.view_types": "TensorView, BarChartView: for 1D tensors" diff --git a/crates/store/re_types/definitions/rerun/archetypes/text_document.fbs b/crates/store/re_types/definitions/rerun/archetypes/text_document.fbs index d5224bc8f201..5259f16f09dc 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/text_document.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/text_document.fbs @@ -8,7 +8,8 @@ namespace rerun.archetypes; /// /// \example archetypes/text_document title="Markdown text document" image="https://static.rerun.io/textdocument/babda19558ee32ed8d730495b595aee7a5e2c174/1200w.png" table TextDocument ( - "attr.rust.derive": "PartialEq, Eq", + "attr.rust.archetype_eager", + "attr.rust.derive": "PartialEq", "attr.docs.category": "Text", "attr.docs.view_types": "TextDocumentView" ) { diff --git a/crates/store/re_types/definitions/rerun/archetypes/text_log.fbs b/crates/store/re_types/definitions/rerun/archetypes/text_log.fbs index 9646ba0654cd..6ed31795cd15 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/text_log.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/text_log.fbs @@ -6,7 +6,8 @@ namespace rerun.archetypes; /// /// \example archetypes/text_log_integration text="Logging text directly or via a logger" image="https://static.rerun.io/text_log_integration/9737d0c986325802a9885499d6fcc773b1736488/1200w.png" table TextLog ( - "attr.rust.derive": "PartialEq, Eq", + "attr.rust.archetype_eager", + "attr.rust.derive": "PartialEq", "attr.docs.category": "Text", "attr.docs.view_types": "TextLogView" ) { diff --git a/crates/store/re_types/definitions/rerun/archetypes/video_frame_reference.fbs b/crates/store/re_types/definitions/rerun/archetypes/video_frame_reference.fbs index 0bf9de7af449..a423a147a73d 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/video_frame_reference.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/video_frame_reference.fbs @@ -10,6 +10,7 @@ namespace rerun.archetypes; /// \example archetypes/video_auto_frames title="Video with automatically determined frames" image="https://static.rerun.io/video_manual_frames/320a44e1e06b8b3a3161ecbbeae3e04d1ccb9589/1200w.png" /// \example archetypes/video_manual_frames title="Demonstrates manual use of video frame references" image="https://static.rerun.io/video_manual_frames/9f41c00f84a98cc3f26875fba7c1d2fa2bad7151/1200w.png" table VideoFrameReference ( + "attr.rust.archetype_eager", "attr.docs.category": "Video", "attr.docs.view_types": "Spatial2DView, Spatial3DView: if logged under a projection" ){ diff --git a/crates/store/re_types/definitions/rerun/archetypes/view_coordinates.fbs b/crates/store/re_types/definitions/rerun/archetypes/view_coordinates.fbs index 88cf09f52a40..49ebdd02d0bc 100644 --- a/crates/store/re_types/definitions/rerun/archetypes/view_coordinates.fbs +++ b/crates/store/re_types/definitions/rerun/archetypes/view_coordinates.fbs @@ -17,6 +17,7 @@ namespace rerun.archetypes; /// /// \example archetypes/view_coordinates_simple title="View coordinates for adjusting the eye camera" image="https://static.rerun.io/viewcoordinates/0833f0dc8616a676b7b2c566f2a6f613363680c5/1200w.png" table ViewCoordinates ( + // TODO(#7245): "attr.rust.archetype_eager", "attr.rust.derive": "Copy, PartialEq, Eq, bytemuck::Pod, bytemuck::Zeroable", "attr.rust.repr": "transparent", "attr.docs.category": "Spatial 3D", diff --git a/crates/store/re_types/src/archetypes/arrows2d.rs b/crates/store/re_types/src/archetypes/arrows2d.rs index 6afea171fe0b..e34a17d00a8b 100644 --- a/crates/store/re_types/src/archetypes/arrows2d.rs +++ b/crates/store/re_types/src/archetypes/arrows2d.rs @@ -48,43 +48,43 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct Arrows2D { /// All the vectors for each arrow in the batch. - pub vectors: Vec, + pub vectors: Option, /// All the origin (base) positions for each arrow in the batch. /// /// If no origins are set, (0, 0) is used as the origin for each arrow. - pub origins: Option>, + pub origins: Option, /// Optional radii for the arrows. /// /// The shaft is rendered as a line with `radius = 0.5 * radius`. /// The tip is rendered with `height = 2.0 * radius` and `radius = 1.0 * radius`. - pub radii: Option>, + pub radii: Option, /// Optional colors for the points. - pub colors: Option>, + pub colors: Option, /// Optional text labels for the arrows. /// /// If there's a single label present, it will be placed at the center of the entity. /// Otherwise, each instance will have its own label. - pub labels: Option>, + pub labels: Option, /// Optional choice of whether the text labels should be shown by default. - pub show_labels: Option, + pub show_labels: Option, /// An optional floating point value that specifies the 2D drawing order. /// /// Objects with higher values are drawn on top of those with lower values. - pub draw_order: Option, + pub draw_order: Option, /// Optional class Ids for the points. /// /// The [`components::ClassId`][crate::components::ClassId] provides colors and labels if not specified explicitly. - pub class_ids: Option>, + pub class_ids: Option, } impl Arrows2D { @@ -271,97 +271,36 @@ impl ::re_types_core::Archetype for Arrows2D { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let vectors = { - let array = arrays_by_descr - .get(&Self::descriptor_vectors()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.Arrows2D#vectors")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Arrows2D#vectors")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Arrows2D#vectors")? - }; - let origins = if let Some(array) = arrays_by_descr.get(&Self::descriptor_origins()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Arrows2D#origins")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Arrows2D#origins")? - }) - } else { - None - }; - let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Arrows2D#radii")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Arrows2D#radii")? - }) - } else { - None - }; - let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Arrows2D#colors")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Arrows2D#colors")? - }) - } else { - None - }; - let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Arrows2D#labels")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Arrows2D#labels")? - }) - } else { - None - }; - let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Arrows2D#show_labels")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let draw_order = if let Some(array) = arrays_by_descr.get(&Self::descriptor_draw_order()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Arrows2D#draw_order")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Arrows2D#class_ids")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Arrows2D#class_ids")? - }) - } else { - None - }; + let vectors = arrays_by_descr + .get(&Self::descriptor_vectors()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_vectors())); + let origins = arrays_by_descr + .get(&Self::descriptor_origins()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_origins())); + let radii = arrays_by_descr + .get(&Self::descriptor_radii()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_radii())); + let colors = arrays_by_descr + .get(&Self::descriptor_colors()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_colors())); + let labels = arrays_by_descr + .get(&Self::descriptor_labels()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_labels())); + let show_labels = arrays_by_descr + .get(&Self::descriptor_show_labels()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_show_labels()) + }); + let draw_order = arrays_by_descr + .get(&Self::descriptor_draw_order()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_draw_order()) + }); + let class_ids = arrays_by_descr + .get(&Self::descriptor_class_ids()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_class_ids()) + }); Ok(Self { vectors, origins, @@ -376,73 +315,19 @@ impl ::re_types_core::Archetype for Arrows2D { } impl ::re_types_core::AsComponents for Arrows2D { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.vectors as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_vectors()), - } - }), - (self - .origins - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_origins()), - }), - (self - .radii - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_radii()), - }), - (self - .colors - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_colors()), - }), - (self - .labels - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_labels()), - }), - (self - .show_labels - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_show_labels()), - }), - (self - .draw_order - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_draw_order()), - }), - (self - .class_ids - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_class_ids()), - }), + Self::indicator().serialized(), + self.vectors.clone(), + self.origins.clone(), + self.radii.clone(), + self.colors.clone(), + self.labels.clone(), + self.show_labels.clone(), + self.draw_order.clone(), + self.class_ids.clone(), ] .into_iter() .flatten() @@ -459,7 +344,7 @@ impl Arrows2D { vectors: impl IntoIterator>, ) -> Self { Self { - vectors: vectors.into_iter().map(Into::into).collect(), + vectors: try_serialize_field(Self::descriptor_vectors(), vectors), origins: None, radii: None, colors: None, @@ -470,6 +355,62 @@ impl Arrows2D { } } + /// Update only some specific fields of a `Arrows2D`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `Arrows2D`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + vectors: Some(SerializedComponentBatch::new( + crate::components::Vector2D::arrow_empty(), + Self::descriptor_vectors(), + )), + origins: Some(SerializedComponentBatch::new( + crate::components::Position2D::arrow_empty(), + Self::descriptor_origins(), + )), + radii: Some(SerializedComponentBatch::new( + crate::components::Radius::arrow_empty(), + Self::descriptor_radii(), + )), + colors: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_colors(), + )), + labels: Some(SerializedComponentBatch::new( + crate::components::Text::arrow_empty(), + Self::descriptor_labels(), + )), + show_labels: Some(SerializedComponentBatch::new( + crate::components::ShowLabels::arrow_empty(), + Self::descriptor_show_labels(), + )), + draw_order: Some(SerializedComponentBatch::new( + crate::components::DrawOrder::arrow_empty(), + Self::descriptor_draw_order(), + )), + class_ids: Some(SerializedComponentBatch::new( + crate::components::ClassId::arrow_empty(), + Self::descriptor_class_ids(), + )), + } + } + + /// All the vectors for each arrow in the batch. + #[inline] + pub fn with_vectors( + mut self, + vectors: impl IntoIterator>, + ) -> Self { + self.vectors = try_serialize_field(Self::descriptor_vectors(), vectors); + self + } + /// All the origin (base) positions for each arrow in the batch. /// /// If no origins are set, (0, 0) is used as the origin for each arrow. @@ -478,7 +419,7 @@ impl Arrows2D { mut self, origins: impl IntoIterator>, ) -> Self { - self.origins = Some(origins.into_iter().map(Into::into).collect()); + self.origins = try_serialize_field(Self::descriptor_origins(), origins); self } @@ -491,7 +432,7 @@ impl Arrows2D { mut self, radii: impl IntoIterator>, ) -> Self { - self.radii = Some(radii.into_iter().map(Into::into).collect()); + self.radii = try_serialize_field(Self::descriptor_radii(), radii); self } @@ -501,7 +442,7 @@ impl Arrows2D { mut self, colors: impl IntoIterator>, ) -> Self { - self.colors = Some(colors.into_iter().map(Into::into).collect()); + self.colors = try_serialize_field(Self::descriptor_colors(), colors); self } @@ -514,7 +455,7 @@ impl Arrows2D { mut self, labels: impl IntoIterator>, ) -> Self { - self.labels = Some(labels.into_iter().map(Into::into).collect()); + self.labels = try_serialize_field(Self::descriptor_labels(), labels); self } @@ -524,7 +465,7 @@ impl Arrows2D { mut self, show_labels: impl Into, ) -> Self { - self.show_labels = Some(show_labels.into()); + self.show_labels = try_serialize_field(Self::descriptor_show_labels(), [show_labels]); self } @@ -533,7 +474,7 @@ impl Arrows2D { /// Objects with higher values are drawn on top of those with lower values. #[inline] pub fn with_draw_order(mut self, draw_order: impl Into) -> Self { - self.draw_order = Some(draw_order.into()); + self.draw_order = try_serialize_field(Self::descriptor_draw_order(), [draw_order]); self } @@ -545,7 +486,7 @@ impl Arrows2D { mut self, class_ids: impl IntoIterator>, ) -> Self { - self.class_ids = Some(class_ids.into_iter().map(Into::into).collect()); + self.class_ids = try_serialize_field(Self::descriptor_class_ids(), class_ids); self } } @@ -562,16 +503,4 @@ impl ::re_byte_size::SizeBytes for Arrows2D { + self.draw_order.heap_size_bytes() + self.class_ids.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >::is_pod() - && >::is_pod() - && >>::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/arrows3d.rs b/crates/store/re_types/src/archetypes/arrows3d.rs index dd0027b11e8d..5ba80d6c4c50 100644 --- a/crates/store/re_types/src/archetypes/arrows3d.rs +++ b/crates/store/re_types/src/archetypes/arrows3d.rs @@ -61,38 +61,38 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct Arrows3D { /// All the vectors for each arrow in the batch. - pub vectors: Vec, + pub vectors: Option, /// All the origin (base) positions for each arrow in the batch. /// /// If no origins are set, (0, 0, 0) is used as the origin for each arrow. - pub origins: Option>, + pub origins: Option, /// Optional radii for the arrows. /// /// The shaft is rendered as a line with `radius = 0.5 * radius`. /// The tip is rendered with `height = 2.0 * radius` and `radius = 1.0 * radius`. - pub radii: Option>, + pub radii: Option, /// Optional colors for the points. - pub colors: Option>, + pub colors: Option, /// Optional text labels for the arrows. /// /// If there's a single label present, it will be placed at the center of the entity. /// Otherwise, each instance will have its own label. - pub labels: Option>, + pub labels: Option, /// Optional choice of whether the text labels should be shown by default. - pub show_labels: Option, + pub show_labels: Option, /// Optional class Ids for the points. /// /// The [`components::ClassId`][crate::components::ClassId] provides colors and labels if not specified explicitly. - pub class_ids: Option>, + pub class_ids: Option, } impl Arrows3D { @@ -267,88 +267,31 @@ impl ::re_types_core::Archetype for Arrows3D { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let vectors = { - let array = arrays_by_descr - .get(&Self::descriptor_vectors()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.Arrows3D#vectors")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Arrows3D#vectors")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Arrows3D#vectors")? - }; - let origins = if let Some(array) = arrays_by_descr.get(&Self::descriptor_origins()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Arrows3D#origins")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Arrows3D#origins")? - }) - } else { - None - }; - let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Arrows3D#radii")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Arrows3D#radii")? - }) - } else { - None - }; - let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Arrows3D#colors")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Arrows3D#colors")? - }) - } else { - None - }; - let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Arrows3D#labels")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Arrows3D#labels")? - }) - } else { - None - }; - let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Arrows3D#show_labels")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Arrows3D#class_ids")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Arrows3D#class_ids")? - }) - } else { - None - }; + let vectors = arrays_by_descr + .get(&Self::descriptor_vectors()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_vectors())); + let origins = arrays_by_descr + .get(&Self::descriptor_origins()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_origins())); + let radii = arrays_by_descr + .get(&Self::descriptor_radii()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_radii())); + let colors = arrays_by_descr + .get(&Self::descriptor_colors()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_colors())); + let labels = arrays_by_descr + .get(&Self::descriptor_labels()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_labels())); + let show_labels = arrays_by_descr + .get(&Self::descriptor_show_labels()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_show_labels()) + }); + let class_ids = arrays_by_descr + .get(&Self::descriptor_class_ids()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_class_ids()) + }); Ok(Self { vectors, origins, @@ -362,65 +305,18 @@ impl ::re_types_core::Archetype for Arrows3D { } impl ::re_types_core::AsComponents for Arrows3D { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.vectors as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_vectors()), - } - }), - (self - .origins - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_origins()), - }), - (self - .radii - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_radii()), - }), - (self - .colors - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_colors()), - }), - (self - .labels - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_labels()), - }), - (self - .show_labels - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_show_labels()), - }), - (self - .class_ids - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_class_ids()), - }), + Self::indicator().serialized(), + self.vectors.clone(), + self.origins.clone(), + self.radii.clone(), + self.colors.clone(), + self.labels.clone(), + self.show_labels.clone(), + self.class_ids.clone(), ] .into_iter() .flatten() @@ -437,7 +333,7 @@ impl Arrows3D { vectors: impl IntoIterator>, ) -> Self { Self { - vectors: vectors.into_iter().map(Into::into).collect(), + vectors: try_serialize_field(Self::descriptor_vectors(), vectors), origins: None, radii: None, colors: None, @@ -447,6 +343,58 @@ impl Arrows3D { } } + /// Update only some specific fields of a `Arrows3D`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `Arrows3D`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + vectors: Some(SerializedComponentBatch::new( + crate::components::Vector3D::arrow_empty(), + Self::descriptor_vectors(), + )), + origins: Some(SerializedComponentBatch::new( + crate::components::Position3D::arrow_empty(), + Self::descriptor_origins(), + )), + radii: Some(SerializedComponentBatch::new( + crate::components::Radius::arrow_empty(), + Self::descriptor_radii(), + )), + colors: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_colors(), + )), + labels: Some(SerializedComponentBatch::new( + crate::components::Text::arrow_empty(), + Self::descriptor_labels(), + )), + show_labels: Some(SerializedComponentBatch::new( + crate::components::ShowLabels::arrow_empty(), + Self::descriptor_show_labels(), + )), + class_ids: Some(SerializedComponentBatch::new( + crate::components::ClassId::arrow_empty(), + Self::descriptor_class_ids(), + )), + } + } + + /// All the vectors for each arrow in the batch. + #[inline] + pub fn with_vectors( + mut self, + vectors: impl IntoIterator>, + ) -> Self { + self.vectors = try_serialize_field(Self::descriptor_vectors(), vectors); + self + } + /// All the origin (base) positions for each arrow in the batch. /// /// If no origins are set, (0, 0, 0) is used as the origin for each arrow. @@ -455,7 +403,7 @@ impl Arrows3D { mut self, origins: impl IntoIterator>, ) -> Self { - self.origins = Some(origins.into_iter().map(Into::into).collect()); + self.origins = try_serialize_field(Self::descriptor_origins(), origins); self } @@ -468,7 +416,7 @@ impl Arrows3D { mut self, radii: impl IntoIterator>, ) -> Self { - self.radii = Some(radii.into_iter().map(Into::into).collect()); + self.radii = try_serialize_field(Self::descriptor_radii(), radii); self } @@ -478,7 +426,7 @@ impl Arrows3D { mut self, colors: impl IntoIterator>, ) -> Self { - self.colors = Some(colors.into_iter().map(Into::into).collect()); + self.colors = try_serialize_field(Self::descriptor_colors(), colors); self } @@ -491,7 +439,7 @@ impl Arrows3D { mut self, labels: impl IntoIterator>, ) -> Self { - self.labels = Some(labels.into_iter().map(Into::into).collect()); + self.labels = try_serialize_field(Self::descriptor_labels(), labels); self } @@ -501,7 +449,7 @@ impl Arrows3D { mut self, show_labels: impl Into, ) -> Self { - self.show_labels = Some(show_labels.into()); + self.show_labels = try_serialize_field(Self::descriptor_show_labels(), [show_labels]); self } @@ -513,7 +461,7 @@ impl Arrows3D { mut self, class_ids: impl IntoIterator>, ) -> Self { - self.class_ids = Some(class_ids.into_iter().map(Into::into).collect()); + self.class_ids = try_serialize_field(Self::descriptor_class_ids(), class_ids); self } } @@ -529,15 +477,4 @@ impl ::re_byte_size::SizeBytes for Arrows3D { + self.show_labels.heap_size_bytes() + self.class_ids.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >::is_pod() - && >>::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/bar_chart.rs b/crates/store/re_types/src/archetypes/bar_chart.rs index 29ed3f84cf21..5e8cf8a7da88 100644 --- a/crates/store/re_types/src/archetypes/bar_chart.rs +++ b/crates/store/re_types/src/archetypes/bar_chart.rs @@ -46,13 +46,13 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct BarChart { /// The values. Should always be a 1-dimensional tensor (i.e. a vector). - pub values: crate::components::TensorData, + pub values: Option, /// The color of the bar chart - pub color: Option, + pub color: Option, } impl BarChart { @@ -159,52 +159,24 @@ impl ::re_types_core::Archetype for BarChart { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let values = { - let array = arrays_by_descr - .get(&Self::descriptor_values()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.BarChart#values")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.BarChart#values")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.BarChart#values")? - }; - let color = if let Some(array) = arrays_by_descr.get(&Self::descriptor_color()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.BarChart#color")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let values = arrays_by_descr + .get(&Self::descriptor_values()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_values())); + let color = arrays_by_descr + .get(&Self::descriptor_color()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_color())); Ok(Self { values, color }) } } impl ::re_types_core::AsComponents for BarChart { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.values as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_values()), - } - }), - (self - .color - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_color()), - }), + Self::indicator().serialized(), + self.values.clone(), + self.color.clone(), ] .into_iter() .flatten() @@ -219,15 +191,44 @@ impl BarChart { #[inline] pub fn new(values: impl Into) -> Self { Self { - values: values.into(), + values: try_serialize_field(Self::descriptor_values(), [values]), color: None, } } + /// Update only some specific fields of a `BarChart`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `BarChart`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + values: Some(SerializedComponentBatch::new( + crate::components::TensorData::arrow_empty(), + Self::descriptor_values(), + )), + color: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_color(), + )), + } + } + + /// The values. Should always be a 1-dimensional tensor (i.e. a vector). + #[inline] + pub fn with_values(mut self, values: impl Into) -> Self { + self.values = try_serialize_field(Self::descriptor_values(), [values]); + self + } + /// The color of the bar chart #[inline] pub fn with_color(mut self, color: impl Into) -> Self { - self.color = Some(color.into()); + self.color = try_serialize_field(Self::descriptor_color(), [color]); self } } @@ -237,9 +238,4 @@ impl ::re_byte_size::SizeBytes for BarChart { fn heap_size_bytes(&self) -> u64 { self.values.heap_size_bytes() + self.color.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - ::is_pod() && >::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/capsules3d.rs b/crates/store/re_types/src/archetypes/capsules3d.rs index db56147fb9cf..aa569e508056 100644 --- a/crates/store/re_types/src/archetypes/capsules3d.rs +++ b/crates/store/re_types/src/archetypes/capsules3d.rs @@ -71,45 +71,45 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct Capsules3D { /// Lengths of the capsules, defined as the distance between the centers of the endcaps. - pub lengths: Vec, + pub lengths: Option, /// Radii of the capsules. - pub radii: Vec, + pub radii: Option, /// Optional translations of the capsules. /// /// If not specified, one end of each capsule will be at (0, 0, 0). /// Note that this uses a [`components::PoseTranslation3D`][crate::components::PoseTranslation3D] which is also used by [`archetypes::InstancePoses3D`][crate::archetypes::InstancePoses3D]. - pub translations: Option>, + pub translations: Option, /// Rotations via axis + angle. /// /// If no rotation is specified, the capsules align with the +Z axis of the local coordinate system. /// Note that this uses a [`components::PoseRotationAxisAngle`][crate::components::PoseRotationAxisAngle] which is also used by [`archetypes::InstancePoses3D`][crate::archetypes::InstancePoses3D]. - pub rotation_axis_angles: Option>, + pub rotation_axis_angles: Option, /// Rotations via quaternion. /// /// If no rotation is specified, the capsules align with the +Z axis of the local coordinate system. /// Note that this uses a [`components::PoseRotationQuat`][crate::components::PoseRotationQuat] which is also used by [`archetypes::InstancePoses3D`][crate::archetypes::InstancePoses3D]. - pub quaternions: Option>, + pub quaternions: Option, /// Optional colors for the capsules. - pub colors: Option>, + pub colors: Option, /// Optional text labels for the capsules, which will be located at their centers. - pub labels: Option>, + pub labels: Option, /// Optional choice of whether the text labels should be shown by default. - pub show_labels: Option, + pub show_labels: Option, /// Optional class ID for the ellipsoids. /// /// The class ID provides colors and labels if not specified explicitly. - pub class_ids: Option>, + pub class_ids: Option, } impl Capsules3D { @@ -312,115 +312,46 @@ impl ::re_types_core::Archetype for Capsules3D { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let lengths = { - let array = arrays_by_descr - .get(&Self::descriptor_lengths()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.Capsules3D#lengths")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Capsules3D#lengths")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Capsules3D#lengths")? - }; - let radii = { - let array = arrays_by_descr - .get(&Self::descriptor_radii()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.Capsules3D#radii")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Capsules3D#radii")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Capsules3D#radii")? - }; - let translations = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_translations()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Capsules3D#translations")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Capsules3D#translations")? - }) - } else { - None - }; - let rotation_axis_angles = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_rotation_axis_angles()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Capsules3D#rotation_axis_angles")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Capsules3D#rotation_axis_angles")? - }) - } else { - None - }; - let quaternions = if let Some(array) = arrays_by_descr.get(&Self::descriptor_quaternions()) - { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Capsules3D#quaternions")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Capsules3D#quaternions")? - }) - } else { - None - }; - let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Capsules3D#colors")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Capsules3D#colors")? - }) - } else { - None - }; - let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Capsules3D#labels")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Capsules3D#labels")? - }) - } else { - None - }; - let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Capsules3D#show_labels")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Capsules3D#class_ids")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Capsules3D#class_ids")? - }) - } else { - None - }; + let lengths = arrays_by_descr + .get(&Self::descriptor_lengths()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_lengths())); + let radii = arrays_by_descr + .get(&Self::descriptor_radii()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_radii())); + let translations = arrays_by_descr + .get(&Self::descriptor_translations()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_translations()) + }); + let rotation_axis_angles = arrays_by_descr + .get(&Self::descriptor_rotation_axis_angles()) + .map(|array| { + SerializedComponentBatch::new( + array.clone(), + Self::descriptor_rotation_axis_angles(), + ) + }); + let quaternions = arrays_by_descr + .get(&Self::descriptor_quaternions()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_quaternions()) + }); + let colors = arrays_by_descr + .get(&Self::descriptor_colors()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_colors())); + let labels = arrays_by_descr + .get(&Self::descriptor_labels()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_labels())); + let show_labels = arrays_by_descr + .get(&Self::descriptor_show_labels()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_show_labels()) + }); + let class_ids = arrays_by_descr + .get(&Self::descriptor_class_ids()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_class_ids()) + }); Ok(Self { lengths, radii, @@ -436,79 +367,20 @@ impl ::re_types_core::Archetype for Capsules3D { } impl ::re_types_core::AsComponents for Capsules3D { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.lengths as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_lengths()), - } - }), - (Some(&self.radii as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_radii()), - } - }), - (self - .translations - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_translations()), - }), - (self - .rotation_axis_angles - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_rotation_axis_angles()), - }), - (self - .quaternions - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_quaternions()), - }), - (self - .colors - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_colors()), - }), - (self - .labels - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_labels()), - }), - (self - .show_labels - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_show_labels()), - }), - (self - .class_ids - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_class_ids()), - }), + Self::indicator().serialized(), + self.lengths.clone(), + self.radii.clone(), + self.translations.clone(), + self.rotation_axis_angles.clone(), + self.quaternions.clone(), + self.colors.clone(), + self.labels.clone(), + self.show_labels.clone(), + self.class_ids.clone(), ] .into_iter() .flatten() @@ -526,8 +398,8 @@ impl Capsules3D { radii: impl IntoIterator>, ) -> Self { Self { - lengths: lengths.into_iter().map(Into::into).collect(), - radii: radii.into_iter().map(Into::into).collect(), + lengths: try_serialize_field(Self::descriptor_lengths(), lengths), + radii: try_serialize_field(Self::descriptor_radii(), radii), translations: None, rotation_axis_angles: None, quaternions: None, @@ -538,6 +410,76 @@ impl Capsules3D { } } + /// Update only some specific fields of a `Capsules3D`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `Capsules3D`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + lengths: Some(SerializedComponentBatch::new( + crate::components::Length::arrow_empty(), + Self::descriptor_lengths(), + )), + radii: Some(SerializedComponentBatch::new( + crate::components::Radius::arrow_empty(), + Self::descriptor_radii(), + )), + translations: Some(SerializedComponentBatch::new( + crate::components::PoseTranslation3D::arrow_empty(), + Self::descriptor_translations(), + )), + rotation_axis_angles: Some(SerializedComponentBatch::new( + crate::components::PoseRotationAxisAngle::arrow_empty(), + Self::descriptor_rotation_axis_angles(), + )), + quaternions: Some(SerializedComponentBatch::new( + crate::components::PoseRotationQuat::arrow_empty(), + Self::descriptor_quaternions(), + )), + colors: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_colors(), + )), + labels: Some(SerializedComponentBatch::new( + crate::components::Text::arrow_empty(), + Self::descriptor_labels(), + )), + show_labels: Some(SerializedComponentBatch::new( + crate::components::ShowLabels::arrow_empty(), + Self::descriptor_show_labels(), + )), + class_ids: Some(SerializedComponentBatch::new( + crate::components::ClassId::arrow_empty(), + Self::descriptor_class_ids(), + )), + } + } + + /// Lengths of the capsules, defined as the distance between the centers of the endcaps. + #[inline] + pub fn with_lengths( + mut self, + lengths: impl IntoIterator>, + ) -> Self { + self.lengths = try_serialize_field(Self::descriptor_lengths(), lengths); + self + } + + /// Radii of the capsules. + #[inline] + pub fn with_radii( + mut self, + radii: impl IntoIterator>, + ) -> Self { + self.radii = try_serialize_field(Self::descriptor_radii(), radii); + self + } + /// Optional translations of the capsules. /// /// If not specified, one end of each capsule will be at (0, 0, 0). @@ -547,7 +489,7 @@ impl Capsules3D { mut self, translations: impl IntoIterator>, ) -> Self { - self.translations = Some(translations.into_iter().map(Into::into).collect()); + self.translations = try_serialize_field(Self::descriptor_translations(), translations); self } @@ -562,8 +504,10 @@ impl Capsules3D { Item = impl Into, >, ) -> Self { - self.rotation_axis_angles = - Some(rotation_axis_angles.into_iter().map(Into::into).collect()); + self.rotation_axis_angles = try_serialize_field( + Self::descriptor_rotation_axis_angles(), + rotation_axis_angles, + ); self } @@ -576,7 +520,7 @@ impl Capsules3D { mut self, quaternions: impl IntoIterator>, ) -> Self { - self.quaternions = Some(quaternions.into_iter().map(Into::into).collect()); + self.quaternions = try_serialize_field(Self::descriptor_quaternions(), quaternions); self } @@ -586,7 +530,7 @@ impl Capsules3D { mut self, colors: impl IntoIterator>, ) -> Self { - self.colors = Some(colors.into_iter().map(Into::into).collect()); + self.colors = try_serialize_field(Self::descriptor_colors(), colors); self } @@ -596,7 +540,7 @@ impl Capsules3D { mut self, labels: impl IntoIterator>, ) -> Self { - self.labels = Some(labels.into_iter().map(Into::into).collect()); + self.labels = try_serialize_field(Self::descriptor_labels(), labels); self } @@ -606,7 +550,7 @@ impl Capsules3D { mut self, show_labels: impl Into, ) -> Self { - self.show_labels = Some(show_labels.into()); + self.show_labels = try_serialize_field(Self::descriptor_show_labels(), [show_labels]); self } @@ -618,7 +562,7 @@ impl Capsules3D { mut self, class_ids: impl IntoIterator>, ) -> Self { - self.class_ids = Some(class_ids.into_iter().map(Into::into).collect()); + self.class_ids = try_serialize_field(Self::descriptor_class_ids(), class_ids); self } } @@ -636,17 +580,4 @@ impl ::re_byte_size::SizeBytes for Capsules3D { + self.show_labels.heap_size_bytes() + self.class_ids.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >::is_pod() - && >>::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/capsules3d_ext.rs b/crates/store/re_types/src/archetypes/capsules3d_ext.rs index f42af8ab9f52..889adb4344c6 100644 --- a/crates/store/re_types/src/archetypes/capsules3d_ext.rs +++ b/crates/store/re_types/src/archetypes/capsules3d_ext.rs @@ -65,6 +65,7 @@ impl Capsules3D { } #[cfg(test)] +#[cfg(feature = "glam")] mod tests { use super::*; use glam::vec3; diff --git a/crates/store/re_types/src/archetypes/depth_image.rs b/crates/store/re_types/src/archetypes/depth_image.rs index 9feba02636a2..3293d6babd1d 100644 --- a/crates/store/re_types/src/archetypes/depth_image.rs +++ b/crates/store/re_types/src/archetypes/depth_image.rs @@ -64,13 +64,13 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct DepthImage { /// The raw depth image data. - pub buffer: crate::components::ImageBuffer, + pub buffer: Option, /// The format of the image. - pub format: crate::components::ImageFormat, + pub format: Option, /// An optional floating point value that specifies how long a meter is in the native depth units. /// @@ -79,12 +79,12 @@ pub struct DepthImage { /// /// Note that the only effect on 2D views is the physical depth values shown when hovering the image. /// In 3D views on the other hand, this affects where the points of the point cloud are placed. - pub meter: Option, + pub meter: Option, /// Colormap to use for rendering the depth image. /// /// If not set, the depth image will be rendered using the Turbo colormap. - pub colormap: Option, + pub colormap: Option, /// The expected range of depth values. /// @@ -97,7 +97,7 @@ pub struct DepthImage { /// in the contents of the depth image. /// E.g. if all values are positive, some bigger than 1.0 and all smaller than 255.0, /// the Viewer will guess that the data likely came from an 8bit image, thus assuming a range of 0-255. - pub depth_range: Option, + pub depth_range: Option, /// Scale the radii of the points in the point cloud generated from this image. /// @@ -106,12 +106,12 @@ pub struct DepthImage { /// A fill ratio of 0.5 means that each point touches the edge of its neighbor if it has the same depth. /// /// TODO(#6744): This applies only to 3D views! - pub point_fill_ratio: Option, + pub point_fill_ratio: Option, /// An optional floating point value that specifies the 2D drawing order, used only if the depth image is shown as a 2D image. /// /// Objects with higher values are drawn on top of those with lower values. - pub draw_order: Option, + pub draw_order: Option, } impl DepthImage { @@ -286,79 +286,33 @@ impl ::re_types_core::Archetype for DepthImage { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let buffer = { - let array = arrays_by_descr - .get(&Self::descriptor_buffer()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.DepthImage#buffer")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.DepthImage#buffer")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.DepthImage#buffer")? - }; - let format = { - let array = arrays_by_descr - .get(&Self::descriptor_format()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.DepthImage#format")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.DepthImage#format")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.DepthImage#format")? - }; - let meter = if let Some(array) = arrays_by_descr.get(&Self::descriptor_meter()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.DepthImage#meter")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let colormap = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colormap()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.DepthImage#colormap")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let depth_range = if let Some(array) = arrays_by_descr.get(&Self::descriptor_depth_range()) - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.DepthImage#depth_range")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let point_fill_ratio = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_point_fill_ratio()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.DepthImage#point_fill_ratio")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let draw_order = if let Some(array) = arrays_by_descr.get(&Self::descriptor_draw_order()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.DepthImage#draw_order")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let buffer = arrays_by_descr + .get(&Self::descriptor_buffer()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_buffer())); + let format = arrays_by_descr + .get(&Self::descriptor_format()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_format())); + let meter = arrays_by_descr + .get(&Self::descriptor_meter()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_meter())); + let colormap = arrays_by_descr + .get(&Self::descriptor_colormap()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_colormap())); + let depth_range = arrays_by_descr + .get(&Self::descriptor_depth_range()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_depth_range()) + }); + let point_fill_ratio = arrays_by_descr + .get(&Self::descriptor_point_fill_ratio()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_point_fill_ratio()) + }); + let draw_order = arrays_by_descr + .get(&Self::descriptor_draw_order()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_draw_order()) + }); Ok(Self { buffer, format, @@ -372,63 +326,18 @@ impl ::re_types_core::Archetype for DepthImage { } impl ::re_types_core::AsComponents for DepthImage { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.buffer as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_buffer()), - } - }), - (Some(&self.format as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_format()), - } - }), - (self - .meter - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_meter()), - }), - (self - .colormap - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_colormap()), - }), - (self - .depth_range - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_depth_range()), - }), - (self - .point_fill_ratio - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_point_fill_ratio()), - }), - (self - .draw_order - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_draw_order()), - }), + Self::indicator().serialized(), + self.buffer.clone(), + self.format.clone(), + self.meter.clone(), + self.colormap.clone(), + self.depth_range.clone(), + self.point_fill_ratio.clone(), + self.draw_order.clone(), ] .into_iter() .flatten() @@ -446,8 +355,8 @@ impl DepthImage { format: impl Into, ) -> Self { Self { - buffer: buffer.into(), - format: format.into(), + buffer: try_serialize_field(Self::descriptor_buffer(), [buffer]), + format: try_serialize_field(Self::descriptor_format(), [format]), meter: None, colormap: None, depth_range: None, @@ -456,6 +365,62 @@ impl DepthImage { } } + /// Update only some specific fields of a `DepthImage`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `DepthImage`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + buffer: Some(SerializedComponentBatch::new( + crate::components::ImageBuffer::arrow_empty(), + Self::descriptor_buffer(), + )), + format: Some(SerializedComponentBatch::new( + crate::components::ImageFormat::arrow_empty(), + Self::descriptor_format(), + )), + meter: Some(SerializedComponentBatch::new( + crate::components::DepthMeter::arrow_empty(), + Self::descriptor_meter(), + )), + colormap: Some(SerializedComponentBatch::new( + crate::components::Colormap::arrow_empty(), + Self::descriptor_colormap(), + )), + depth_range: Some(SerializedComponentBatch::new( + crate::components::ValueRange::arrow_empty(), + Self::descriptor_depth_range(), + )), + point_fill_ratio: Some(SerializedComponentBatch::new( + crate::components::FillRatio::arrow_empty(), + Self::descriptor_point_fill_ratio(), + )), + draw_order: Some(SerializedComponentBatch::new( + crate::components::DrawOrder::arrow_empty(), + Self::descriptor_draw_order(), + )), + } + } + + /// The raw depth image data. + #[inline] + pub fn with_buffer(mut self, buffer: impl Into) -> Self { + self.buffer = try_serialize_field(Self::descriptor_buffer(), [buffer]); + self + } + + /// The format of the image. + #[inline] + pub fn with_format(mut self, format: impl Into) -> Self { + self.format = try_serialize_field(Self::descriptor_format(), [format]); + self + } + /// An optional floating point value that specifies how long a meter is in the native depth units. /// /// For instance: with uint16, perhaps meter=1000 which would mean you have millimeter precision @@ -465,7 +430,7 @@ impl DepthImage { /// In 3D views on the other hand, this affects where the points of the point cloud are placed. #[inline] pub fn with_meter(mut self, meter: impl Into) -> Self { - self.meter = Some(meter.into()); + self.meter = try_serialize_field(Self::descriptor_meter(), [meter]); self } @@ -474,7 +439,7 @@ impl DepthImage { /// If not set, the depth image will be rendered using the Turbo colormap. #[inline] pub fn with_colormap(mut self, colormap: impl Into) -> Self { - self.colormap = Some(colormap.into()); + self.colormap = try_serialize_field(Self::descriptor_colormap(), [colormap]); self } @@ -494,7 +459,7 @@ impl DepthImage { mut self, depth_range: impl Into, ) -> Self { - self.depth_range = Some(depth_range.into()); + self.depth_range = try_serialize_field(Self::descriptor_depth_range(), [depth_range]); self } @@ -510,7 +475,8 @@ impl DepthImage { mut self, point_fill_ratio: impl Into, ) -> Self { - self.point_fill_ratio = Some(point_fill_ratio.into()); + self.point_fill_ratio = + try_serialize_field(Self::descriptor_point_fill_ratio(), [point_fill_ratio]); self } @@ -519,7 +485,7 @@ impl DepthImage { /// Objects with higher values are drawn on top of those with lower values. #[inline] pub fn with_draw_order(mut self, draw_order: impl Into) -> Self { - self.draw_order = Some(draw_order.into()); + self.draw_order = try_serialize_field(Self::descriptor_draw_order(), [draw_order]); self } } @@ -535,15 +501,4 @@ impl ::re_byte_size::SizeBytes for DepthImage { + self.point_fill_ratio.heap_size_bytes() + self.draw_order.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - ::is_pod() - && ::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/depth_image_ext.rs b/crates/store/re_types/src/archetypes/depth_image_ext.rs index af72285a3edd..f6128ca7979f 100644 --- a/crates/store/re_types/src/archetypes/depth_image_ext.rs +++ b/crates/store/re_types/src/archetypes/depth_image_ext.rs @@ -34,15 +34,7 @@ impl DepthImage { let image_format = ImageFormat::depth([width as u32, height as u32], datatype); - Ok(Self { - buffer: blob.into(), - format: image_format, - draw_order: None, - meter: None, - colormap: None, - point_fill_ratio: None, - depth_range: None, - }) + Ok(Self::new(blob, image_format)) } /// Construct a depth image from a byte buffer given its resolution, and data type. @@ -62,15 +54,7 @@ impl DepthImage { ); } - Self { - buffer, - format: image_format, - meter: None, - colormap: None, - depth_range: None, - point_fill_ratio: None, - draw_order: None, - } + Self::new(buffer, image_format) } /// From an 16-bit grayscale image. diff --git a/crates/store/re_types/src/archetypes/ellipsoids3d.rs b/crates/store/re_types/src/archetypes/ellipsoids3d.rs index 06677f84f624..4bd00fda37be 100644 --- a/crates/store/re_types/src/archetypes/ellipsoids3d.rs +++ b/crates/store/re_types/src/archetypes/ellipsoids3d.rs @@ -79,50 +79,50 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct Ellipsoids3D { /// For each ellipsoid, half of its size on its three axes. /// /// If all components are equal, then it is a sphere with that radius. - pub half_sizes: Vec, + pub half_sizes: Option, /// Optional center positions of the ellipsoids. /// /// If not specified, the centers will be at (0, 0, 0). /// Note that this uses a [`components::PoseTranslation3D`][crate::components::PoseTranslation3D] which is also used by [`archetypes::InstancePoses3D`][crate::archetypes::InstancePoses3D]. - pub centers: Option>, + pub centers: Option, /// Rotations via axis + angle. /// /// If no rotation is specified, the axes of the ellipsoid align with the axes of the local coordinate system. /// Note that this uses a [`components::PoseRotationAxisAngle`][crate::components::PoseRotationAxisAngle] which is also used by [`archetypes::InstancePoses3D`][crate::archetypes::InstancePoses3D]. - pub rotation_axis_angles: Option>, + pub rotation_axis_angles: Option, /// Rotations via quaternion. /// /// If no rotation is specified, the axes of the ellipsoid align with the axes of the local coordinate system. /// Note that this uses a [`components::PoseRotationQuat`][crate::components::PoseRotationQuat] which is also used by [`archetypes::InstancePoses3D`][crate::archetypes::InstancePoses3D]. - pub quaternions: Option>, + pub quaternions: Option, /// Optional colors for the ellipsoids. - pub colors: Option>, + pub colors: Option, /// Optional radii for the lines used when the ellipsoid is rendered as a wireframe. - pub line_radii: Option>, + pub line_radii: Option, /// Optionally choose whether the ellipsoids are drawn with lines or solid. - pub fill_mode: Option, + pub fill_mode: Option, /// Optional text labels for the ellipsoids. - pub labels: Option>, + pub labels: Option, /// Optional choice of whether the text labels should be shown by default. - pub show_labels: Option, + pub show_labels: Option, /// Optional class ID for the ellipsoids. /// /// The class ID provides colors and labels if not specified explicitly. - pub class_ids: Option>, + pub class_ids: Option, } impl Ellipsoids3D { @@ -333,123 +333,53 @@ impl ::re_types_core::Archetype for Ellipsoids3D { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let half_sizes = { - let array = arrays_by_descr - .get(&Self::descriptor_half_sizes()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.Ellipsoids3D#half_sizes")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Ellipsoids3D#half_sizes")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Ellipsoids3D#half_sizes")? - }; - let centers = if let Some(array) = arrays_by_descr.get(&Self::descriptor_centers()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Ellipsoids3D#centers")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Ellipsoids3D#centers")? - }) - } else { - None - }; - let rotation_axis_angles = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_rotation_axis_angles()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Ellipsoids3D#rotation_axis_angles")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Ellipsoids3D#rotation_axis_angles")? - }) - } else { - None - }; - let quaternions = if let Some(array) = arrays_by_descr.get(&Self::descriptor_quaternions()) - { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Ellipsoids3D#quaternions")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Ellipsoids3D#quaternions")? - }) - } else { - None - }; - let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Ellipsoids3D#colors")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Ellipsoids3D#colors")? - }) - } else { - None - }; - let line_radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_line_radii()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Ellipsoids3D#line_radii")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Ellipsoids3D#line_radii")? - }) - } else { - None - }; - let fill_mode = if let Some(array) = arrays_by_descr.get(&Self::descriptor_fill_mode()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Ellipsoids3D#fill_mode")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Ellipsoids3D#labels")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Ellipsoids3D#labels")? - }) - } else { - None - }; - let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Ellipsoids3D#show_labels")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Ellipsoids3D#class_ids")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Ellipsoids3D#class_ids")? - }) - } else { - None - }; + let half_sizes = arrays_by_descr + .get(&Self::descriptor_half_sizes()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_half_sizes()) + }); + let centers = arrays_by_descr + .get(&Self::descriptor_centers()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_centers())); + let rotation_axis_angles = arrays_by_descr + .get(&Self::descriptor_rotation_axis_angles()) + .map(|array| { + SerializedComponentBatch::new( + array.clone(), + Self::descriptor_rotation_axis_angles(), + ) + }); + let quaternions = arrays_by_descr + .get(&Self::descriptor_quaternions()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_quaternions()) + }); + let colors = arrays_by_descr + .get(&Self::descriptor_colors()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_colors())); + let line_radii = arrays_by_descr + .get(&Self::descriptor_line_radii()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_line_radii()) + }); + let fill_mode = arrays_by_descr + .get(&Self::descriptor_fill_mode()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_fill_mode()) + }); + let labels = arrays_by_descr + .get(&Self::descriptor_labels()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_labels())); + let show_labels = arrays_by_descr + .get(&Self::descriptor_show_labels()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_show_labels()) + }); + let class_ids = arrays_by_descr + .get(&Self::descriptor_class_ids()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_class_ids()) + }); Ok(Self { half_sizes, centers, @@ -466,89 +396,21 @@ impl ::re_types_core::Archetype for Ellipsoids3D { } impl ::re_types_core::AsComponents for Ellipsoids3D { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.half_sizes as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_half_sizes()), - } - }), - (self - .centers - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_centers()), - }), - (self - .rotation_axis_angles - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_rotation_axis_angles()), - }), - (self - .quaternions - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_quaternions()), - }), - (self - .colors - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_colors()), - }), - (self - .line_radii - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_line_radii()), - }), - (self - .fill_mode - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_fill_mode()), - }), - (self - .labels - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_labels()), - }), - (self - .show_labels - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_show_labels()), - }), - (self - .class_ids - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_class_ids()), - }), + Self::indicator().serialized(), + self.half_sizes.clone(), + self.centers.clone(), + self.rotation_axis_angles.clone(), + self.quaternions.clone(), + self.colors.clone(), + self.line_radii.clone(), + self.fill_mode.clone(), + self.labels.clone(), + self.show_labels.clone(), + self.class_ids.clone(), ] .into_iter() .flatten() @@ -565,7 +427,7 @@ impl Ellipsoids3D { half_sizes: impl IntoIterator>, ) -> Self { Self { - half_sizes: half_sizes.into_iter().map(Into::into).collect(), + half_sizes: try_serialize_field(Self::descriptor_half_sizes(), half_sizes), centers: None, rotation_axis_angles: None, quaternions: None, @@ -578,6 +440,72 @@ impl Ellipsoids3D { } } + /// Update only some specific fields of a `Ellipsoids3D`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `Ellipsoids3D`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + half_sizes: Some(SerializedComponentBatch::new( + crate::components::HalfSize3D::arrow_empty(), + Self::descriptor_half_sizes(), + )), + centers: Some(SerializedComponentBatch::new( + crate::components::PoseTranslation3D::arrow_empty(), + Self::descriptor_centers(), + )), + rotation_axis_angles: Some(SerializedComponentBatch::new( + crate::components::PoseRotationAxisAngle::arrow_empty(), + Self::descriptor_rotation_axis_angles(), + )), + quaternions: Some(SerializedComponentBatch::new( + crate::components::PoseRotationQuat::arrow_empty(), + Self::descriptor_quaternions(), + )), + colors: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_colors(), + )), + line_radii: Some(SerializedComponentBatch::new( + crate::components::Radius::arrow_empty(), + Self::descriptor_line_radii(), + )), + fill_mode: Some(SerializedComponentBatch::new( + crate::components::FillMode::arrow_empty(), + Self::descriptor_fill_mode(), + )), + labels: Some(SerializedComponentBatch::new( + crate::components::Text::arrow_empty(), + Self::descriptor_labels(), + )), + show_labels: Some(SerializedComponentBatch::new( + crate::components::ShowLabels::arrow_empty(), + Self::descriptor_show_labels(), + )), + class_ids: Some(SerializedComponentBatch::new( + crate::components::ClassId::arrow_empty(), + Self::descriptor_class_ids(), + )), + } + } + + /// For each ellipsoid, half of its size on its three axes. + /// + /// If all components are equal, then it is a sphere with that radius. + #[inline] + pub fn with_half_sizes( + mut self, + half_sizes: impl IntoIterator>, + ) -> Self { + self.half_sizes = try_serialize_field(Self::descriptor_half_sizes(), half_sizes); + self + } + /// Optional center positions of the ellipsoids. /// /// If not specified, the centers will be at (0, 0, 0). @@ -587,7 +515,7 @@ impl Ellipsoids3D { mut self, centers: impl IntoIterator>, ) -> Self { - self.centers = Some(centers.into_iter().map(Into::into).collect()); + self.centers = try_serialize_field(Self::descriptor_centers(), centers); self } @@ -602,8 +530,10 @@ impl Ellipsoids3D { Item = impl Into, >, ) -> Self { - self.rotation_axis_angles = - Some(rotation_axis_angles.into_iter().map(Into::into).collect()); + self.rotation_axis_angles = try_serialize_field( + Self::descriptor_rotation_axis_angles(), + rotation_axis_angles, + ); self } @@ -616,7 +546,7 @@ impl Ellipsoids3D { mut self, quaternions: impl IntoIterator>, ) -> Self { - self.quaternions = Some(quaternions.into_iter().map(Into::into).collect()); + self.quaternions = try_serialize_field(Self::descriptor_quaternions(), quaternions); self } @@ -626,7 +556,7 @@ impl Ellipsoids3D { mut self, colors: impl IntoIterator>, ) -> Self { - self.colors = Some(colors.into_iter().map(Into::into).collect()); + self.colors = try_serialize_field(Self::descriptor_colors(), colors); self } @@ -636,14 +566,14 @@ impl Ellipsoids3D { mut self, line_radii: impl IntoIterator>, ) -> Self { - self.line_radii = Some(line_radii.into_iter().map(Into::into).collect()); + self.line_radii = try_serialize_field(Self::descriptor_line_radii(), line_radii); self } /// Optionally choose whether the ellipsoids are drawn with lines or solid. #[inline] pub fn with_fill_mode(mut self, fill_mode: impl Into) -> Self { - self.fill_mode = Some(fill_mode.into()); + self.fill_mode = try_serialize_field(Self::descriptor_fill_mode(), [fill_mode]); self } @@ -653,7 +583,7 @@ impl Ellipsoids3D { mut self, labels: impl IntoIterator>, ) -> Self { - self.labels = Some(labels.into_iter().map(Into::into).collect()); + self.labels = try_serialize_field(Self::descriptor_labels(), labels); self } @@ -663,7 +593,7 @@ impl Ellipsoids3D { mut self, show_labels: impl Into, ) -> Self { - self.show_labels = Some(show_labels.into()); + self.show_labels = try_serialize_field(Self::descriptor_show_labels(), [show_labels]); self } @@ -675,7 +605,7 @@ impl Ellipsoids3D { mut self, class_ids: impl IntoIterator>, ) -> Self { - self.class_ids = Some(class_ids.into_iter().map(Into::into).collect()); + self.class_ids = try_serialize_field(Self::descriptor_class_ids(), class_ids); self } } @@ -694,18 +624,4 @@ impl ::re_byte_size::SizeBytes for Ellipsoids3D { + self.show_labels.heap_size_bytes() + self.class_ids.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >::is_pod() - && >>::is_pod() - && >::is_pod() - && >>::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/encoded_image.rs b/crates/store/re_types/src/archetypes/encoded_image.rs index 8dfd575a277f..8c06b552f1ce 100644 --- a/crates/store/re_types/src/archetypes/encoded_image.rs +++ b/crates/store/re_types/src/archetypes/encoded_image.rs @@ -40,10 +40,10 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// Ok(()) /// } /// ``` -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct EncodedImage { /// The encoded content of some image file, e.g. a PNG or JPEG. - pub blob: crate::components::Blob, + pub blob: Option, /// The Media Type of the asset. /// @@ -53,17 +53,17 @@ pub struct EncodedImage { /// /// If omitted, the viewer will try to guess from the data blob. /// If it cannot guess, it won't be able to render the asset. - pub media_type: Option, + pub media_type: Option, /// Opacity of the image, useful for layering several images. /// /// Defaults to 1.0 (fully opaque). - pub opacity: Option, + pub opacity: Option, /// An optional floating point value that specifies the 2D drawing order. /// /// Objects with higher values are drawn on top of those with lower values. - pub draw_order: Option, + pub draw_order: Option, } impl EncodedImage { @@ -202,46 +202,22 @@ impl ::re_types_core::Archetype for EncodedImage { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let blob = { - let array = arrays_by_descr - .get(&Self::descriptor_blob()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.EncodedImage#blob")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.EncodedImage#blob")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.EncodedImage#blob")? - }; - let media_type = if let Some(array) = arrays_by_descr.get(&Self::descriptor_media_type()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.EncodedImage#media_type")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let opacity = if let Some(array) = arrays_by_descr.get(&Self::descriptor_opacity()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.EncodedImage#opacity")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let draw_order = if let Some(array) = arrays_by_descr.get(&Self::descriptor_draw_order()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.EncodedImage#draw_order")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let blob = arrays_by_descr + .get(&Self::descriptor_blob()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_blob())); + let media_type = arrays_by_descr + .get(&Self::descriptor_media_type()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_media_type()) + }); + let opacity = arrays_by_descr + .get(&Self::descriptor_opacity()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_opacity())); + let draw_order = arrays_by_descr + .get(&Self::descriptor_draw_order()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_draw_order()) + }); Ok(Self { blob, media_type, @@ -252,41 +228,15 @@ impl ::re_types_core::Archetype for EncodedImage { } impl ::re_types_core::AsComponents for EncodedImage { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.blob as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_blob()), - } - }), - (self - .media_type - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_media_type()), - }), - (self - .opacity - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_opacity()), - }), - (self - .draw_order - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_draw_order()), - }), + Self::indicator().serialized(), + self.blob.clone(), + self.media_type.clone(), + self.opacity.clone(), + self.draw_order.clone(), ] .into_iter() .flatten() @@ -301,13 +251,50 @@ impl EncodedImage { #[inline] pub fn new(blob: impl Into) -> Self { Self { - blob: blob.into(), + blob: try_serialize_field(Self::descriptor_blob(), [blob]), media_type: None, opacity: None, draw_order: None, } } + /// Update only some specific fields of a `EncodedImage`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `EncodedImage`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + blob: Some(SerializedComponentBatch::new( + crate::components::Blob::arrow_empty(), + Self::descriptor_blob(), + )), + media_type: Some(SerializedComponentBatch::new( + crate::components::MediaType::arrow_empty(), + Self::descriptor_media_type(), + )), + opacity: Some(SerializedComponentBatch::new( + crate::components::Opacity::arrow_empty(), + Self::descriptor_opacity(), + )), + draw_order: Some(SerializedComponentBatch::new( + crate::components::DrawOrder::arrow_empty(), + Self::descriptor_draw_order(), + )), + } + } + + /// The encoded content of some image file, e.g. a PNG or JPEG. + #[inline] + pub fn with_blob(mut self, blob: impl Into) -> Self { + self.blob = try_serialize_field(Self::descriptor_blob(), [blob]); + self + } + /// The Media Type of the asset. /// /// Supported values: @@ -318,7 +305,7 @@ impl EncodedImage { /// If it cannot guess, it won't be able to render the asset. #[inline] pub fn with_media_type(mut self, media_type: impl Into) -> Self { - self.media_type = Some(media_type.into()); + self.media_type = try_serialize_field(Self::descriptor_media_type(), [media_type]); self } @@ -327,7 +314,7 @@ impl EncodedImage { /// Defaults to 1.0 (fully opaque). #[inline] pub fn with_opacity(mut self, opacity: impl Into) -> Self { - self.opacity = Some(opacity.into()); + self.opacity = try_serialize_field(Self::descriptor_opacity(), [opacity]); self } @@ -336,7 +323,7 @@ impl EncodedImage { /// Objects with higher values are drawn on top of those with lower values. #[inline] pub fn with_draw_order(mut self, draw_order: impl Into) -> Self { - self.draw_order = Some(draw_order.into()); + self.draw_order = try_serialize_field(Self::descriptor_draw_order(), [draw_order]); self } } @@ -349,12 +336,4 @@ impl ::re_byte_size::SizeBytes for EncodedImage { + self.opacity.heap_size_bytes() + self.draw_order.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - ::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/encoded_image_ext.rs b/crates/store/re_types/src/archetypes/encoded_image_ext.rs index 09b37ad36ced..409c4411e189 100644 --- a/crates/store/re_types/src/archetypes/encoded_image_ext.rs +++ b/crates/store/re_types/src/archetypes/encoded_image_ext.rs @@ -1,5 +1,3 @@ -use crate::components::Blob; - use super::EncodedImage; impl EncodedImage { @@ -20,14 +18,16 @@ impl EncodedImage { /// /// [`Self::media_type`] will be guessed from the bytes. pub fn from_file_contents(bytes: Vec) -> Self { - #[allow(clippy::unnecessary_struct_initialization)] - Self { - #[cfg(feature = "image")] - media_type: image::guess_format(&bytes) + #[cfg(feature = "image")] + { + if let Some(media_type) = image::guess_format(&bytes) .ok() - .map(|format| crate::components::MediaType::from(format.to_mime_type())), - - ..Self::new(Blob::from(bytes)) + .map(|format| crate::components::MediaType::from(format.to_mime_type())) + { + return Self::new(bytes).with_media_type(media_type); + } } + + Self::new(bytes) } } diff --git a/crates/store/re_types/src/archetypes/geo_line_strings.rs b/crates/store/re_types/src/archetypes/geo_line_strings.rs index 58109147e0bc..a7159b1232ca 100644 --- a/crates/store/re_types/src/archetypes/geo_line_strings.rs +++ b/crates/store/re_types/src/archetypes/geo_line_strings.rs @@ -54,19 +54,19 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct GeoLineStrings { /// The line strings, expressed in [EPSG:4326](https://epsg.io/4326) coordinates (North/East-positive degrees). - pub line_strings: Vec, + pub line_strings: Option, /// Optional radii for the line strings. /// /// *Note*: scene units radiii are interpreted as meters. Currently, the display scale only considers the latitude of /// the first vertex of each line string (see [this issue](https://github.com/rerun-io/rerun/issues/8013)). - pub radii: Option>, + pub radii: Option, /// Optional colors for the line strings. - pub colors: Option>, + pub colors: Option, } impl GeoLineStrings { @@ -190,42 +190,17 @@ impl ::re_types_core::Archetype for GeoLineStrings { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let line_strings = { - let array = arrays_by_descr - .get(&Self::descriptor_line_strings()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.GeoLineStrings#line_strings")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.GeoLineStrings#line_strings")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.GeoLineStrings#line_strings")? - }; - let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.GeoLineStrings#radii")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.GeoLineStrings#radii")? - }) - } else { - None - }; - let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.GeoLineStrings#colors")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.GeoLineStrings#colors")? - }) - } else { - None - }; + let line_strings = arrays_by_descr + .get(&Self::descriptor_line_strings()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_line_strings()) + }); + let radii = arrays_by_descr + .get(&Self::descriptor_radii()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_radii())); + let colors = arrays_by_descr + .get(&Self::descriptor_colors()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_colors())); Ok(Self { line_strings, radii, @@ -235,33 +210,14 @@ impl ::re_types_core::Archetype for GeoLineStrings { } impl ::re_types_core::AsComponents for GeoLineStrings { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.line_strings as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_line_strings()), - } - }), - (self - .radii - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_radii()), - }), - (self - .colors - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_colors()), - }), + Self::indicator().serialized(), + self.line_strings.clone(), + self.radii.clone(), + self.colors.clone(), ] .into_iter() .flatten() @@ -278,12 +234,48 @@ impl GeoLineStrings { line_strings: impl IntoIterator>, ) -> Self { Self { - line_strings: line_strings.into_iter().map(Into::into).collect(), + line_strings: try_serialize_field(Self::descriptor_line_strings(), line_strings), radii: None, colors: None, } } + /// Update only some specific fields of a `GeoLineStrings`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `GeoLineStrings`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + line_strings: Some(SerializedComponentBatch::new( + crate::components::GeoLineString::arrow_empty(), + Self::descriptor_line_strings(), + )), + radii: Some(SerializedComponentBatch::new( + crate::components::Radius::arrow_empty(), + Self::descriptor_radii(), + )), + colors: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_colors(), + )), + } + } + + /// The line strings, expressed in [EPSG:4326](https://epsg.io/4326) coordinates (North/East-positive degrees). + #[inline] + pub fn with_line_strings( + mut self, + line_strings: impl IntoIterator>, + ) -> Self { + self.line_strings = try_serialize_field(Self::descriptor_line_strings(), line_strings); + self + } + /// Optional radii for the line strings. /// /// *Note*: scene units radiii are interpreted as meters. Currently, the display scale only considers the latitude of @@ -293,7 +285,7 @@ impl GeoLineStrings { mut self, radii: impl IntoIterator>, ) -> Self { - self.radii = Some(radii.into_iter().map(Into::into).collect()); + self.radii = try_serialize_field(Self::descriptor_radii(), radii); self } @@ -303,7 +295,7 @@ impl GeoLineStrings { mut self, colors: impl IntoIterator>, ) -> Self { - self.colors = Some(colors.into_iter().map(Into::into).collect()); + self.colors = try_serialize_field(Self::descriptor_colors(), colors); self } } @@ -315,11 +307,4 @@ impl ::re_byte_size::SizeBytes for GeoLineStrings { + self.radii.heap_size_bytes() + self.colors.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >>::is_pod() - && >>::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/geo_points.rs b/crates/store/re_types/src/archetypes/geo_points.rs index 44dfd2581e17..9f6a0f585749 100644 --- a/crates/store/re_types/src/archetypes/geo_points.rs +++ b/crates/store/re_types/src/archetypes/geo_points.rs @@ -46,23 +46,23 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct GeoPoints { /// The [EPSG:4326](https://epsg.io/4326) coordinates for the points (North/East-positive degrees). - pub positions: Vec, + pub positions: Option, /// Optional radii for the points, effectively turning them into circles. /// /// *Note*: scene units radiii are interpreted as meters. - pub radii: Option>, + pub radii: Option, /// Optional colors for the points. - pub colors: Option>, + pub colors: Option, /// Optional class Ids for the points. /// /// The [`components::ClassId`][crate::components::ClassId] provides colors if not specified explicitly. - pub class_ids: Option>, + pub class_ids: Option, } impl GeoPoints { @@ -197,54 +197,22 @@ impl ::re_types_core::Archetype for GeoPoints { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let positions = { - let array = arrays_by_descr - .get(&Self::descriptor_positions()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.GeoPoints#positions")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.GeoPoints#positions")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.GeoPoints#positions")? - }; - let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.GeoPoints#radii")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.GeoPoints#radii")? - }) - } else { - None - }; - let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.GeoPoints#colors")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.GeoPoints#colors")? - }) - } else { - None - }; - let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.GeoPoints#class_ids")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.GeoPoints#class_ids")? - }) - } else { - None - }; + let positions = arrays_by_descr + .get(&Self::descriptor_positions()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_positions()) + }); + let radii = arrays_by_descr + .get(&Self::descriptor_radii()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_radii())); + let colors = arrays_by_descr + .get(&Self::descriptor_colors()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_colors())); + let class_ids = arrays_by_descr + .get(&Self::descriptor_class_ids()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_class_ids()) + }); Ok(Self { positions, radii, @@ -255,41 +223,15 @@ impl ::re_types_core::Archetype for GeoPoints { } impl ::re_types_core::AsComponents for GeoPoints { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.positions as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_positions()), - } - }), - (self - .radii - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_radii()), - }), - (self - .colors - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_colors()), - }), - (self - .class_ids - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_class_ids()), - }), + Self::indicator().serialized(), + self.positions.clone(), + self.radii.clone(), + self.colors.clone(), + self.class_ids.clone(), ] .into_iter() .flatten() @@ -306,13 +248,53 @@ impl GeoPoints { positions: impl IntoIterator>, ) -> Self { Self { - positions: positions.into_iter().map(Into::into).collect(), + positions: try_serialize_field(Self::descriptor_positions(), positions), radii: None, colors: None, class_ids: None, } } + /// Update only some specific fields of a `GeoPoints`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `GeoPoints`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + positions: Some(SerializedComponentBatch::new( + crate::components::LatLon::arrow_empty(), + Self::descriptor_positions(), + )), + radii: Some(SerializedComponentBatch::new( + crate::components::Radius::arrow_empty(), + Self::descriptor_radii(), + )), + colors: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_colors(), + )), + class_ids: Some(SerializedComponentBatch::new( + crate::components::ClassId::arrow_empty(), + Self::descriptor_class_ids(), + )), + } + } + + /// The [EPSG:4326](https://epsg.io/4326) coordinates for the points (North/East-positive degrees). + #[inline] + pub fn with_positions( + mut self, + positions: impl IntoIterator>, + ) -> Self { + self.positions = try_serialize_field(Self::descriptor_positions(), positions); + self + } + /// Optional radii for the points, effectively turning them into circles. /// /// *Note*: scene units radiii are interpreted as meters. @@ -321,7 +303,7 @@ impl GeoPoints { mut self, radii: impl IntoIterator>, ) -> Self { - self.radii = Some(radii.into_iter().map(Into::into).collect()); + self.radii = try_serialize_field(Self::descriptor_radii(), radii); self } @@ -331,7 +313,7 @@ impl GeoPoints { mut self, colors: impl IntoIterator>, ) -> Self { - self.colors = Some(colors.into_iter().map(Into::into).collect()); + self.colors = try_serialize_field(Self::descriptor_colors(), colors); self } @@ -343,7 +325,7 @@ impl GeoPoints { mut self, class_ids: impl IntoIterator>, ) -> Self { - self.class_ids = Some(class_ids.into_iter().map(Into::into).collect()); + self.class_ids = try_serialize_field(Self::descriptor_class_ids(), class_ids); self } } @@ -356,12 +338,4 @@ impl ::re_byte_size::SizeBytes for GeoPoints { + self.colors.heap_size_bytes() + self.class_ids.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/graph_edges.rs b/crates/store/re_types/src/archetypes/graph_edges.rs index a3b74d6e0c45..7ebf59ec2f30 100644 --- a/crates/store/re_types/src/archetypes/graph_edges.rs +++ b/crates/store/re_types/src/archetypes/graph_edges.rs @@ -51,15 +51,15 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct GraphEdges { /// A list of node tuples. - pub edges: Vec, + pub edges: Option, /// Specifies if the graph is directed or undirected. /// /// If no [`components::GraphType`][crate::components::GraphType] is provided, the graph is assumed to be undirected. - pub graph_type: Option, + pub graph_type: Option, } impl GraphEdges { @@ -171,51 +171,26 @@ impl ::re_types_core::Archetype for GraphEdges { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let edges = { - let array = arrays_by_descr - .get(&Self::descriptor_edges()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.GraphEdges#edges")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.GraphEdges#edges")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.GraphEdges#edges")? - }; - let graph_type = if let Some(array) = arrays_by_descr.get(&Self::descriptor_graph_type()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.GraphEdges#graph_type")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let edges = arrays_by_descr + .get(&Self::descriptor_edges()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_edges())); + let graph_type = arrays_by_descr + .get(&Self::descriptor_graph_type()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_graph_type()) + }); Ok(Self { edges, graph_type }) } } impl ::re_types_core::AsComponents for GraphEdges { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.edges as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_edges()), - } - }), - (self - .graph_type - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_graph_type()), - }), + Self::indicator().serialized(), + self.edges.clone(), + self.graph_type.clone(), ] .into_iter() .flatten() @@ -230,17 +205,49 @@ impl GraphEdges { #[inline] pub fn new(edges: impl IntoIterator>) -> Self { Self { - edges: edges.into_iter().map(Into::into).collect(), + edges: try_serialize_field(Self::descriptor_edges(), edges), graph_type: None, } } + /// Update only some specific fields of a `GraphEdges`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `GraphEdges`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + edges: Some(SerializedComponentBatch::new( + crate::components::GraphEdge::arrow_empty(), + Self::descriptor_edges(), + )), + graph_type: Some(SerializedComponentBatch::new( + crate::components::GraphType::arrow_empty(), + Self::descriptor_graph_type(), + )), + } + } + + /// A list of node tuples. + #[inline] + pub fn with_edges( + mut self, + edges: impl IntoIterator>, + ) -> Self { + self.edges = try_serialize_field(Self::descriptor_edges(), edges); + self + } + /// Specifies if the graph is directed or undirected. /// /// If no [`components::GraphType`][crate::components::GraphType] is provided, the graph is assumed to be undirected. #[inline] pub fn with_graph_type(mut self, graph_type: impl Into) -> Self { - self.graph_type = Some(graph_type.into()); + self.graph_type = try_serialize_field(Self::descriptor_graph_type(), [graph_type]); self } } @@ -250,10 +257,4 @@ impl ::re_byte_size::SizeBytes for GraphEdges { fn heap_size_bytes(&self) -> u64 { self.edges.heap_size_bytes() + self.graph_type.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/graph_edges_ext.rs b/crates/store/re_types/src/archetypes/graph_edges_ext.rs index 9e97e0797882..f77ef05d3ada 100644 --- a/crates/store/re_types/src/archetypes/graph_edges_ext.rs +++ b/crates/store/re_types/src/archetypes/graph_edges_ext.rs @@ -3,15 +3,13 @@ use super::GraphEdges; impl GraphEdges { /// Creates a graph with undirected edges. #[inline(always)] - pub fn with_undirected_edges(mut self) -> Self { - self.graph_type = Some(crate::components::GraphType::Undirected); - self + pub fn with_undirected_edges(self) -> Self { + self.with_graph_type(crate::components::GraphType::Undirected) } /// Creates a graph with directed edges. #[inline(always)] - pub fn with_directed_edges(mut self) -> Self { - self.graph_type = Some(crate::components::GraphType::Directed); - self + pub fn with_directed_edges(self) -> Self { + self.with_graph_type(crate::components::GraphType::Directed) } } diff --git a/crates/store/re_types/src/archetypes/graph_nodes.rs b/crates/store/re_types/src/archetypes/graph_nodes.rs index 615538403848..59a9b48ed87e 100644 --- a/crates/store/re_types/src/archetypes/graph_nodes.rs +++ b/crates/store/re_types/src/archetypes/graph_nodes.rs @@ -49,25 +49,25 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct GraphNodes { /// A list of node IDs. - pub node_ids: Vec, + pub node_ids: Option, /// Optional center positions of the nodes. - pub positions: Option>, + pub positions: Option, /// Optional colors for the boxes. - pub colors: Option>, + pub colors: Option, /// Optional text labels for the node. - pub labels: Option>, + pub labels: Option, /// Optional choice of whether the text labels should be shown by default. - pub show_labels: Option, + pub show_labels: Option, /// Optional radii for nodes. - pub radii: Option>, + pub radii: Option, } impl GraphNodes { @@ -226,76 +226,28 @@ impl ::re_types_core::Archetype for GraphNodes { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let node_ids = { - let array = arrays_by_descr - .get(&Self::descriptor_node_ids()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.GraphNodes#node_ids")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.GraphNodes#node_ids")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.GraphNodes#node_ids")? - }; - let positions = if let Some(array) = arrays_by_descr.get(&Self::descriptor_positions()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.GraphNodes#positions")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.GraphNodes#positions")? - }) - } else { - None - }; - let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.GraphNodes#colors")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.GraphNodes#colors")? - }) - } else { - None - }; - let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.GraphNodes#labels")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.GraphNodes#labels")? - }) - } else { - None - }; - let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.GraphNodes#show_labels")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.GraphNodes#radii")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.GraphNodes#radii")? - }) - } else { - None - }; + let node_ids = arrays_by_descr + .get(&Self::descriptor_node_ids()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_node_ids())); + let positions = arrays_by_descr + .get(&Self::descriptor_positions()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_positions()) + }); + let colors = arrays_by_descr + .get(&Self::descriptor_colors()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_colors())); + let labels = arrays_by_descr + .get(&Self::descriptor_labels()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_labels())); + let show_labels = arrays_by_descr + .get(&Self::descriptor_show_labels()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_show_labels()) + }); + let radii = arrays_by_descr + .get(&Self::descriptor_radii()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_radii())); Ok(Self { node_ids, positions, @@ -308,57 +260,17 @@ impl ::re_types_core::Archetype for GraphNodes { } impl ::re_types_core::AsComponents for GraphNodes { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.node_ids as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_node_ids()), - } - }), - (self - .positions - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_positions()), - }), - (self - .colors - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_colors()), - }), - (self - .labels - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_labels()), - }), - (self - .show_labels - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_show_labels()), - }), - (self - .radii - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_radii()), - }), + Self::indicator().serialized(), + self.node_ids.clone(), + self.positions.clone(), + self.colors.clone(), + self.labels.clone(), + self.show_labels.clone(), + self.radii.clone(), ] .into_iter() .flatten() @@ -375,7 +287,7 @@ impl GraphNodes { node_ids: impl IntoIterator>, ) -> Self { Self { - node_ids: node_ids.into_iter().map(Into::into).collect(), + node_ids: try_serialize_field(Self::descriptor_node_ids(), node_ids), positions: None, colors: None, labels: None, @@ -384,13 +296,61 @@ impl GraphNodes { } } + /// Update only some specific fields of a `GraphNodes`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `GraphNodes`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + node_ids: Some(SerializedComponentBatch::new( + crate::components::GraphNode::arrow_empty(), + Self::descriptor_node_ids(), + )), + positions: Some(SerializedComponentBatch::new( + crate::components::Position2D::arrow_empty(), + Self::descriptor_positions(), + )), + colors: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_colors(), + )), + labels: Some(SerializedComponentBatch::new( + crate::components::Text::arrow_empty(), + Self::descriptor_labels(), + )), + show_labels: Some(SerializedComponentBatch::new( + crate::components::ShowLabels::arrow_empty(), + Self::descriptor_show_labels(), + )), + radii: Some(SerializedComponentBatch::new( + crate::components::Radius::arrow_empty(), + Self::descriptor_radii(), + )), + } + } + + /// A list of node IDs. + #[inline] + pub fn with_node_ids( + mut self, + node_ids: impl IntoIterator>, + ) -> Self { + self.node_ids = try_serialize_field(Self::descriptor_node_ids(), node_ids); + self + } + /// Optional center positions of the nodes. #[inline] pub fn with_positions( mut self, positions: impl IntoIterator>, ) -> Self { - self.positions = Some(positions.into_iter().map(Into::into).collect()); + self.positions = try_serialize_field(Self::descriptor_positions(), positions); self } @@ -400,7 +360,7 @@ impl GraphNodes { mut self, colors: impl IntoIterator>, ) -> Self { - self.colors = Some(colors.into_iter().map(Into::into).collect()); + self.colors = try_serialize_field(Self::descriptor_colors(), colors); self } @@ -410,7 +370,7 @@ impl GraphNodes { mut self, labels: impl IntoIterator>, ) -> Self { - self.labels = Some(labels.into_iter().map(Into::into).collect()); + self.labels = try_serialize_field(Self::descriptor_labels(), labels); self } @@ -420,7 +380,7 @@ impl GraphNodes { mut self, show_labels: impl Into, ) -> Self { - self.show_labels = Some(show_labels.into()); + self.show_labels = try_serialize_field(Self::descriptor_show_labels(), [show_labels]); self } @@ -430,7 +390,7 @@ impl GraphNodes { mut self, radii: impl IntoIterator>, ) -> Self { - self.radii = Some(radii.into_iter().map(Into::into).collect()); + self.radii = try_serialize_field(Self::descriptor_radii(), radii); self } } @@ -445,14 +405,4 @@ impl ::re_byte_size::SizeBytes for GraphNodes { + self.show_labels.heap_size_bytes() + self.radii.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >::is_pod() - && >>::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/instance_poses3d.rs b/crates/store/re_types/src/archetypes/instance_poses3d.rs index daf9df5a9dc9..a019a9c1cc1b 100644 --- a/crates/store/re_types/src/archetypes/instance_poses3d.rs +++ b/crates/store/re_types/src/archetypes/instance_poses3d.rs @@ -90,22 +90,22 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct InstancePoses3D { /// Translation vectors. - pub translations: Option>, + pub translations: Option, /// Rotations via axis + angle. - pub rotation_axis_angles: Option>, + pub rotation_axis_angles: Option, /// Rotations via quaternion. - pub quaternions: Option>, + pub quaternions: Option, /// Scaling factors. - pub scales: Option>, + pub scales: Option, /// 3x3 transformation matrices. - pub mat3x3: Option>, + pub mat3x3: Option, } impl InstancePoses3D { @@ -253,69 +253,30 @@ impl ::re_types_core::Archetype for InstancePoses3D { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let translations = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_translations()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.InstancePoses3D#translations")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.InstancePoses3D#translations")? - }) - } else { - None - }; - let rotation_axis_angles = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_rotation_axis_angles()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.InstancePoses3D#rotation_axis_angles")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.InstancePoses3D#rotation_axis_angles")? - }) - } else { - None - }; - let quaternions = if let Some(array) = arrays_by_descr.get(&Self::descriptor_quaternions()) - { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.InstancePoses3D#quaternions")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.InstancePoses3D#quaternions")? - }) - } else { - None - }; - let scales = if let Some(array) = arrays_by_descr.get(&Self::descriptor_scales()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.InstancePoses3D#scales")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.InstancePoses3D#scales")? - }) - } else { - None - }; - let mat3x3 = if let Some(array) = arrays_by_descr.get(&Self::descriptor_mat3x3()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.InstancePoses3D#mat3x3")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.InstancePoses3D#mat3x3")? - }) - } else { - None - }; + let translations = arrays_by_descr + .get(&Self::descriptor_translations()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_translations()) + }); + let rotation_axis_angles = arrays_by_descr + .get(&Self::descriptor_rotation_axis_angles()) + .map(|array| { + SerializedComponentBatch::new( + array.clone(), + Self::descriptor_rotation_axis_angles(), + ) + }); + let quaternions = arrays_by_descr + .get(&Self::descriptor_quaternions()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_quaternions()) + }); + let scales = arrays_by_descr + .get(&Self::descriptor_scales()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_scales())); + let mat3x3 = arrays_by_descr + .get(&Self::descriptor_mat3x3()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_mat3x3())); Ok(Self { translations, rotation_axis_angles, @@ -327,51 +288,16 @@ impl ::re_types_core::Archetype for InstancePoses3D { } impl ::re_types_core::AsComponents for InstancePoses3D { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (self - .translations - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_translations()), - }), - (self - .rotation_axis_angles - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_rotation_axis_angles()), - }), - (self - .quaternions - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_quaternions()), - }), - (self - .scales - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_scales()), - }), - (self - .mat3x3 - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_mat3x3()), - }), + Self::indicator().serialized(), + self.translations.clone(), + self.rotation_axis_angles.clone(), + self.quaternions.clone(), + self.scales.clone(), + self.mat3x3.clone(), ] .into_iter() .flatten() @@ -394,13 +320,47 @@ impl InstancePoses3D { } } + /// Update only some specific fields of a `InstancePoses3D`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `InstancePoses3D`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + translations: Some(SerializedComponentBatch::new( + crate::components::PoseTranslation3D::arrow_empty(), + Self::descriptor_translations(), + )), + rotation_axis_angles: Some(SerializedComponentBatch::new( + crate::components::PoseRotationAxisAngle::arrow_empty(), + Self::descriptor_rotation_axis_angles(), + )), + quaternions: Some(SerializedComponentBatch::new( + crate::components::PoseRotationQuat::arrow_empty(), + Self::descriptor_quaternions(), + )), + scales: Some(SerializedComponentBatch::new( + crate::components::PoseScale3D::arrow_empty(), + Self::descriptor_scales(), + )), + mat3x3: Some(SerializedComponentBatch::new( + crate::components::PoseTransformMat3x3::arrow_empty(), + Self::descriptor_mat3x3(), + )), + } + } + /// Translation vectors. #[inline] pub fn with_translations( mut self, translations: impl IntoIterator>, ) -> Self { - self.translations = Some(translations.into_iter().map(Into::into).collect()); + self.translations = try_serialize_field(Self::descriptor_translations(), translations); self } @@ -412,8 +372,10 @@ impl InstancePoses3D { Item = impl Into, >, ) -> Self { - self.rotation_axis_angles = - Some(rotation_axis_angles.into_iter().map(Into::into).collect()); + self.rotation_axis_angles = try_serialize_field( + Self::descriptor_rotation_axis_angles(), + rotation_axis_angles, + ); self } @@ -423,7 +385,7 @@ impl InstancePoses3D { mut self, quaternions: impl IntoIterator>, ) -> Self { - self.quaternions = Some(quaternions.into_iter().map(Into::into).collect()); + self.quaternions = try_serialize_field(Self::descriptor_quaternions(), quaternions); self } @@ -433,7 +395,7 @@ impl InstancePoses3D { mut self, scales: impl IntoIterator>, ) -> Self { - self.scales = Some(scales.into_iter().map(Into::into).collect()); + self.scales = try_serialize_field(Self::descriptor_scales(), scales); self } @@ -443,7 +405,7 @@ impl InstancePoses3D { mut self, mat3x3: impl IntoIterator>, ) -> Self { - self.mat3x3 = Some(mat3x3.into_iter().map(Into::into).collect()); + self.mat3x3 = try_serialize_field(Self::descriptor_mat3x3(), mat3x3); self } } @@ -457,13 +419,4 @@ impl ::re_byte_size::SizeBytes for InstancePoses3D { + self.scales.heap_size_bytes() + self.mat3x3.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/points2d.rs b/crates/store/re_types/src/archetypes/points2d.rs index ff673182bf6a..54a4cf25b289 100644 --- a/crates/store/re_types/src/archetypes/points2d.rs +++ b/crates/store/re_types/src/archetypes/points2d.rs @@ -96,35 +96,35 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct Points2D { /// All the 2D positions at which the point cloud shows points. - pub positions: Vec, + pub positions: Option, /// Optional radii for the points, effectively turning them into circles. - pub radii: Option>, + pub radii: Option, /// Optional colors for the points. - pub colors: Option>, + pub colors: Option, /// Optional text labels for the points. /// /// If there's a single label present, it will be placed at the center of the entity. /// Otherwise, each instance will have its own label. - pub labels: Option>, + pub labels: Option, /// Optional choice of whether the text labels should be shown by default. - pub show_labels: Option, + pub show_labels: Option, /// An optional floating point value that specifies the 2D drawing order. /// /// Objects with higher values are drawn on top of those with lower values. - pub draw_order: Option, + pub draw_order: Option, /// Optional class Ids for the points. /// /// The [`components::ClassId`][crate::components::ClassId] provides colors and labels if not specified explicitly. - pub class_ids: Option>, + pub class_ids: Option, /// Optional keypoint IDs for the points, identifying them within a class. /// @@ -134,7 +134,7 @@ pub struct Points2D { /// with `class_id`). /// E.g. the classification might be 'Person' and the keypoints refer to joints on a /// detected skeleton. - pub keypoint_ids: Option>, + pub keypoint_ids: Option, } impl Points2D { @@ -321,98 +321,40 @@ impl ::re_types_core::Archetype for Points2D { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let positions = { - let array = arrays_by_descr - .get(&Self::descriptor_positions()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.Points2D#positions")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points2D#positions")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Points2D#positions")? - }; - let radii = if let Some(array) = arrays_by_descr.get(&Self::descriptor_radii()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points2D#radii")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Points2D#radii")? - }) - } else { - None - }; - let colors = if let Some(array) = arrays_by_descr.get(&Self::descriptor_colors()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points2D#colors")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Points2D#colors")? - }) - } else { - None - }; - let labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_labels()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points2D#labels")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Points2D#labels")? - }) - } else { - None - }; - let show_labels = if let Some(array) = arrays_by_descr.get(&Self::descriptor_show_labels()) - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points2D#show_labels")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let draw_order = if let Some(array) = arrays_by_descr.get(&Self::descriptor_draw_order()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points2D#draw_order")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let class_ids = if let Some(array) = arrays_by_descr.get(&Self::descriptor_class_ids()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points2D#class_ids")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Points2D#class_ids")? - }) - } else { - None - }; - let keypoint_ids = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_keypoint_ids()) { - Some({ - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Points2D#keypoint_ids")? - .into_iter() - .map(|v| v.ok_or_else(DeserializationError::missing_data)) - .collect::>>() - .with_context("rerun.archetypes.Points2D#keypoint_ids")? - }) - } else { - None - }; + let positions = arrays_by_descr + .get(&Self::descriptor_positions()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_positions()) + }); + let radii = arrays_by_descr + .get(&Self::descriptor_radii()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_radii())); + let colors = arrays_by_descr + .get(&Self::descriptor_colors()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_colors())); + let labels = arrays_by_descr + .get(&Self::descriptor_labels()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_labels())); + let show_labels = arrays_by_descr + .get(&Self::descriptor_show_labels()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_show_labels()) + }); + let draw_order = arrays_by_descr + .get(&Self::descriptor_draw_order()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_draw_order()) + }); + let class_ids = arrays_by_descr + .get(&Self::descriptor_class_ids()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_class_ids()) + }); + let keypoint_ids = arrays_by_descr + .get(&Self::descriptor_keypoint_ids()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_keypoint_ids()) + }); Ok(Self { positions, radii, @@ -427,73 +369,19 @@ impl ::re_types_core::Archetype for Points2D { } impl ::re_types_core::AsComponents for Points2D { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.positions as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_positions()), - } - }), - (self - .radii - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_radii()), - }), - (self - .colors - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_colors()), - }), - (self - .labels - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_labels()), - }), - (self - .show_labels - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_show_labels()), - }), - (self - .draw_order - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_draw_order()), - }), - (self - .class_ids - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_class_ids()), - }), - (self - .keypoint_ids - .as_ref() - .map(|comp_batch| (comp_batch as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_keypoint_ids()), - }), + Self::indicator().serialized(), + self.positions.clone(), + self.radii.clone(), + self.colors.clone(), + self.labels.clone(), + self.show_labels.clone(), + self.draw_order.clone(), + self.class_ids.clone(), + self.keypoint_ids.clone(), ] .into_iter() .flatten() @@ -510,7 +398,7 @@ impl Points2D { positions: impl IntoIterator>, ) -> Self { Self { - positions: positions.into_iter().map(Into::into).collect(), + positions: try_serialize_field(Self::descriptor_positions(), positions), radii: None, colors: None, labels: None, @@ -521,13 +409,69 @@ impl Points2D { } } + /// Update only some specific fields of a `Points2D`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `Points2D`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + positions: Some(SerializedComponentBatch::new( + crate::components::Position2D::arrow_empty(), + Self::descriptor_positions(), + )), + radii: Some(SerializedComponentBatch::new( + crate::components::Radius::arrow_empty(), + Self::descriptor_radii(), + )), + colors: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_colors(), + )), + labels: Some(SerializedComponentBatch::new( + crate::components::Text::arrow_empty(), + Self::descriptor_labels(), + )), + show_labels: Some(SerializedComponentBatch::new( + crate::components::ShowLabels::arrow_empty(), + Self::descriptor_show_labels(), + )), + draw_order: Some(SerializedComponentBatch::new( + crate::components::DrawOrder::arrow_empty(), + Self::descriptor_draw_order(), + )), + class_ids: Some(SerializedComponentBatch::new( + crate::components::ClassId::arrow_empty(), + Self::descriptor_class_ids(), + )), + keypoint_ids: Some(SerializedComponentBatch::new( + crate::components::KeypointId::arrow_empty(), + Self::descriptor_keypoint_ids(), + )), + } + } + + /// All the 2D positions at which the point cloud shows points. + #[inline] + pub fn with_positions( + mut self, + positions: impl IntoIterator>, + ) -> Self { + self.positions = try_serialize_field(Self::descriptor_positions(), positions); + self + } + /// Optional radii for the points, effectively turning them into circles. #[inline] pub fn with_radii( mut self, radii: impl IntoIterator>, ) -> Self { - self.radii = Some(radii.into_iter().map(Into::into).collect()); + self.radii = try_serialize_field(Self::descriptor_radii(), radii); self } @@ -537,7 +481,7 @@ impl Points2D { mut self, colors: impl IntoIterator>, ) -> Self { - self.colors = Some(colors.into_iter().map(Into::into).collect()); + self.colors = try_serialize_field(Self::descriptor_colors(), colors); self } @@ -550,7 +494,7 @@ impl Points2D { mut self, labels: impl IntoIterator>, ) -> Self { - self.labels = Some(labels.into_iter().map(Into::into).collect()); + self.labels = try_serialize_field(Self::descriptor_labels(), labels); self } @@ -560,7 +504,7 @@ impl Points2D { mut self, show_labels: impl Into, ) -> Self { - self.show_labels = Some(show_labels.into()); + self.show_labels = try_serialize_field(Self::descriptor_show_labels(), [show_labels]); self } @@ -569,7 +513,7 @@ impl Points2D { /// Objects with higher values are drawn on top of those with lower values. #[inline] pub fn with_draw_order(mut self, draw_order: impl Into) -> Self { - self.draw_order = Some(draw_order.into()); + self.draw_order = try_serialize_field(Self::descriptor_draw_order(), [draw_order]); self } @@ -581,7 +525,7 @@ impl Points2D { mut self, class_ids: impl IntoIterator>, ) -> Self { - self.class_ids = Some(class_ids.into_iter().map(Into::into).collect()); + self.class_ids = try_serialize_field(Self::descriptor_class_ids(), class_ids); self } @@ -598,7 +542,7 @@ impl Points2D { mut self, keypoint_ids: impl IntoIterator>, ) -> Self { - self.keypoint_ids = Some(keypoint_ids.into_iter().map(Into::into).collect()); + self.keypoint_ids = try_serialize_field(Self::descriptor_keypoint_ids(), keypoint_ids); self } } @@ -615,16 +559,4 @@ impl ::re_byte_size::SizeBytes for Points2D { + self.class_ids.heap_size_bytes() + self.keypoint_ids.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >>::is_pod() - && >>::is_pod() - && >>::is_pod() - && >::is_pod() - && >::is_pod() - && >>::is_pod() - && >>::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/scalar.rs b/crates/store/re_types/src/archetypes/scalar.rs index 686aa4a106ce..9653c4d40a90 100644 --- a/crates/store/re_types/src/archetypes/scalar.rs +++ b/crates/store/re_types/src/archetypes/scalar.rs @@ -53,10 +53,10 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct Scalar { /// The scalar value to log. - pub scalar: crate::components::Scalar, + pub scalar: Option, } impl Scalar { @@ -147,39 +147,21 @@ impl ::re_types_core::Archetype for Scalar { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let scalar = { - let array = arrays_by_descr - .get(&Self::descriptor_scalar()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.Scalar#scalar")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Scalar#scalar")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.Scalar#scalar")? - }; + let scalar = arrays_by_descr + .get(&Self::descriptor_scalar()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_scalar())); Ok(Self { scalar }) } } impl ::re_types_core::AsComponents for Scalar { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; - [ - Some(Self::indicator()), - (Some(&self.scalar as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_scalar()), - } - }), - ] - .into_iter() - .flatten() - .collect() + [Self::indicator().serialized(), self.scalar.clone()] + .into_iter() + .flatten() + .collect() } } @@ -190,9 +172,34 @@ impl Scalar { #[inline] pub fn new(scalar: impl Into) -> Self { Self { - scalar: scalar.into(), + scalar: try_serialize_field(Self::descriptor_scalar(), [scalar]), } } + + /// Update only some specific fields of a `Scalar`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `Scalar`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + scalar: Some(SerializedComponentBatch::new( + crate::components::Scalar::arrow_empty(), + Self::descriptor_scalar(), + )), + } + } + + /// The scalar value to log. + #[inline] + pub fn with_scalar(mut self, scalar: impl Into) -> Self { + self.scalar = try_serialize_field(Self::descriptor_scalar(), [scalar]); + self + } } impl ::re_byte_size::SizeBytes for Scalar { @@ -200,9 +207,4 @@ impl ::re_byte_size::SizeBytes for Scalar { fn heap_size_bytes(&self) -> u64 { self.scalar.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - ::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/segmentation_image.rs b/crates/store/re_types/src/archetypes/segmentation_image.rs index 45e298b84e07..d447dccf0084 100644 --- a/crates/store/re_types/src/archetypes/segmentation_image.rs +++ b/crates/store/re_types/src/archetypes/segmentation_image.rs @@ -64,23 +64,23 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct SegmentationImage { /// The raw image data. - pub buffer: crate::components::ImageBuffer, + pub buffer: Option, /// The format of the image. - pub format: crate::components::ImageFormat, + pub format: Option, /// Opacity of the image, useful for layering the segmentation image on top of another image. /// /// Defaults to 0.5 if there's any other images in the scene, otherwise 1.0. - pub opacity: Option, + pub opacity: Option, /// An optional floating point value that specifies the 2D drawing order. /// /// Objects with higher values are drawn on top of those with lower values. - pub draw_order: Option, + pub draw_order: Option, } impl SegmentationImage { @@ -219,50 +219,20 @@ impl ::re_types_core::Archetype for SegmentationImage { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let buffer = { - let array = arrays_by_descr - .get(&Self::descriptor_buffer()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.SegmentationImage#buffer")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.SegmentationImage#buffer")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.SegmentationImage#buffer")? - }; - let format = { - let array = arrays_by_descr - .get(&Self::descriptor_format()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.SegmentationImage#format")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.SegmentationImage#format")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.SegmentationImage#format")? - }; - let opacity = if let Some(array) = arrays_by_descr.get(&Self::descriptor_opacity()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.SegmentationImage#opacity")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let draw_order = if let Some(array) = arrays_by_descr.get(&Self::descriptor_draw_order()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.SegmentationImage#draw_order")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let buffer = arrays_by_descr + .get(&Self::descriptor_buffer()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_buffer())); + let format = arrays_by_descr + .get(&Self::descriptor_format()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_format())); + let opacity = arrays_by_descr + .get(&Self::descriptor_opacity()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_opacity())); + let draw_order = arrays_by_descr + .get(&Self::descriptor_draw_order()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_draw_order()) + }); Ok(Self { buffer, format, @@ -273,39 +243,15 @@ impl ::re_types_core::Archetype for SegmentationImage { } impl ::re_types_core::AsComponents for SegmentationImage { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.buffer as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_buffer()), - } - }), - (Some(&self.format as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_format()), - } - }), - (self - .opacity - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_opacity()), - }), - (self - .draw_order - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_draw_order()), - }), + Self::indicator().serialized(), + self.buffer.clone(), + self.format.clone(), + self.opacity.clone(), + self.draw_order.clone(), ] .into_iter() .flatten() @@ -323,19 +269,63 @@ impl SegmentationImage { format: impl Into, ) -> Self { Self { - buffer: buffer.into(), - format: format.into(), + buffer: try_serialize_field(Self::descriptor_buffer(), [buffer]), + format: try_serialize_field(Self::descriptor_format(), [format]), opacity: None, draw_order: None, } } + /// Update only some specific fields of a `SegmentationImage`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `SegmentationImage`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + buffer: Some(SerializedComponentBatch::new( + crate::components::ImageBuffer::arrow_empty(), + Self::descriptor_buffer(), + )), + format: Some(SerializedComponentBatch::new( + crate::components::ImageFormat::arrow_empty(), + Self::descriptor_format(), + )), + opacity: Some(SerializedComponentBatch::new( + crate::components::Opacity::arrow_empty(), + Self::descriptor_opacity(), + )), + draw_order: Some(SerializedComponentBatch::new( + crate::components::DrawOrder::arrow_empty(), + Self::descriptor_draw_order(), + )), + } + } + + /// The raw image data. + #[inline] + pub fn with_buffer(mut self, buffer: impl Into) -> Self { + self.buffer = try_serialize_field(Self::descriptor_buffer(), [buffer]); + self + } + + /// The format of the image. + #[inline] + pub fn with_format(mut self, format: impl Into) -> Self { + self.format = try_serialize_field(Self::descriptor_format(), [format]); + self + } + /// Opacity of the image, useful for layering the segmentation image on top of another image. /// /// Defaults to 0.5 if there's any other images in the scene, otherwise 1.0. #[inline] pub fn with_opacity(mut self, opacity: impl Into) -> Self { - self.opacity = Some(opacity.into()); + self.opacity = try_serialize_field(Self::descriptor_opacity(), [opacity]); self } @@ -344,7 +334,7 @@ impl SegmentationImage { /// Objects with higher values are drawn on top of those with lower values. #[inline] pub fn with_draw_order(mut self, draw_order: impl Into) -> Self { - self.draw_order = Some(draw_order.into()); + self.draw_order = try_serialize_field(Self::descriptor_draw_order(), [draw_order]); self } } @@ -357,12 +347,4 @@ impl ::re_byte_size::SizeBytes for SegmentationImage { + self.opacity.heap_size_bytes() + self.draw_order.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - ::is_pod() - && ::is_pod() - && >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/segmentation_image_ext.rs b/crates/store/re_types/src/archetypes/segmentation_image_ext.rs index a90856eb24d3..5a071c28335b 100644 --- a/crates/store/re_types/src/archetypes/segmentation_image_ext.rs +++ b/crates/store/re_types/src/archetypes/segmentation_image_ext.rs @@ -33,11 +33,6 @@ impl SegmentationImage { let image_format = ImageFormat::segmentation([width as _, height as _], datatype); - Ok(Self { - buffer: blob.into(), - format: image_format.into(), - draw_order: None, - opacity: None, - }) + Ok(Self::new(blob, image_format)) } } diff --git a/crates/store/re_types/src/archetypes/series_line.rs b/crates/store/re_types/src/archetypes/series_line.rs index d1c7ffda63b5..539b65bc09a2 100644 --- a/crates/store/re_types/src/archetypes/series_line.rs +++ b/crates/store/re_types/src/archetypes/series_line.rs @@ -69,25 +69,25 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct SeriesLine { /// Color for the corresponding series. - pub color: Option, + pub color: Option, /// Stroke width for the corresponding series. - pub width: Option, + pub width: Option, /// Display name of the series. /// /// Used in the legend. - pub name: Option, + pub name: Option, /// Configures the zoom-dependent scalar aggregation. /// /// This is done only if steps on the X axis go below a single pixel, /// i.e. a single pixel covers more than one tick worth of data. It can greatly improve performance /// (and readability) in such situations as it prevents overdraw. - pub aggregation_policy: Option, + pub aggregation_policy: Option, } impl SeriesLine { @@ -223,43 +223,20 @@ impl ::re_types_core::Archetype for SeriesLine { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let color = if let Some(array) = arrays_by_descr.get(&Self::descriptor_color()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.SeriesLine#color")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let width = if let Some(array) = arrays_by_descr.get(&Self::descriptor_width()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.SeriesLine#width")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let name = if let Some(array) = arrays_by_descr.get(&Self::descriptor_name()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.SeriesLine#name")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let aggregation_policy = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_aggregation_policy()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.SeriesLine#aggregation_policy")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let color = arrays_by_descr + .get(&Self::descriptor_color()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_color())); + let width = arrays_by_descr + .get(&Self::descriptor_width()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_width())); + let name = arrays_by_descr + .get(&Self::descriptor_name()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_name())); + let aggregation_policy = arrays_by_descr + .get(&Self::descriptor_aggregation_policy()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_aggregation_policy()) + }); Ok(Self { color, width, @@ -270,41 +247,15 @@ impl ::re_types_core::Archetype for SeriesLine { } impl ::re_types_core::AsComponents for SeriesLine { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (self - .color - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_color()), - }), - (self - .width - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_width()), - }), - (self.name.as_ref().map(|comp| (comp as &dyn ComponentBatch))).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_name()), - } - }), - (self - .aggregation_policy - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_aggregation_policy()), - }), + Self::indicator().serialized(), + self.color.clone(), + self.width.clone(), + self.name.clone(), + self.aggregation_policy.clone(), ] .into_iter() .flatten() @@ -326,17 +277,47 @@ impl SeriesLine { } } + /// Update only some specific fields of a `SeriesLine`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `SeriesLine`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + color: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_color(), + )), + width: Some(SerializedComponentBatch::new( + crate::components::StrokeWidth::arrow_empty(), + Self::descriptor_width(), + )), + name: Some(SerializedComponentBatch::new( + crate::components::Name::arrow_empty(), + Self::descriptor_name(), + )), + aggregation_policy: Some(SerializedComponentBatch::new( + crate::components::AggregationPolicy::arrow_empty(), + Self::descriptor_aggregation_policy(), + )), + } + } + /// Color for the corresponding series. #[inline] pub fn with_color(mut self, color: impl Into) -> Self { - self.color = Some(color.into()); + self.color = try_serialize_field(Self::descriptor_color(), [color]); self } /// Stroke width for the corresponding series. #[inline] pub fn with_width(mut self, width: impl Into) -> Self { - self.width = Some(width.into()); + self.width = try_serialize_field(Self::descriptor_width(), [width]); self } @@ -345,7 +326,7 @@ impl SeriesLine { /// Used in the legend. #[inline] pub fn with_name(mut self, name: impl Into) -> Self { - self.name = Some(name.into()); + self.name = try_serialize_field(Self::descriptor_name(), [name]); self } @@ -359,7 +340,8 @@ impl SeriesLine { mut self, aggregation_policy: impl Into, ) -> Self { - self.aggregation_policy = Some(aggregation_policy.into()); + self.aggregation_policy = + try_serialize_field(Self::descriptor_aggregation_policy(), [aggregation_policy]); self } } @@ -372,12 +354,4 @@ impl ::re_byte_size::SizeBytes for SeriesLine { + self.name.heap_size_bytes() + self.aggregation_policy.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/series_point.rs b/crates/store/re_types/src/archetypes/series_point.rs index 67dd7ff002e5..bc839b5c5c28 100644 --- a/crates/store/re_types/src/archetypes/series_point.rs +++ b/crates/store/re_types/src/archetypes/series_point.rs @@ -71,21 +71,21 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct SeriesPoint { /// Color for the corresponding series. - pub color: Option, + pub color: Option, /// What shape to use to represent the point - pub marker: Option, + pub marker: Option, /// Display name of the series. /// /// Used in the legend. - pub name: Option, + pub name: Option, /// Size of the marker. - pub marker_size: Option, + pub marker_size: Option, } impl SeriesPoint { @@ -221,43 +221,20 @@ impl ::re_types_core::Archetype for SeriesPoint { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let color = if let Some(array) = arrays_by_descr.get(&Self::descriptor_color()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.SeriesPoint#color")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let marker = if let Some(array) = arrays_by_descr.get(&Self::descriptor_marker()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.SeriesPoint#marker")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let name = if let Some(array) = arrays_by_descr.get(&Self::descriptor_name()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.SeriesPoint#name")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let marker_size = if let Some(array) = arrays_by_descr.get(&Self::descriptor_marker_size()) - { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.SeriesPoint#marker_size")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let color = arrays_by_descr + .get(&Self::descriptor_color()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_color())); + let marker = arrays_by_descr + .get(&Self::descriptor_marker()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_marker())); + let name = arrays_by_descr + .get(&Self::descriptor_name()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_name())); + let marker_size = arrays_by_descr + .get(&Self::descriptor_marker_size()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_marker_size()) + }); Ok(Self { color, marker, @@ -268,41 +245,15 @@ impl ::re_types_core::Archetype for SeriesPoint { } impl ::re_types_core::AsComponents for SeriesPoint { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (self - .color - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_color()), - }), - (self - .marker - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_marker()), - }), - (self.name.as_ref().map(|comp| (comp as &dyn ComponentBatch))).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_name()), - } - }), - (self - .marker_size - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_marker_size()), - }), + Self::indicator().serialized(), + self.color.clone(), + self.marker.clone(), + self.name.clone(), + self.marker_size.clone(), ] .into_iter() .flatten() @@ -324,17 +275,47 @@ impl SeriesPoint { } } + /// Update only some specific fields of a `SeriesPoint`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `SeriesPoint`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + color: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_color(), + )), + marker: Some(SerializedComponentBatch::new( + crate::components::MarkerShape::arrow_empty(), + Self::descriptor_marker(), + )), + name: Some(SerializedComponentBatch::new( + crate::components::Name::arrow_empty(), + Self::descriptor_name(), + )), + marker_size: Some(SerializedComponentBatch::new( + crate::components::MarkerSize::arrow_empty(), + Self::descriptor_marker_size(), + )), + } + } + /// Color for the corresponding series. #[inline] pub fn with_color(mut self, color: impl Into) -> Self { - self.color = Some(color.into()); + self.color = try_serialize_field(Self::descriptor_color(), [color]); self } /// What shape to use to represent the point #[inline] pub fn with_marker(mut self, marker: impl Into) -> Self { - self.marker = Some(marker.into()); + self.marker = try_serialize_field(Self::descriptor_marker(), [marker]); self } @@ -343,7 +324,7 @@ impl SeriesPoint { /// Used in the legend. #[inline] pub fn with_name(mut self, name: impl Into) -> Self { - self.name = Some(name.into()); + self.name = try_serialize_field(Self::descriptor_name(), [name]); self } @@ -353,7 +334,7 @@ impl SeriesPoint { mut self, marker_size: impl Into, ) -> Self { - self.marker_size = Some(marker_size.into()); + self.marker_size = try_serialize_field(Self::descriptor_marker_size(), [marker_size]); self } } @@ -366,12 +347,4 @@ impl ::re_byte_size::SizeBytes for SeriesPoint { + self.name.heap_size_bytes() + self.marker_size.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - >::is_pod() - && >::is_pod() - && >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/text_document.rs b/crates/store/re_types/src/archetypes/text_document.rs index e990e14407c3..e06b1347e6e5 100644 --- a/crates/store/re_types/src/archetypes/text_document.rs +++ b/crates/store/re_types/src/archetypes/text_document.rs @@ -87,10 +87,10 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct TextDocument { /// Contents of the text document. - pub text: crate::components::Text, + pub text: Option, /// The Media Type of the text. /// @@ -99,7 +99,7 @@ pub struct TextDocument { /// * `text/markdown` /// /// If omitted, `text/plain` is assumed. - pub media_type: Option, + pub media_type: Option, } impl TextDocument { @@ -206,52 +206,26 @@ impl ::re_types_core::Archetype for TextDocument { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let text = { - let array = arrays_by_descr - .get(&Self::descriptor_text()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.TextDocument#text")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.TextDocument#text")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.TextDocument#text")? - }; - let media_type = if let Some(array) = arrays_by_descr.get(&Self::descriptor_media_type()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.TextDocument#media_type")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let text = arrays_by_descr + .get(&Self::descriptor_text()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_text())); + let media_type = arrays_by_descr + .get(&Self::descriptor_media_type()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_media_type()) + }); Ok(Self { text, media_type }) } } impl ::re_types_core::AsComponents for TextDocument { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.text as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_text()), - } - }), - (self - .media_type - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_media_type()), - }), + Self::indicator().serialized(), + self.text.clone(), + self.media_type.clone(), ] .into_iter() .flatten() @@ -266,11 +240,40 @@ impl TextDocument { #[inline] pub fn new(text: impl Into) -> Self { Self { - text: text.into(), + text: try_serialize_field(Self::descriptor_text(), [text]), media_type: None, } } + /// Update only some specific fields of a `TextDocument`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `TextDocument`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + text: Some(SerializedComponentBatch::new( + crate::components::Text::arrow_empty(), + Self::descriptor_text(), + )), + media_type: Some(SerializedComponentBatch::new( + crate::components::MediaType::arrow_empty(), + Self::descriptor_media_type(), + )), + } + } + + /// Contents of the text document. + #[inline] + pub fn with_text(mut self, text: impl Into) -> Self { + self.text = try_serialize_field(Self::descriptor_text(), [text]); + self + } + /// The Media Type of the text. /// /// For instance: @@ -280,7 +283,7 @@ impl TextDocument { /// If omitted, `text/plain` is assumed. #[inline] pub fn with_media_type(mut self, media_type: impl Into) -> Self { - self.media_type = Some(media_type.into()); + self.media_type = try_serialize_field(Self::descriptor_media_type(), [media_type]); self } } @@ -290,9 +293,4 @@ impl ::re_byte_size::SizeBytes for TextDocument { fn heap_size_bytes(&self) -> u64 { self.text.heap_size_bytes() + self.media_type.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - ::is_pod() && >::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/text_document_ext.rs b/crates/store/re_types/src/archetypes/text_document_ext.rs index 891921bb9435..80bad89c7eaa 100644 --- a/crates/store/re_types/src/archetypes/text_document_ext.rs +++ b/crates/store/re_types/src/archetypes/text_document_ext.rs @@ -25,11 +25,13 @@ impl TextDocument { contents: Vec, media_type: Option>, ) -> anyhow::Result { - let media_type = media_type.map(Into::into); - let media_type = MediaType::or_guess_from_data(media_type, &contents); - Ok(Self { - text: String::from_utf8(contents)?.into(), - media_type, + let media_type = MediaType::or_guess_from_data(media_type.map(Into::into), &contents); + let result = Self::new(String::from_utf8(contents)?); + + Ok(if let Some(media_type) = media_type { + result.with_media_type(media_type) + } else { + result }) } diff --git a/crates/store/re_types/src/archetypes/text_log.rs b/crates/store/re_types/src/archetypes/text_log.rs index e417bb959b7c..1504cad37f84 100644 --- a/crates/store/re_types/src/archetypes/text_log.rs +++ b/crates/store/re_types/src/archetypes/text_log.rs @@ -58,18 +58,18 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct TextLog { /// The body of the message. - pub text: crate::components::Text, + pub text: Option, /// The verbosity level of the message. /// /// This can be used to filter the log messages in the Rerun Viewer. - pub level: Option, + pub level: Option, /// Optional color to use for the log line in the Rerun Viewer. - pub color: Option, + pub color: Option, } impl TextLog { @@ -187,69 +187,28 @@ impl ::re_types_core::Archetype for TextLog { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let text = { - let array = arrays_by_descr - .get(&Self::descriptor_text()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.TextLog#text")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.TextLog#text")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.TextLog#text")? - }; - let level = if let Some(array) = arrays_by_descr.get(&Self::descriptor_level()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.TextLog#level")? - .into_iter() - .next() - .flatten() - } else { - None - }; - let color = if let Some(array) = arrays_by_descr.get(&Self::descriptor_color()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.TextLog#color")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let text = arrays_by_descr + .get(&Self::descriptor_text()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_text())); + let level = arrays_by_descr + .get(&Self::descriptor_level()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_level())); + let color = arrays_by_descr + .get(&Self::descriptor_color()) + .map(|array| SerializedComponentBatch::new(array.clone(), Self::descriptor_color())); Ok(Self { text, level, color }) } } impl ::re_types_core::AsComponents for TextLog { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.text as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_text()), - } - }), - (self - .level - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_level()), - }), - (self - .color - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_color()), - }), + Self::indicator().serialized(), + self.text.clone(), + self.level.clone(), + self.color.clone(), ] .into_iter() .flatten() @@ -264,25 +223,58 @@ impl TextLog { #[inline] pub fn new(text: impl Into) -> Self { Self { - text: text.into(), + text: try_serialize_field(Self::descriptor_text(), [text]), level: None, color: None, } } + /// Update only some specific fields of a `TextLog`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `TextLog`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + text: Some(SerializedComponentBatch::new( + crate::components::Text::arrow_empty(), + Self::descriptor_text(), + )), + level: Some(SerializedComponentBatch::new( + crate::components::TextLogLevel::arrow_empty(), + Self::descriptor_level(), + )), + color: Some(SerializedComponentBatch::new( + crate::components::Color::arrow_empty(), + Self::descriptor_color(), + )), + } + } + + /// The body of the message. + #[inline] + pub fn with_text(mut self, text: impl Into) -> Self { + self.text = try_serialize_field(Self::descriptor_text(), [text]); + self + } + /// The verbosity level of the message. /// /// This can be used to filter the log messages in the Rerun Viewer. #[inline] pub fn with_level(mut self, level: impl Into) -> Self { - self.level = Some(level.into()); + self.level = try_serialize_field(Self::descriptor_level(), [level]); self } /// Optional color to use for the log line in the Rerun Viewer. #[inline] pub fn with_color(mut self, color: impl Into) -> Self { - self.color = Some(color.into()); + self.color = try_serialize_field(Self::descriptor_color(), [color]); self } } @@ -292,11 +284,4 @@ impl ::re_byte_size::SizeBytes for TextLog { fn heap_size_bytes(&self) -> u64 { self.text.heap_size_bytes() + self.level.heap_size_bytes() + self.color.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - ::is_pod() - && >::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/src/archetypes/video_frame_reference.rs b/crates/store/re_types/src/archetypes/video_frame_reference.rs index 45092d428a7e..c84541a5f45c 100644 --- a/crates/store/re_types/src/archetypes/video_frame_reference.rs +++ b/crates/store/re_types/src/archetypes/video_frame_reference.rs @@ -122,7 +122,7 @@ use ::re_types_core::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct VideoFrameReference { /// References the closest video frame to this timestamp. /// @@ -132,7 +132,7 @@ pub struct VideoFrameReference { /// Timestamps are relative to the start of the video, i.e. a timestamp of 0 always corresponds to the first frame. /// This is oftentimes equivalent to presentation timestamps (known as PTS), but in the presence of B-frames /// (bidirectionally predicted frames) there may be an offset on the first presentation timestamp in the video. - pub timestamp: crate::components::VideoTimestamp, + pub timestamp: Option, /// Optional reference to an entity with a [`archetypes::AssetVideo`][crate::archetypes::AssetVideo]. /// @@ -143,7 +143,7 @@ pub struct VideoFrameReference { /// For a series of video frame references, it is recommended to specify this path only once /// at the beginning of the series and then rely on latest-at query semantics to /// keep the video reference active. - pub video_reference: Option, + pub video_reference: Option, } impl VideoFrameReference { @@ -251,29 +251,16 @@ impl ::re_types_core::Archetype for VideoFrameReference { re_tracing::profile_function!(); use ::re_types_core::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let timestamp = { - let array = arrays_by_descr - .get(&Self::descriptor_timestamp()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.VideoFrameReference#timestamp")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.VideoFrameReference#timestamp")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.VideoFrameReference#timestamp")? - }; - let video_reference = - if let Some(array) = arrays_by_descr.get(&Self::descriptor_video_reference()) { - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.VideoFrameReference#video_reference")? - .into_iter() - .next() - .flatten() - } else { - None - }; + let timestamp = arrays_by_descr + .get(&Self::descriptor_timestamp()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_timestamp()) + }); + let video_reference = arrays_by_descr + .get(&Self::descriptor_video_reference()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_video_reference()) + }); Ok(Self { timestamp, video_reference, @@ -282,25 +269,13 @@ impl ::re_types_core::Archetype for VideoFrameReference { } impl ::re_types_core::AsComponents for VideoFrameReference { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use ::re_types_core::Archetype as _; [ - Some(Self::indicator()), - (Some(&self.timestamp as &dyn ComponentBatch)).map(|batch| { - ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_timestamp()), - } - }), - (self - .video_reference - .as_ref() - .map(|comp| (comp as &dyn ComponentBatch))) - .map(|batch| ::re_types_core::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_video_reference()), - }), + Self::indicator().serialized(), + self.timestamp.clone(), + self.video_reference.clone(), ] .into_iter() .flatten() @@ -315,11 +290,50 @@ impl VideoFrameReference { #[inline] pub fn new(timestamp: impl Into) -> Self { Self { - timestamp: timestamp.into(), + timestamp: try_serialize_field(Self::descriptor_timestamp(), [timestamp]), video_reference: None, } } + /// Update only some specific fields of a `VideoFrameReference`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `VideoFrameReference`. + #[inline] + pub fn clear_fields() -> Self { + use ::re_types_core::Loggable as _; + Self { + timestamp: Some(SerializedComponentBatch::new( + crate::components::VideoTimestamp::arrow_empty(), + Self::descriptor_timestamp(), + )), + video_reference: Some(SerializedComponentBatch::new( + crate::components::EntityPath::arrow_empty(), + Self::descriptor_video_reference(), + )), + } + } + + /// References the closest video frame to this timestamp. + /// + /// Note that this uses the closest video frame instead of the latest at this timestamp + /// in order to be more forgiving of rounding errors for inprecise timestamp types. + /// + /// Timestamps are relative to the start of the video, i.e. a timestamp of 0 always corresponds to the first frame. + /// This is oftentimes equivalent to presentation timestamps (known as PTS), but in the presence of B-frames + /// (bidirectionally predicted frames) there may be an offset on the first presentation timestamp in the video. + #[inline] + pub fn with_timestamp( + mut self, + timestamp: impl Into, + ) -> Self { + self.timestamp = try_serialize_field(Self::descriptor_timestamp(), [timestamp]); + self + } + /// Optional reference to an entity with a [`archetypes::AssetVideo`][crate::archetypes::AssetVideo]. /// /// If none is specified, the video is assumed to be at the same entity. @@ -334,7 +348,8 @@ impl VideoFrameReference { mut self, video_reference: impl Into, ) -> Self { - self.video_reference = Some(video_reference.into()); + self.video_reference = + try_serialize_field(Self::descriptor_video_reference(), [video_reference]); self } } @@ -344,10 +359,4 @@ impl ::re_byte_size::SizeBytes for VideoFrameReference { fn heap_size_bytes(&self) -> u64 { self.timestamp.heap_size_bytes() + self.video_reference.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - ::is_pod() - && >::is_pod() - } } diff --git a/crates/store/re_types/tests/types/arrows3d.rs b/crates/store/re_types/tests/types/arrows3d.rs index 5e838c40da6c..b8517a64f73d 100644 --- a/crates/store/re_types/tests/types/arrows3d.rs +++ b/crates/store/re_types/tests/types/arrows3d.rs @@ -1,8 +1,8 @@ use re_types::{ archetypes::Arrows3D, - components::{ClassId, Color, Position3D, Radius, Vector3D}, + components::{ClassId, Color, Position3D, Radius, ShowLabels, Text, Vector3D}, datatypes::Vec3D, - Archetype as _, AsComponents as _, + Archetype as _, AsComponents as _, ComponentBatch, }; #[test] @@ -11,28 +11,42 @@ fn roundtrip() { vectors: vec![ Vector3D(Vec3D([1.0, 2.0, 3.0])), Vector3D(Vec3D([10.0, 20.0, 30.0])), - ], - origins: Some(vec![ + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Arrows3D::descriptor_vectors())), + origins: vec![ Position3D(Vec3D([4.0, 5.0, 6.0])), // Position3D(Vec3D([40.0, 50.0, 60.0])), // - ]), - radii: Some(vec![ + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Arrows3D::descriptor_origins())), + radii: vec![ Radius::from(1.0), // Radius::from(10.0), - ]), - colors: Some(vec![ + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Arrows3D::descriptor_radii())), + colors: vec![ Color::from_unmultiplied_rgba(0xAA, 0x00, 0x00, 0xCC), // Color::from_unmultiplied_rgba(0x00, 0xBB, 0x00, 0xDD), - ]), - labels: Some(vec![ - "hello".into(), // - "friend".into(), // - ]), - class_ids: Some(vec![ + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Arrows3D::descriptor_colors())), + labels: vec![ + Text::from("hello"), // + Text::from("friend"), // + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Arrows3D::descriptor_labels())), + class_ids: vec![ ClassId::from(126), // ClassId::from(127), // - ]), - show_labels: Some(true.into()), + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Arrows3D::descriptor_class_ids())), + show_labels: ShowLabels(true.into()) + .serialized() + .map(|batch| batch.with_descriptor_override(Arrows3D::descriptor_show_labels())), }; let arch = Arrows3D::from_vectors([[1.0, 2.0, 3.0], [10.0, 20.0, 30.0]]) diff --git a/crates/store/re_types/tests/types/clear.rs b/crates/store/re_types/tests/types/clear.rs index a9a6d2084441..02eac2769d11 100644 --- a/crates/store/re_types/tests/types/clear.rs +++ b/crates/store/re_types/tests/types/clear.rs @@ -1,13 +1,17 @@ -use re_types::{archetypes::Clear, Archetype as _, AsComponents as _}; +use re_types::{archetypes::Clear, Archetype as _, AsComponents as _, ComponentBatch as _}; #[test] fn roundtrip() { let all_expected = [ Clear { - is_recursive: true.into(), - }, // + is_recursive: re_types::components::ClearIsRecursive(true.into()) + .serialized() + .map(|batch| batch.with_descriptor_override(Clear::descriptor_is_recursive())), + }, Clear { - is_recursive: false.into(), + is_recursive: re_types::components::ClearIsRecursive(false.into()) + .serialized() + .map(|batch| batch.with_descriptor_override(Clear::descriptor_is_recursive())), }, ]; diff --git a/crates/store/re_types/tests/types/depth_image.rs b/crates/store/re_types/tests/types/depth_image.rs index a7a992518d1e..869aa5afe5c3 100644 --- a/crates/store/re_types/tests/types/depth_image.rs +++ b/crates/store/re_types/tests/types/depth_image.rs @@ -1,24 +1,30 @@ use re_types::{ archetypes::DepthImage, - components::DepthMeter, - datatypes::{ChannelDatatype, ImageFormat}, - Archetype as _, AsComponents as _, + components::{DepthMeter, ImageBuffer, ImageFormat}, + datatypes::{self, ChannelDatatype}, + Archetype as _, AsComponents as _, ComponentBatch as _, }; #[test] fn depth_image_roundtrip() { - let format_expected = ImageFormat { + let format_expected = ImageFormat(datatypes::ImageFormat { width: 3, height: 2, pixel_format: None, channel_datatype: Some(ChannelDatatype::U8), color_model: None, - }; + }); let all_expected = [DepthImage { - buffer: vec![1, 2, 3, 4, 5, 6].into(), - format: format_expected.into(), - meter: Some(DepthMeter::from(1000.0)), + buffer: ImageBuffer::from(vec![1, 2, 3, 4, 5, 6]) + .serialized() + .map(|batch| batch.with_descriptor_override(DepthImage::descriptor_buffer())), + format: format_expected + .serialized() + .map(|batch| batch.with_descriptor_override(DepthImage::descriptor_format())), + meter: DepthMeter::from(1000.0) + .serialized() + .map(|batch| batch.with_descriptor_override(DepthImage::descriptor_meter())), draw_order: None, colormap: None, point_fill_ratio: None, diff --git a/crates/store/re_types/tests/types/points2d.rs b/crates/store/re_types/tests/types/points2d.rs index 4bce901cd764..4bc07b7815f1 100644 --- a/crates/store/re_types/tests/types/points2d.rs +++ b/crates/store/re_types/tests/types/points2d.rs @@ -1,4 +1,8 @@ -use re_types::{archetypes::Points2D, components, Archetype as _, AsComponents as _}; +use re_types::{ + archetypes::Points2D, + components::{self, ShowLabels}, + Archetype as _, AsComponents as _, ComponentBatch as _, +}; #[test] fn roundtrip() { @@ -6,29 +10,45 @@ fn roundtrip() { positions: vec![ components::Position2D::new(1.0, 2.0), // components::Position2D::new(3.0, 4.0), - ], - radii: Some(vec![ + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Points2D::descriptor_positions())), + radii: vec![ components::Radius::from(42.0), // components::Radius::from(43.0), - ]), - colors: Some(vec![ + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Points2D::descriptor_radii())), + colors: vec![ components::Color::from_unmultiplied_rgba(0xAA, 0x00, 0x00, 0xCC), // components::Color::from_unmultiplied_rgba(0x00, 0xBB, 0x00, 0xDD), - ]), - labels: Some(vec![ - "hello".into(), // - "friend".into(), // - ]), - draw_order: Some(components::DrawOrder(300.0.into())), - class_ids: Some(vec![ + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Points2D::descriptor_colors())), + labels: vec![ + components::Text::from("hello"), // + components::Text::from("friend"), // + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Points2D::descriptor_labels())), + draw_order: components::DrawOrder::from(300.0) + .serialized() + .map(|batch| batch.with_descriptor_override(Points2D::descriptor_draw_order())), + class_ids: vec![ components::ClassId::from(126), // components::ClassId::from(127), // - ]), - keypoint_ids: Some(vec![ + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Points2D::descriptor_class_ids())), + keypoint_ids: vec![ components::KeypointId::from(2), // components::KeypointId::from(3), // - ]), - show_labels: Some(false.into()), + ] + .serialized() + .map(|batch| batch.with_descriptor_override(Points2D::descriptor_keypoint_ids())), + show_labels: ShowLabels::from(false) + .serialized() + .map(|batch| batch.with_descriptor_override(Points2D::descriptor_show_labels())), }; let arch = Points2D::new([(1.0, 2.0), (3.0, 4.0)]) diff --git a/crates/store/re_types/tests/types/segmentation_image.rs b/crates/store/re_types/tests/types/segmentation_image.rs index d99151f01447..83124d604372 100644 --- a/crates/store/re_types/tests/types/segmentation_image.rs +++ b/crates/store/re_types/tests/types/segmentation_image.rs @@ -1,22 +1,27 @@ use re_types::{ archetypes::SegmentationImage, - datatypes::{ChannelDatatype, ImageFormat}, - Archetype as _, AsComponents as _, + components::{ImageBuffer, ImageFormat}, + datatypes::{self, ChannelDatatype}, + Archetype as _, AsComponents as _, ComponentBatch as _, }; #[test] fn segmentation_image_roundtrip() { - let format_expected = ImageFormat { + let format_expected = ImageFormat(datatypes::ImageFormat { width: 3, height: 2, pixel_format: None, channel_datatype: Some(ChannelDatatype::U8), color_model: None, - }; + }); let all_expected = [SegmentationImage { - buffer: vec![1, 2, 3, 4, 5, 6].into(), - format: format_expected.into(), + buffer: ImageBuffer::from(vec![1, 2, 3, 4, 5, 6]) + .serialized() + .map(|batch| batch.with_descriptor_override(SegmentationImage::descriptor_buffer())), + format: format_expected + .serialized() + .map(|batch| batch.with_descriptor_override(SegmentationImage::descriptor_format())), draw_order: None, opacity: None, }]; diff --git a/crates/store/re_types/tests/types/text_document.rs b/crates/store/re_types/tests/types/text_document.rs index 3c3c44a052dc..279396ca3009 100644 --- a/crates/store/re_types/tests/types/text_document.rs +++ b/crates/store/re_types/tests/types/text_document.rs @@ -1,12 +1,19 @@ use re_types::{ archetypes::TextDocument, components::MediaType, Archetype as _, AsComponents as _, + ComponentBatch as _, }; #[test] fn roundtrip() { + use re_types::components::Text; + let expected = TextDocument { - text: "This is the contents of the text document.".into(), - media_type: Some(MediaType::markdown()), + text: Text::from("This is the contents of the text document.") + .serialized() + .map(|batch| batch.with_descriptor_override(TextDocument::descriptor_text())), + media_type: MediaType::markdown() + .serialized() + .map(|batch| batch.with_descriptor_override(TextDocument::descriptor_media_type())), }; let arch = TextDocument::new("This is the contents of the text document.") diff --git a/crates/store/re_types_core/src/archetypes/clear.rs b/crates/store/re_types_core/src/archetypes/clear.rs index f380e13e1295..2c0223e8506a 100644 --- a/crates/store/re_types_core/src/archetypes/clear.rs +++ b/crates/store/re_types_core/src/archetypes/clear.rs @@ -73,9 +73,9 @@ use crate::{DeserializationError, DeserializationResult}; /// /// /// -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Default)] pub struct Clear { - pub is_recursive: crate::components::ClearIsRecursive, + pub is_recursive: Option, } impl Clear { @@ -171,39 +171,23 @@ impl crate::Archetype for Clear { re_tracing::profile_function!(); use crate::{Loggable as _, ResultExt as _}; let arrays_by_descr: ::nohash_hasher::IntMap<_, _> = arrow_data.into_iter().collect(); - let is_recursive = { - let array = arrays_by_descr - .get(&Self::descriptor_is_recursive()) - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.Clear#is_recursive")?; - ::from_arrow_opt(&**array) - .with_context("rerun.archetypes.Clear#is_recursive")? - .into_iter() - .next() - .flatten() - .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.archetypes.Clear#is_recursive")? - }; + let is_recursive = arrays_by_descr + .get(&Self::descriptor_is_recursive()) + .map(|array| { + SerializedComponentBatch::new(array.clone(), Self::descriptor_is_recursive()) + }); Ok(Self { is_recursive }) } } impl crate::AsComponents for Clear { - fn as_component_batches(&self) -> Vec> { - re_tracing::profile_function!(); + #[inline] + fn as_serialized_batches(&self) -> Vec { use crate::Archetype as _; - [ - Some(Self::indicator()), - (Some(&self.is_recursive as &dyn ComponentBatch)).map(|batch| { - crate::ComponentBatchCowWithDescriptor { - batch: batch.into(), - descriptor_override: Some(Self::descriptor_is_recursive()), - } - }), - ] - .into_iter() - .flatten() - .collect() + [Self::indicator().serialized(), self.is_recursive.clone()] + .into_iter() + .flatten() + .collect() } } @@ -214,9 +198,36 @@ impl Clear { #[inline] pub fn new(is_recursive: impl Into) -> Self { Self { - is_recursive: is_recursive.into(), + is_recursive: try_serialize_field(Self::descriptor_is_recursive(), [is_recursive]), + } + } + + /// Update only some specific fields of a `Clear`. + #[inline] + pub fn update_fields() -> Self { + Self::default() + } + + /// Clear all the fields of a `Clear`. + #[inline] + pub fn clear_fields() -> Self { + use crate::Loggable as _; + Self { + is_recursive: Some(SerializedComponentBatch::new( + crate::components::ClearIsRecursive::arrow_empty(), + Self::descriptor_is_recursive(), + )), } } + + #[inline] + pub fn with_is_recursive( + mut self, + is_recursive: impl Into, + ) -> Self { + self.is_recursive = try_serialize_field(Self::descriptor_is_recursive(), [is_recursive]); + self + } } impl ::re_byte_size::SizeBytes for Clear { @@ -224,9 +235,4 @@ impl ::re_byte_size::SizeBytes for Clear { fn heap_size_bytes(&self) -> u64 { self.is_recursive.heap_size_bytes() } - - #[inline] - fn is_pod() -> bool { - ::is_pod() - } } diff --git a/crates/store/re_types_core/src/lib.rs b/crates/store/re_types_core/src/lib.rs index d8e4e38d104d..620fd06eb3a1 100644 --- a/crates/store/re_types_core/src/lib.rs +++ b/crates/store/re_types_core/src/lib.rs @@ -98,8 +98,7 @@ pub mod external { /// Useful macro for statically asserting that a `struct` contains some specific fields. /// -/// In particular, this is useful to statcially check that an archetype -/// has a specific component. +/// For asserting that an archetype has a specific component use `re_log_types::debug_assert_archetype_has_components` /// /// ``` /// # #[macro_use] extern crate re_types_core; diff --git a/crates/viewer/re_data_ui/src/instance_path.rs b/crates/viewer/re_data_ui/src/instance_path.rs index 2184700e4c1b..dc52f05b96c0 100644 --- a/crates/viewer/re_data_ui/src/instance_path.rs +++ b/crates/viewer/re_data_ui/src/instance_path.rs @@ -3,7 +3,7 @@ use nohash_hasher::IntMap; use re_chunk_store::UnitChunkShared; use re_entity_db::InstancePath; -use re_log_types::ComponentPath; +use re_log_types::{debug_assert_archetype_has_components, ComponentPath}; use re_types::{ archetypes, components, datatypes::{ChannelDatatype, ColorModel}, @@ -278,12 +278,12 @@ fn preview_if_image_ui( buffer: components::ImageBuffer, format: components::ImageFormat ); - static_assert_struct_has_fields!( + debug_assert_archetype_has_components!( archetypes::DepthImage, buffer: components::ImageBuffer, format: components::ImageFormat ); - static_assert_struct_has_fields!( + debug_assert_archetype_has_components!( archetypes::SegmentationImage, buffer: components::ImageBuffer, format: components::ImageFormat diff --git a/crates/viewer/re_view_spatial/src/lib.rs b/crates/viewer/re_view_spatial/src/lib.rs index 1ce80145f306..cd0733894119 100644 --- a/crates/viewer/re_view_spatial/src/lib.rs +++ b/crates/viewer/re_view_spatial/src/lib.rs @@ -40,6 +40,7 @@ pub(crate) use pickable_textured_rect::{PickableRectSourceData, PickableTextured use re_view::DataResultQuery as _; use re_viewer_context::{ImageDecodeCache, ViewContext, ViewerContext}; +use re_log_types::debug_assert_archetype_has_components; use re_renderer::RenderContext; use re_types::{ archetypes, @@ -64,7 +65,7 @@ fn resolution_of_image_at( ) -> Option { // First check assumptions: static_assert_struct_has_fields!(archetypes::Image, format: components::ImageFormat); - static_assert_struct_has_fields!(archetypes::EncodedImage, blob: components::Blob); + debug_assert_archetype_has_components!(archetypes::EncodedImage, blob: components::Blob); let db = ctx.recording();