diff --git a/Cargo.lock b/Cargo.lock index 1739cbcc7bf1..ca86c1a56a4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4777,7 +4777,6 @@ dependencies = [ "ahash 0.8.3", "anyhow", "arrow2", - "arrow2_convert", "bytemuck", "cfg-if", "eframe", diff --git a/crates/re_arrow_store/Cargo.toml b/crates/re_arrow_store/Cargo.toml index bbe2166620b4..2a2a251d4f0c 100644 --- a/crates/re_arrow_store/Cargo.toml +++ b/crates/re_arrow_store/Cargo.toml @@ -123,11 +123,6 @@ name = "arrow2" harness = false required-features = ["testing"] -[[bench]] -name = "arrow2_convert" -harness = false -required-features = ["testing"] - [[bench]] name = "vectors" harness = false diff --git a/crates/re_arrow_store/benches/arrow2_convert.rs b/crates/re_arrow_store/benches/arrow2_convert.rs deleted file mode 100644 index b04db52b8b51..000000000000 --- a/crates/re_arrow_store/benches/arrow2_convert.rs +++ /dev/null @@ -1,145 +0,0 @@ -//! Keeping track of performance issues/regressions in `arrow2_convert` that directly affect us. - -#[global_allocator] -static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; - -use arrow2::{array::PrimitiveArray, datatypes::PhysicalType, types::PrimitiveType}; -use criterion::{criterion_group, Criterion}; -use re_log_types::DataCell; -use re_types::{components::InstanceKey, Loggable as _}; - -// --- - -criterion_group!(benches, serialize, deserialize); - -#[cfg(not(feature = "core_benchmarks_only"))] -criterion::criterion_main!(benches); - -// Don't run these benchmarks on CI: they measure the performance of third-party libraries. -#[cfg(feature = "core_benchmarks_only")] -fn main() {} - -// --- - -#[cfg(not(debug_assertions))] -const NUM_INSTANCES: usize = 100_000; - -// `cargo test` also runs the benchmark setup code, so make sure they run quickly: -#[cfg(debug_assertions)] -const NUM_INSTANCES: usize = 1; - -// --- - -fn serialize(c: &mut Criterion) { - let mut group = c.benchmark_group(format!( - "arrow2_convert/serialize/primitive/instances={NUM_INSTANCES}" - )); - group.throughput(criterion::Throughput::Elements(NUM_INSTANCES as _)); - - { - group.bench_function("arrow2_convert", |b| { - b.iter(|| { - let cell = DataCell::from_component::(0..NUM_INSTANCES as u64); - assert_eq!(NUM_INSTANCES as u32, cell.num_instances()); - assert_eq!( - cell.datatype().to_physical_type(), - PhysicalType::Primitive(PrimitiveType::UInt64) - ); - cell - }); - }); - } - - { - group.bench_function("arrow2/from_values", |b| { - b.iter(|| { - let values = PrimitiveArray::from_values(0..NUM_INSTANCES as u64).boxed(); - let cell = crate::DataCell::from_arrow(InstanceKey::name(), values); - assert_eq!(NUM_INSTANCES as u32, cell.num_instances()); - assert_eq!( - cell.datatype().to_physical_type(), - PhysicalType::Primitive(PrimitiveType::UInt64) - ); - cell - }); - }); - } - - { - group.bench_function("arrow2/from_vec", |b| { - b.iter(|| { - // NOTE: We do the `collect()` here on purpose! - // - // All of these APIs have to allocate an array under the hood, except `from_vec` - // which is O(1) (it just unsafely reuses the vec's data pointer). - // We need to measure the collection in order to have a leveled playing field. - let values = PrimitiveArray::from_vec((0..NUM_INSTANCES as u64).collect()).boxed(); - let cell = crate::DataCell::from_arrow(InstanceKey::name(), values); - assert_eq!(NUM_INSTANCES as u32, cell.num_instances()); - assert_eq!( - cell.datatype().to_physical_type(), - PhysicalType::Primitive(PrimitiveType::UInt64) - ); - cell - }); - }); - } -} - -fn deserialize(c: &mut Criterion) { - let mut group = c.benchmark_group(format!( - "arrow2_convert/deserialize/primitive/instances={NUM_INSTANCES}" - )); - group.throughput(criterion::Throughput::Elements(NUM_INSTANCES as _)); - - let cell = DataCell::from_component::(0..NUM_INSTANCES as u64); - let data = cell.to_arrow(); - - { - group.bench_function("arrow2_convert", |b| { - b.iter(|| { - let keys: Vec = InstanceKey::from_arrow(data.as_ref()).unwrap(); - assert_eq!(NUM_INSTANCES, keys.len()); - assert_eq!( - InstanceKey(NUM_INSTANCES as u64 / 2), - keys[NUM_INSTANCES / 2] - ); - keys - }); - }); - } - - { - group.bench_function("arrow2/validity_checks", |b| { - b.iter(|| { - let data = data.as_any().downcast_ref::>().unwrap(); - let keys: Vec = data - .into_iter() - .filter_map(|v| v.copied().map(InstanceKey)) - .collect(); - assert_eq!(NUM_INSTANCES, keys.len()); - assert_eq!( - InstanceKey(NUM_INSTANCES as u64 / 2), - keys[NUM_INSTANCES / 2] - ); - keys - }); - }); - } - - { - group.bench_function("arrow2/validity_bypass", |b| { - b.iter(|| { - let data = data.as_any().downcast_ref::>().unwrap(); - assert!(data.validity().is_none()); - let keys: Vec = data.values_iter().copied().map(InstanceKey).collect(); - assert_eq!(NUM_INSTANCES, keys.len()); - assert_eq!( - InstanceKey(NUM_INSTANCES as u64 / 2), - keys[NUM_INSTANCES / 2] - ); - keys - }); - }); - } -} diff --git a/crates/re_types/.gitattributes b/crates/re_types/.gitattributes index d0ecc4487f58..184fa46b078d 100644 --- a/crates/re_types/.gitattributes +++ b/crates/re_types/.gitattributes @@ -25,6 +25,9 @@ src/archetypes/text_log.rs linguist-generated=true src/archetypes/time_series_scalar.rs linguist-generated=true src/archetypes/transform3d.rs linguist-generated=true src/archetypes/view_coordinates.rs linguist-generated=true +src/blueprint/auto_space_views.rs linguist-generated=true +src/blueprint/mod.rs linguist-generated=true +src/blueprint/panel_view.rs linguist-generated=true src/components/annotation_context.rs linguist-generated=true src/components/blob.rs linguist-generated=true src/components/class_id.rs linguist-generated=true @@ -94,6 +97,7 @@ src/testing/archetypes/affix_fuzzer2.rs linguist-generated=true src/testing/archetypes/affix_fuzzer3.rs linguist-generated=true src/testing/archetypes/affix_fuzzer4.rs linguist-generated=true src/testing/archetypes/mod.rs linguist-generated=true +src/testing/blueprint/mod.rs linguist-generated=true src/testing/components/affix_fuzzer1.rs linguist-generated=true src/testing/components/affix_fuzzer10.rs linguist-generated=true src/testing/components/affix_fuzzer11.rs linguist-generated=true diff --git a/crates/re_types/definitions/rerun/archetypes.fbs b/crates/re_types/definitions/rerun/archetypes.fbs index 26d9eabbe275..f7b93625105b 100644 --- a/crates/re_types/definitions/rerun/archetypes.fbs +++ b/crates/re_types/definitions/rerun/archetypes.fbs @@ -24,4 +24,8 @@ include "./archetypes/view_coordinates.fbs"; include "./testing/archetypes/fuzzy.fbs"; +// NOTE: The current file is the entrypoint for codegen, and so we need to import +// the blueprint types here otherwise nothing will. +include "./blueprint.fbs"; + namespace rerun.archetypes; diff --git a/crates/re_types/definitions/rerun/blueprint.fbs b/crates/re_types/definitions/rerun/blueprint.fbs new file mode 100644 index 000000000000..ab514b28f2e0 --- /dev/null +++ b/crates/re_types/definitions/rerun/blueprint.fbs @@ -0,0 +1,2 @@ +include "./blueprint/auto_space_views.fbs"; +include "./blueprint/panel_view.fbs"; diff --git a/crates/re_types/definitions/rerun/blueprint/auto_space_views.fbs b/crates/re_types/definitions/rerun/blueprint/auto_space_views.fbs new file mode 100644 index 000000000000..26d11aaac803 --- /dev/null +++ b/crates/re_types/definitions/rerun/blueprint/auto_space_views.fbs @@ -0,0 +1,22 @@ +include "arrow/attributes.fbs"; +include "python/attributes.fbs"; +include "rust/attributes.fbs"; + +include "rerun/datatypes.fbs"; +include "rerun/attributes.fbs"; + +namespace rerun.blueprint; + +// --- + +/// A flag indicating space views should be automatically populated. +/// +/// Unstable. Used for the ongoing blueprint experimentations. +struct AutoSpaceViews ( + "attr.arrow.transparent", + "attr.rust.derive": "Copy, Default", + "attr.rust.repr": "transparent", + "attr.rust.tuple_struct" +) { + enabled: bool (order: 100); +} diff --git a/crates/re_types/definitions/rerun/blueprint/panel_view.fbs b/crates/re_types/definitions/rerun/blueprint/panel_view.fbs new file mode 100644 index 000000000000..f6e168cf8469 --- /dev/null +++ b/crates/re_types/definitions/rerun/blueprint/panel_view.fbs @@ -0,0 +1,19 @@ +include "arrow/attributes.fbs"; +include "python/attributes.fbs"; +include "rust/attributes.fbs"; + +include "rerun/datatypes.fbs"; +include "rerun/attributes.fbs"; + +namespace rerun.blueprint; + +// --- + +/// The state of the panels. +/// +/// Unstable. Used for the ongoing blueprint experimentations. +struct PanelView ( + "attr.rust.derive": "Copy" +) { + is_expanded: bool (order: 100); +} diff --git a/crates/re_types/src/blueprint/auto_space_views.rs b/crates/re_types/src/blueprint/auto_space_views.rs new file mode 100644 index 000000000000..58d70dde0d81 --- /dev/null +++ b/crates/re_types/src/blueprint/auto_space_views.rs @@ -0,0 +1,129 @@ +// DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/rust/api.rs +// Based on "crates/re_types/definitions/rerun/blueprint/auto_space_views.fbs". + +#![allow(trivial_numeric_casts)] +#![allow(unused_parens)] +#![allow(clippy::clone_on_copy)] +#![allow(clippy::iter_on_single_items)] +#![allow(clippy::map_flatten)] +#![allow(clippy::match_wildcard_for_single_variants)] +#![allow(clippy::needless_question_mark)] +#![allow(clippy::new_without_default)] +#![allow(clippy::redundant_closure)] +#![allow(clippy::too_many_arguments)] +#![allow(clippy::too_many_lines)] +#![allow(clippy::unnecessary_cast)] + +/// **Blueprint**: A flag indicating space views should be automatically populated. +/// +/// Unstable. Used for the ongoing blueprint experimentations. +#[derive(Clone, Debug, Copy, Default)] +#[repr(transparent)] +pub struct AutoSpaceViews(pub bool); + +impl From for AutoSpaceViews { + #[inline] + fn from(enabled: bool) -> Self { + Self(enabled) + } +} + +impl From for bool { + #[inline] + fn from(value: AutoSpaceViews) -> Self { + value.0 + } +} + +impl<'a> From for ::std::borrow::Cow<'a, AutoSpaceViews> { + #[inline] + fn from(value: AutoSpaceViews) -> Self { + std::borrow::Cow::Owned(value) + } +} + +impl<'a> From<&'a AutoSpaceViews> for ::std::borrow::Cow<'a, AutoSpaceViews> { + #[inline] + fn from(value: &'a AutoSpaceViews) -> Self { + std::borrow::Cow::Borrowed(value) + } +} + +impl crate::Loggable for AutoSpaceViews { + type Name = crate::ComponentName; + + #[inline] + fn name() -> Self::Name { + "rerun.blueprint.AutoSpaceViews".into() + } + + #[allow(unused_imports, clippy::wildcard_imports)] + #[inline] + fn arrow_datatype() -> arrow2::datatypes::DataType { + use ::arrow2::datatypes::*; + DataType::Boolean + } + + #[allow(unused_imports, clippy::wildcard_imports)] + fn to_arrow_opt<'a>( + data: impl IntoIterator>>>, + ) -> crate::SerializationResult> + where + Self: Clone + 'a, + { + re_tracing::profile_function!(); + use crate::{Loggable as _, ResultExt as _}; + use ::arrow2::{array::*, datatypes::*}; + Ok({ + let (somes, data0): (Vec<_>, Vec<_>) = data + .into_iter() + .map(|datum| { + let datum: Option<::std::borrow::Cow<'a, Self>> = datum.map(Into::into); + let datum = datum.map(|datum| { + let Self(data0) = datum.into_owned(); + data0 + }); + (datum.is_some(), datum) + }) + .unzip(); + let data0_bitmap: Option<::arrow2::bitmap::Bitmap> = { + let any_nones = somes.iter().any(|some| !*some); + any_nones.then(|| somes.into()) + }; + BooleanArray::new( + Self::arrow_datatype(), + data0.into_iter().map(|v| v.unwrap_or_default()).collect(), + data0_bitmap, + ) + .boxed() + }) + } + + #[allow(unused_imports, clippy::wildcard_imports)] + fn from_arrow_opt( + arrow_data: &dyn ::arrow2::array::Array, + ) -> crate::DeserializationResult>> + where + Self: Sized, + { + re_tracing::profile_function!(); + use crate::{Loggable as _, ResultExt as _}; + use ::arrow2::{array::*, buffer::*, datatypes::*}; + Ok(arrow_data + .as_any() + .downcast_ref::() + .ok_or_else(|| { + crate::DeserializationError::datatype_mismatch( + DataType::Boolean, + arrow_data.data_type().clone(), + ) + }) + .with_context("rerun.blueprint.AutoSpaceViews#enabled")? + .into_iter() + .map(|v| v.ok_or_else(crate::DeserializationError::missing_data)) + .map(|res| res.map(|v| Some(Self(v)))) + .collect::>>>() + .with_context("rerun.blueprint.AutoSpaceViews#enabled") + .with_context("rerun.blueprint.AutoSpaceViews")?) + } +} diff --git a/crates/re_types/src/blueprint/mod.rs b/crates/re_types/src/blueprint/mod.rs new file mode 100644 index 000000000000..d0c8b63510c9 --- /dev/null +++ b/crates/re_types/src/blueprint/mod.rs @@ -0,0 +1,8 @@ +// DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/rust/api.rs + +mod auto_space_views; +mod panel_view; +mod panel_view_ext; + +pub use self::auto_space_views::AutoSpaceViews; +pub use self::panel_view::PanelView; diff --git a/crates/re_types/src/blueprint/panel_view.rs b/crates/re_types/src/blueprint/panel_view.rs new file mode 100644 index 000000000000..97394f78e0b6 --- /dev/null +++ b/crates/re_types/src/blueprint/panel_view.rs @@ -0,0 +1,204 @@ +// DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/rust/api.rs +// Based on "crates/re_types/definitions/rerun/blueprint/panel_view.fbs". + +#![allow(trivial_numeric_casts)] +#![allow(unused_parens)] +#![allow(clippy::clone_on_copy)] +#![allow(clippy::iter_on_single_items)] +#![allow(clippy::map_flatten)] +#![allow(clippy::match_wildcard_for_single_variants)] +#![allow(clippy::needless_question_mark)] +#![allow(clippy::new_without_default)] +#![allow(clippy::redundant_closure)] +#![allow(clippy::too_many_arguments)] +#![allow(clippy::too_many_lines)] +#![allow(clippy::unnecessary_cast)] + +/// **Blueprint**: The state of the panels. +/// +/// Unstable. Used for the ongoing blueprint experimentations. +#[derive(Clone, Debug, Copy)] +pub struct PanelView { + pub is_expanded: bool, +} + +impl From for PanelView { + #[inline] + fn from(is_expanded: bool) -> Self { + Self { is_expanded } + } +} + +impl From for bool { + #[inline] + fn from(value: PanelView) -> Self { + value.is_expanded + } +} + +impl<'a> From for ::std::borrow::Cow<'a, PanelView> { + #[inline] + fn from(value: PanelView) -> Self { + std::borrow::Cow::Owned(value) + } +} + +impl<'a> From<&'a PanelView> for ::std::borrow::Cow<'a, PanelView> { + #[inline] + fn from(value: &'a PanelView) -> Self { + std::borrow::Cow::Borrowed(value) + } +} + +impl crate::Loggable for PanelView { + type Name = crate::ComponentName; + + #[inline] + fn name() -> Self::Name { + "rerun.blueprint.PanelView".into() + } + + #[allow(unused_imports, clippy::wildcard_imports)] + #[inline] + fn arrow_datatype() -> arrow2::datatypes::DataType { + use ::arrow2::datatypes::*; + DataType::Struct(vec![Field { + name: "is_expanded".to_owned(), + data_type: DataType::Boolean, + is_nullable: false, + metadata: [].into(), + }]) + } + + #[allow(unused_imports, clippy::wildcard_imports)] + fn to_arrow_opt<'a>( + data: impl IntoIterator>>>, + ) -> crate::SerializationResult> + where + Self: Clone + 'a, + { + re_tracing::profile_function!(); + use crate::{Loggable as _, ResultExt as _}; + use ::arrow2::{array::*, datatypes::*}; + Ok({ + let (somes, data): (Vec<_>, Vec<_>) = data + .into_iter() + .map(|datum| { + let datum: Option<::std::borrow::Cow<'a, Self>> = datum.map(Into::into); + (datum.is_some(), datum) + }) + .unzip(); + let bitmap: Option<::arrow2::bitmap::Bitmap> = { + let any_nones = somes.iter().any(|some| !*some); + any_nones.then(|| somes.into()) + }; + StructArray::new( + ::arrow_datatype(), + vec![{ + let (somes, is_expanded): (Vec<_>, Vec<_>) = data + .iter() + .map(|datum| { + let datum = datum.as_ref().map(|datum| { + let Self { is_expanded, .. } = &**datum; + is_expanded.clone() + }); + (datum.is_some(), datum) + }) + .unzip(); + let is_expanded_bitmap: Option<::arrow2::bitmap::Bitmap> = { + let any_nones = somes.iter().any(|some| !*some); + any_nones.then(|| somes.into()) + }; + BooleanArray::new( + DataType::Boolean, + is_expanded + .into_iter() + .map(|v| v.unwrap_or_default()) + .collect(), + is_expanded_bitmap, + ) + .boxed() + }], + bitmap, + ) + .boxed() + }) + } + + #[allow(unused_imports, clippy::wildcard_imports)] + fn from_arrow_opt( + arrow_data: &dyn ::arrow2::array::Array, + ) -> crate::DeserializationResult>> + where + Self: Sized, + { + re_tracing::profile_function!(); + use crate::{Loggable as _, ResultExt as _}; + use ::arrow2::{array::*, buffer::*, datatypes::*}; + Ok({ + let arrow_data = arrow_data + .as_any() + .downcast_ref::<::arrow2::array::StructArray>() + .ok_or_else(|| { + crate::DeserializationError::datatype_mismatch( + DataType::Struct(vec![Field { + name: "is_expanded".to_owned(), + data_type: DataType::Boolean, + is_nullable: false, + metadata: [].into(), + }]), + arrow_data.data_type().clone(), + ) + }) + .with_context("rerun.blueprint.PanelView")?; + if arrow_data.is_empty() { + Vec::new() + } else { + let (arrow_data_fields, arrow_data_arrays) = + (arrow_data.fields(), arrow_data.values()); + let arrays_by_name: ::std::collections::HashMap<_, _> = arrow_data_fields + .iter() + .map(|field| field.name.as_str()) + .zip(arrow_data_arrays) + .collect(); + let is_expanded = { + if !arrays_by_name.contains_key("is_expanded") { + return Err(crate::DeserializationError::missing_struct_field( + Self::arrow_datatype(), + "is_expanded", + )) + .with_context("rerun.blueprint.PanelView"); + } + let arrow_data = &**arrays_by_name["is_expanded"]; + arrow_data + .as_any() + .downcast_ref::() + .ok_or_else(|| { + crate::DeserializationError::datatype_mismatch( + DataType::Boolean, + arrow_data.data_type().clone(), + ) + }) + .with_context("rerun.blueprint.PanelView#is_expanded")? + .into_iter() + }; + arrow2::bitmap::utils::ZipValidity::new_with_validity( + ::itertools::izip!(is_expanded), + arrow_data.validity(), + ) + .map(|opt| { + opt.map(|(is_expanded)| { + Ok(Self { + is_expanded: is_expanded + .ok_or_else(crate::DeserializationError::missing_data) + .with_context("rerun.blueprint.PanelView#is_expanded")?, + }) + }) + .transpose() + }) + .collect::>>() + .with_context("rerun.blueprint.PanelView")? + } + }) + } +} diff --git a/crates/re_types/src/blueprint/panel_view_ext.rs b/crates/re_types/src/blueprint/panel_view_ext.rs new file mode 100644 index 000000000000..a03bd8888987 --- /dev/null +++ b/crates/re_types/src/blueprint/panel_view_ext.rs @@ -0,0 +1,9 @@ +use super::PanelView; + +impl PanelView { + // TODO(jleibs): Would be nice if this could be a const EntityPath but making + // the hash const is a bit of a pain. + pub const BLUEPRINT_VIEW_PATH: &str = "blueprint_view"; + pub const SELECTION_VIEW_PATH: &str = "selection_view"; + pub const TIMELINE_VIEW_PATH: &str = "timeline_view"; +} diff --git a/crates/re_types/src/lib.rs b/crates/re_types/src/lib.rs index de9e92fe3e19..2b825559be63 100644 --- a/crates/re_types/src/lib.rs +++ b/crates/re_types/src/lib.rs @@ -287,6 +287,13 @@ pub mod components; /// They all implement the [`Datatype`] trait. pub mod datatypes; +/// Blueprint-related types. +/// +/// They all implement the [`Component`] trait. +/// +/// Unstable. Used for the ongoing blueprint experimentations. +pub mod blueprint; + mod archetype; mod loggable; mod loggable_batch; diff --git a/crates/re_types/src/testing/blueprint/mod.rs b/crates/re_types/src/testing/blueprint/mod.rs new file mode 100644 index 000000000000..3cb8e2ec35f1 --- /dev/null +++ b/crates/re_types/src/testing/blueprint/mod.rs @@ -0,0 +1 @@ +// DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/rust/api.rs diff --git a/crates/re_types_builder/src/codegen/common.rs b/crates/re_types_builder/src/codegen/common.rs index 8bb6c868b640..6f8f05d29e5c 100644 --- a/crates/re_types_builder/src/codegen/common.rs +++ b/crates/re_types_builder/src/codegen/common.rs @@ -303,7 +303,13 @@ pub fn remove_old_files_from_folder( ) { re_tracing::profile_function!(); re_log::debug!("Checking for old files in {folder_path}"); - for entry in std::fs::read_dir(folder_path).unwrap().flatten() { + + let iter = std::fs::read_dir(folder_path).ok(); + if iter.is_none() { + return; + } + + for entry in iter.unwrap().flatten() { if entry.file_type().unwrap().is_dir() { continue; } diff --git a/crates/re_types_builder/src/codegen/cpp/mod.rs b/crates/re_types_builder/src/codegen/cpp/mod.rs index f83b8484a8d5..fef09c52f564 100644 --- a/crates/re_types_builder/src/codegen/cpp/mod.rs +++ b/crates/re_types_builder/src/codegen/cpp/mod.rs @@ -325,7 +325,7 @@ impl QuotedObject { ) -> Self { match obj.specifics { crate::ObjectSpecifics::Struct => match obj.kind { - ObjectKind::Datatype | ObjectKind::Component => { + ObjectKind::Datatype | ObjectKind::Component | ObjectKind::Blueprint => { Self::from_struct(objects, obj, hpp_includes, hpp_type_extensions) } ObjectKind::Archetype => { @@ -1849,7 +1849,7 @@ fn quote_constants_header_and_cpp( quote!(const char #obj_type_ident::INDICATOR_COMPONENT_NAME[] = #indicator_fqname), ); } - ObjectKind::Datatype => {} + ObjectKind::Datatype | ObjectKind::Blueprint => {} } (hpp, cpp) diff --git a/crates/re_types_builder/src/codegen/docs/mod.rs b/crates/re_types_builder/src/codegen/docs/mod.rs index 0c562f124700..3ddc849dcf8f 100644 --- a/crates/re_types_builder/src/codegen/docs/mod.rs +++ b/crates/re_types_builder/src/codegen/docs/mod.rs @@ -53,6 +53,7 @@ impl CodeGenerator for DocsCodeGenerator { ObjectKind::Datatype => datatypes.push(object), ObjectKind::Component => components.push(object), ObjectKind::Archetype => archetypes.push(object), + ObjectKind::Blueprint => continue, // skip blueprint stuff, too early } let page = object_page(reporter, object, object_map); @@ -151,6 +152,7 @@ fn object_page(reporter: &Reporter, object: &Object, object_map: &ObjectMap) -> write_fields(&mut page, object, object_map); } ObjectKind::Archetype => write_archetype_fields(&mut page, object, object_map), + ObjectKind::Blueprint => {} } { @@ -183,7 +185,7 @@ fn object_page(reporter: &Reporter, object: &Object, object_map: &ObjectMap) -> putln!(page); write_used_by(&mut page, reporter, object, object_map); } - ObjectKind::Archetype => {} + ObjectKind::Blueprint | ObjectKind::Archetype => {} } page diff --git a/crates/re_types_builder/src/codegen/python.rs b/crates/re_types_builder/src/codegen/python.rs index fb83f51bd325..67f9c043cd01 100644 --- a/crates/re_types_builder/src/codegen/python.rs +++ b/crates/re_types_builder/src/codegen/python.rs @@ -297,7 +297,7 @@ impl PythonCodeGenerator { let ext_class = ExtensionClass::new(reporter, &kind_path, obj); let names = match obj.kind { - ObjectKind::Datatype | ObjectKind::Component => { + ObjectKind::Datatype | ObjectKind::Component | ObjectKind::Blueprint => { let name = &obj.name; if obj.is_delegating_component() { @@ -411,15 +411,9 @@ impl PythonCodeGenerator { code.push_text(&clause, 1, 0); } - code.push_unindented_text( - format!( - " - __all__ = [{manifest}] - - ", - ), - 0, - ); + if !manifest.is_empty() { + code.push_unindented_text(format!("\n__all__ = [{manifest}]\n\n\n"), 0); + } let obj_code = if obj.is_struct() { code_for_struct(reporter, arrow_registry, &ext_class, objects, obj) @@ -508,7 +502,9 @@ fn write_init_file( let names = names.join(", "); code.push_text(&format!("from .{module} import {names}"), 1, 0); } - code.push_unindented_text(format!("\n__all__ = [{manifest}]"), 0); + if !manifest.is_empty() { + code.push_unindented_text(format!("\n__all__ = [{manifest}]"), 0); + } files_to_write.insert(path, code); } @@ -751,7 +747,7 @@ fn code_for_struct( match kind { ObjectKind::Archetype => (), - ObjectKind::Component | ObjectKind::Datatype => { + ObjectKind::Datatype | ObjectKind::Blueprint | ObjectKind::Component => { code.push_text( quote_arrow_support_from_obj(arrow_registry, ext_class, objects, obj), 1, @@ -901,7 +897,7 @@ fn code_for_union( ObjectKind::Component => { unreachable!("component may not be a union") } - ObjectKind::Datatype => { + ObjectKind::Datatype | ObjectKind::Blueprint => { code.push_text( quote_arrow_support_from_obj(arrow_registry, ext_class, objects, obj), 1, @@ -1222,6 +1218,8 @@ fn quote_import_clauses_from_fqname(fqname: &str) -> String { "from .. import datatypes".to_owned() } else if from.starts_with("rerun.components") { "from .. import components".to_owned() + } else if from.starts_with("rerun.blueprint") { + "from .. import blueprint".to_owned() } else if from.starts_with("rerun.archetypes") { // NOTE: This is assuming importing other archetypes is legal… which whether it is or // isn't for this code generator to say. @@ -1416,6 +1414,8 @@ fn fqname_to_type(fqname: &str) -> String { format!("datatypes.{class}") } else if from.starts_with("rerun.components") { format!("components.{class}") + } else if from.starts_with("rerun.blueprint") { + format!("blueprint.{class}") } else if from.starts_with("rerun.archetypes") { // NOTE: This is assuming importing other archetypes is legal… which whether it is or // isn't for this code generator to say. @@ -1475,7 +1475,7 @@ fn quote_arrow_support_from_obj( format!("{name}ArrayLike") }; - if obj.kind == ObjectKind::Datatype { + if obj.kind == ObjectKind::Datatype || obj.kind == ObjectKind::Blueprint { type_superclasses.push("BaseExtensionType".to_owned()); batch_superclasses.push(format!("BaseBatch[{many_aliases}]")); } else if obj.kind == ObjectKind::Component { @@ -1684,6 +1684,7 @@ fn quote_init_method( }; let doc_typedesc = match obj.kind { ObjectKind::Datatype => "datatype", + ObjectKind::Blueprint => "blueprint", ObjectKind::Component => "component", ObjectKind::Archetype => "archetype", }; diff --git a/crates/re_types_builder/src/codegen/rust/api.rs b/crates/re_types_builder/src/codegen/rust/api.rs index aeecb301c14b..1e3a47771bd0 100644 --- a/crates/re_types_builder/src/codegen/rust/api.rs +++ b/crates/re_types_builder/src/codegen/rust/api.rs @@ -706,7 +706,7 @@ fn quote_trait_impls_from_obj( let name = format_ident!("{name}"); match kind { - ObjectKind::Datatype | ObjectKind::Component => { + ObjectKind::Datatype | ObjectKind::Component | ObjectKind::Blueprint => { let quoted_kind = if *kind == ObjectKind::Datatype { quote!(Datatype) } else { diff --git a/crates/re_types_builder/src/objects.rs b/crates/re_types_builder/src/objects.rs index 8749dfa122dc..b4bdffe561c7 100644 --- a/crates/re_types_builder/src/objects.rs +++ b/crates/re_types_builder/src/objects.rs @@ -191,17 +191,25 @@ impl std::ops::Index<&str> for Objects { pub enum ObjectKind { Datatype, Component, + Blueprint, Archetype, } impl ObjectKind { - pub const ALL: [Self; 3] = [Self::Datatype, Self::Component, Self::Archetype]; + pub const ALL: [Self; 4] = [ + Self::Datatype, + Self::Component, + Self::Blueprint, + Self::Archetype, + ]; // TODO(#2364): use an attr instead of the path pub fn from_pkg_name(pkg_name: impl AsRef) -> Self { let pkg_name = pkg_name.as_ref().replace(".testing", ""); if pkg_name.starts_with("rerun.datatypes") { ObjectKind::Datatype + } else if pkg_name.starts_with("rerun.blueprint") { + ObjectKind::Blueprint } else if pkg_name.starts_with("rerun.components") { ObjectKind::Component } else if pkg_name.starts_with("rerun.archetypes") { @@ -214,6 +222,7 @@ impl ObjectKind { pub fn plural_snake_case(&self) -> &'static str { match self { ObjectKind::Datatype => "datatypes", + ObjectKind::Blueprint => "blueprint", ObjectKind::Component => "components", ObjectKind::Archetype => "archetypes", } @@ -222,6 +231,7 @@ impl ObjectKind { pub fn singular_name(&self) -> &'static str { match self { ObjectKind::Datatype => "Datatype", + ObjectKind::Blueprint => "Blueprint", ObjectKind::Component => "Component", ObjectKind::Archetype => "Archetype", } @@ -230,6 +240,7 @@ impl ObjectKind { pub fn plural_name(&self) -> &'static str { match self { ObjectKind::Datatype => "Datatypes", + ObjectKind::Blueprint => "Blueprint", ObjectKind::Component => "Components", ObjectKind::Archetype => "Archetypes", } diff --git a/crates/re_viewer/Cargo.toml b/crates/re_viewer/Cargo.toml index f4d19503cae0..4fdd382dd61a 100644 --- a/crates/re_viewer/Cargo.toml +++ b/crates/re_viewer/Cargo.toml @@ -73,7 +73,6 @@ re_analytics = { workspace = true, optional = true } ahash.workspace = true anyhow.workspace = true arrow2.workspace = true -arrow2_convert.workspace = true bytemuck.workspace = true cfg-if.workspace = true eframe = { workspace = true, default-features = false, features = [ diff --git a/crates/re_viewer/src/app_blueprint.rs b/crates/re_viewer/src/app_blueprint.rs index 89833defc0d9..04598676c8e1 100644 --- a/crates/re_viewer/src/app_blueprint.rs +++ b/crates/re_viewer/src/app_blueprint.rs @@ -1,9 +1,8 @@ use re_data_store::StoreDb; use re_log_types::{DataRow, EntityPath, RowId, TimePoint}; +use re_types::blueprint::PanelView; use re_viewer_context::{CommandSender, StoreContext, SystemCommand, SystemCommandSender}; -use crate::blueprint_components::panel::PanelState; - /// Blueprint for top-level application pub struct AppBlueprint<'a> { blueprint_db: Option<&'a StoreDb>, @@ -27,17 +26,17 @@ impl<'a> AppBlueprint<'a> { if let Some(blueprint_db) = blueprint_db { if let Some(expanded) = - load_panel_state(&PanelState::BLUEPRINT_VIEW_PATH.into(), blueprint_db) + load_panel_state(&PanelView::BLUEPRINT_VIEW_PATH.into(), blueprint_db) { ret.blueprint_panel_expanded = expanded; } if let Some(expanded) = - load_panel_state(&PanelState::SELECTION_VIEW_PATH.into(), blueprint_db) + load_panel_state(&PanelView::SELECTION_VIEW_PATH.into(), blueprint_db) { ret.selection_panel_expanded = expanded; } if let Some(expanded) = - load_panel_state(&PanelState::TIMELINE_VIEW_PATH.into(), blueprint_db) + load_panel_state(&PanelView::TIMELINE_VIEW_PATH.into(), blueprint_db) { ret.time_panel_expanded = expanded; } @@ -49,30 +48,30 @@ impl<'a> AppBlueprint<'a> { pub fn toggle_blueprint_panel(&self, command_sender: &CommandSender) { let blueprint_panel_expanded = !self.blueprint_panel_expanded; self.send_panel_expanded( - PanelState::BLUEPRINT_VIEW_PATH, + PanelView::BLUEPRINT_VIEW_PATH, blueprint_panel_expanded, command_sender, ); if self.is_narrow_screen && self.blueprint_panel_expanded { - self.send_panel_expanded(PanelState::SELECTION_VIEW_PATH, false, command_sender); + self.send_panel_expanded(PanelView::SELECTION_VIEW_PATH, false, command_sender); } } pub fn toggle_selection_panel(&self, command_sender: &CommandSender) { let selection_panel_expanded = !self.selection_panel_expanded; self.send_panel_expanded( - PanelState::SELECTION_VIEW_PATH, + PanelView::SELECTION_VIEW_PATH, selection_panel_expanded, command_sender, ); if self.is_narrow_screen && self.blueprint_panel_expanded { - self.send_panel_expanded(PanelState::BLUEPRINT_VIEW_PATH, false, command_sender); + self.send_panel_expanded(PanelView::BLUEPRINT_VIEW_PATH, false, command_sender); } } pub fn toggle_time_panel(&self, command_sender: &CommandSender) { self.send_panel_expanded( - PanelState::TIMELINE_VIEW_PATH, + PanelView::TIMELINE_VIEW_PATH, !self.time_panel_expanded, command_sender, ); @@ -80,16 +79,16 @@ impl<'a> AppBlueprint<'a> { } pub fn setup_welcome_screen_blueprint(welcome_screen_blueprint: &mut StoreDb) { - for (panel_name, expanded) in [ - (PanelState::BLUEPRINT_VIEW_PATH, true), - (PanelState::SELECTION_VIEW_PATH, false), - (PanelState::TIMELINE_VIEW_PATH, false), + for (panel_name, is_expanded) in [ + (PanelView::BLUEPRINT_VIEW_PATH, true), + (PanelView::SELECTION_VIEW_PATH, false), + (PanelView::TIMELINE_VIEW_PATH, false), ] { let entity_path = EntityPath::from(panel_name); // TODO(jleibs): Seq instead of timeless? let timepoint = TimePoint::timeless(); - let component = PanelState { expanded }; + let component = PanelView { is_expanded }; let row = DataRow::from_cells1_sized(RowId::random(), entity_path, timepoint, 1, [component]) @@ -105,7 +104,7 @@ impl<'a> AppBlueprint<'a> { fn send_panel_expanded( &self, panel_name: &str, - expanded: bool, + is_expanded: bool, command_sender: &CommandSender, ) { if let Some(blueprint_db) = self.blueprint_db { @@ -113,7 +112,7 @@ impl<'a> AppBlueprint<'a> { // TODO(jleibs): Seq instead of timeless? let timepoint = TimePoint::timeless(); - let component = PanelState { expanded }; + let component = PanelView { is_expanded }; let row = DataRow::from_cells1_sized(RowId::random(), entity_path, timepoint, 1, [component]) @@ -131,6 +130,6 @@ fn load_panel_state(path: &EntityPath, blueprint_db: &re_data_store::StoreDb) -> re_tracing::profile_function!(); blueprint_db .store() - .query_timeless_component::(path) - .map(|p| p.expanded) + .query_timeless_component::(path) + .map(|p| p.is_expanded) } diff --git a/crates/re_viewer/src/blueprint_components/mod.rs b/crates/re_viewer/src/blueprint_components/mod.rs deleted file mode 100644 index 51d8db096ca6..000000000000 --- a/crates/re_viewer/src/blueprint_components/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! Potentially user-facing components to be used in blueprints. - -pub mod panel; diff --git a/crates/re_viewer/src/blueprint_components/panel.rs b/crates/re_viewer/src/blueprint_components/panel.rs deleted file mode 100644 index ec2c1d68933c..000000000000 --- a/crates/re_viewer/src/blueprint_components/panel.rs +++ /dev/null @@ -1,32 +0,0 @@ -use arrow2_convert::{ArrowDeserialize, ArrowField, ArrowSerialize}; - -/// A Panel component -/// -/// ## Example -/// ``` -/// # use re_viewer::blueprint_components::panel::PanelState; -/// # use arrow2_convert::field::ArrowField; -/// # use arrow2::datatypes::{DataType, Field}; -/// assert_eq!( -/// PanelState::data_type(), -/// DataType::Struct(vec![ -/// Field::new("expanded", DataType::Boolean, false), -/// ]) -/// ); -/// ``` -// TODO(jleibs): If we want these accessible from python, they need to -// go into the registry that's back in `re_log_types` -#[derive(Debug, Clone, Copy, ArrowField, ArrowSerialize, ArrowDeserialize)] -pub struct PanelState { - pub expanded: bool, -} - -impl PanelState { - // TODO(jleibs): Would be nice if this could be a const EntityPath but making - // the hash const is a bit of a pain. - pub const BLUEPRINT_VIEW_PATH: &str = "blueprint_view"; - pub const SELECTION_VIEW_PATH: &str = "selection_view"; - pub const TIMELINE_VIEW_PATH: &str = "timeline_view"; -} - -re_log_types::arrow2convert_component_shim!(PanelState as "rerun.blueprint.PanelView"); diff --git a/crates/re_viewer/src/lib.rs b/crates/re_viewer/src/lib.rs index ebee21a08060..b2ebcb8d255f 100644 --- a/crates/re_viewer/src/lib.rs +++ b/crates/re_viewer/src/lib.rs @@ -7,7 +7,6 @@ mod app; mod app_blueprint; mod app_state; mod background_tasks; -pub mod blueprint_components; pub mod env_vars; #[cfg(not(target_arch = "wasm32"))] mod loading; diff --git a/crates/re_viewport/src/blueprint_components/mod.rs b/crates/re_viewport/src/blueprint_components/mod.rs index 8028c7d6b878..4ee5032b3526 100644 --- a/crates/re_viewport/src/blueprint_components/mod.rs +++ b/crates/re_viewport/src/blueprint_components/mod.rs @@ -4,4 +4,4 @@ mod space_view; mod viewport; pub use space_view::SpaceViewComponent; -pub use viewport::{AutoSpaceViews, SpaceViewMaximized, ViewportLayout, VIEWPORT_PATH}; +pub use viewport::{SpaceViewMaximized, ViewportLayout, VIEWPORT_PATH}; diff --git a/crates/re_viewport/src/blueprint_components/viewport.rs b/crates/re_viewport/src/blueprint_components/viewport.rs index e543cec6594f..b9caa536295b 100644 --- a/crates/re_viewport/src/blueprint_components/viewport.rs +++ b/crates/re_viewport/src/blueprint_components/viewport.rs @@ -6,24 +6,6 @@ pub use re_viewer_context::SpaceViewId; pub const VIEWPORT_PATH: &str = "viewport"; -/// A flag indicating space views should be automatically populated -/// -/// ## Example -/// ``` -/// # use re_viewport::blueprint_components::AutoSpaceViews; -/// # use arrow2_convert::field::ArrowField; -/// # use arrow2::datatypes::{DataType, Field}; -/// assert_eq!( -/// AutoSpaceViews::data_type(), -/// DataType::Boolean -/// ); -/// ``` -#[derive(Clone, Default, ArrowField, ArrowSerialize, ArrowDeserialize)] -#[arrow_field(transparent)] -pub struct AutoSpaceViews(pub bool); - -re_log_types::arrow2convert_component_shim!(AutoSpaceViews as "rerun.blueprint.AutoSpaceViews"); - /// Whether a space view is maximized /// /// ## Example diff --git a/crates/re_viewport/src/viewport_blueprint.rs b/crates/re_viewport/src/viewport_blueprint.rs index d4d7139b32b6..9592380625c7 100644 --- a/crates/re_viewport/src/viewport_blueprint.rs +++ b/crates/re_viewport/src/viewport_blueprint.rs @@ -5,16 +5,14 @@ use arrow2_convert::field::ArrowField; use re_data_store::{EntityPath, StoreDb}; use re_log_types::{DataCell, DataRow, RowId, TimePoint}; -use re_types::Loggable as _; +use re_types::{blueprint::AutoSpaceViews, Loggable as _}; use re_viewer_context::{ CommandSender, Item, SpaceViewClassName, SpaceViewId, SystemCommand, SystemCommandSender, ViewerContext, }; use crate::{ - blueprint_components::{ - AutoSpaceViews, SpaceViewComponent, SpaceViewMaximized, ViewportLayout, VIEWPORT_PATH, - }, + blueprint_components::{SpaceViewComponent, SpaceViewMaximized, ViewportLayout, VIEWPORT_PATH}, space_info::SpaceInfoCollection, space_view::SpaceViewBlueprint, space_view_heuristics::{default_created_space_views, identify_entities_per_system_per_class}, diff --git a/rerun_cpp/.gitattributes b/rerun_cpp/.gitattributes index 16a026543f8a..2e54db6c91b1 100644 --- a/rerun_cpp/.gitattributes +++ b/rerun_cpp/.gitattributes @@ -48,6 +48,11 @@ src/rerun/archetypes/transform3d.hpp linguist-generated=true src/rerun/archetypes/view_coordinates.cpp linguist-generated=true src/rerun/archetypes/view_coordinates.hpp linguist-generated=true src/rerun/archetypes.hpp linguist-generated=true +src/rerun/blueprint/auto_space_views.cpp linguist-generated=true +src/rerun/blueprint/auto_space_views.hpp linguist-generated=true +src/rerun/blueprint/panel_view.cpp linguist-generated=true +src/rerun/blueprint/panel_view.hpp linguist-generated=true +src/rerun/blueprint.hpp linguist-generated=true src/rerun/components/annotation_context.cpp linguist-generated=true src/rerun/components/annotation_context.hpp linguist-generated=true src/rerun/components/blob.cpp linguist-generated=true @@ -183,6 +188,7 @@ tests/generated/archetypes/affix_fuzzer3.hpp linguist-generated=true tests/generated/archetypes/affix_fuzzer4.cpp linguist-generated=true tests/generated/archetypes/affix_fuzzer4.hpp linguist-generated=true tests/generated/archetypes.hpp linguist-generated=true +tests/generated/blueprint.hpp linguist-generated=true tests/generated/components/affix_fuzzer1.cpp linguist-generated=true tests/generated/components/affix_fuzzer1.hpp linguist-generated=true tests/generated/components/affix_fuzzer10.cpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/blueprint.hpp b/rerun_cpp/src/rerun/blueprint.hpp new file mode 100644 index 000000000000..85a4a50132e6 --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint.hpp @@ -0,0 +1,6 @@ +// DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/cpp/mod.rs + +#pragma once + +#include "blueprint/auto_space_views.hpp" +#include "blueprint/panel_view.hpp" diff --git a/rerun_cpp/src/rerun/blueprint/auto_space_views.cpp b/rerun_cpp/src/rerun/blueprint/auto_space_views.cpp new file mode 100644 index 000000000000..1a117360cf45 --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/auto_space_views.cpp @@ -0,0 +1,48 @@ +// DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/cpp/mod.rs +// Based on "crates/re_types/definitions/rerun/blueprint/auto_space_views.fbs". + +#include "auto_space_views.hpp" + +#include +#include + +namespace rerun { + namespace blueprint { + const std::shared_ptr &AutoSpaceViews::arrow_datatype() { + static const auto datatype = arrow::boolean(); + return datatype; + } + + Result> AutoSpaceViews::new_arrow_array_builder( + arrow::MemoryPool *memory_pool + ) { + if (!memory_pool) { + return Error(ErrorCode::UnexpectedNullArgument, "Memory pool is null."); + } + + return Result(std::make_shared(memory_pool)); + } + + Error AutoSpaceViews::fill_arrow_array_builder( + arrow::BooleanBuilder *builder, const AutoSpaceViews *elements, size_t num_elements + ) { + if (!builder) { + return Error(ErrorCode::UnexpectedNullArgument, "Passed array builder is null."); + } + if (!elements) { + return Error( + ErrorCode::UnexpectedNullArgument, + "Cannot serialize null pointer to arrow array." + ); + } + + static_assert(sizeof(*elements) == sizeof(elements->enabled)); + ARROW_RETURN_NOT_OK(builder->AppendValues( + reinterpret_cast(&elements->enabled), + static_cast(num_elements) + )); + + return Error::ok(); + } + } // namespace blueprint +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/auto_space_views.hpp b/rerun_cpp/src/rerun/blueprint/auto_space_views.hpp new file mode 100644 index 000000000000..9c144b709432 --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/auto_space_views.hpp @@ -0,0 +1,50 @@ +// DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/cpp/mod.rs +// Based on "crates/re_types/definitions/rerun/blueprint/auto_space_views.fbs". + +#pragma once + +#include "../result.hpp" + +#include +#include +#include + +namespace arrow { + class BooleanBuilder; + class DataType; + class MemoryPool; +} // namespace arrow + +namespace rerun { + namespace blueprint { + /// **Blueprint**: A flag indicating space views should be automatically populated. + /// + /// Unstable. Used for the ongoing blueprint experimentations. + struct AutoSpaceViews { + bool enabled; + + public: + AutoSpaceViews() = default; + + AutoSpaceViews(bool _enabled) : enabled(std::move(_enabled)) {} + + AutoSpaceViews& operator=(bool _enabled) { + enabled = std::move(_enabled); + return *this; + } + + /// Returns the arrow data type this type corresponds to. + static const std::shared_ptr& arrow_datatype(); + + /// Creates a new array builder with an array of this type. + static Result> new_arrow_array_builder( + arrow::MemoryPool* memory_pool + ); + + /// Fills an arrow array builder with an array of this type. + static Error fill_arrow_array_builder( + arrow::BooleanBuilder* builder, const AutoSpaceViews* elements, size_t num_elements + ); + }; + } // namespace blueprint +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/panel_view.cpp b/rerun_cpp/src/rerun/blueprint/panel_view.cpp new file mode 100644 index 000000000000..da4977eb0d61 --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/panel_view.cpp @@ -0,0 +1,60 @@ +// DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/cpp/mod.rs +// Based on "crates/re_types/definitions/rerun/blueprint/panel_view.fbs". + +#include "panel_view.hpp" + +#include +#include + +namespace rerun { + namespace blueprint { + const std::shared_ptr &PanelView::arrow_datatype() { + static const auto datatype = arrow::struct_({ + arrow::field("is_expanded", arrow::boolean(), false), + }); + return datatype; + } + + Result> PanelView::new_arrow_array_builder( + arrow::MemoryPool *memory_pool + ) { + if (!memory_pool) { + return Error(ErrorCode::UnexpectedNullArgument, "Memory pool is null."); + } + + return Result(std::make_shared( + arrow_datatype(), + memory_pool, + std::vector>({ + std::make_shared(memory_pool), + }) + )); + } + + Error PanelView::fill_arrow_array_builder( + arrow::StructBuilder *builder, const PanelView *elements, size_t num_elements + ) { + if (!builder) { + return Error(ErrorCode::UnexpectedNullArgument, "Passed array builder is null."); + } + if (!elements) { + return Error( + ErrorCode::UnexpectedNullArgument, + "Cannot serialize null pointer to arrow array." + ); + } + + { + auto field_builder = + static_cast(builder->field_builder(0)); + ARROW_RETURN_NOT_OK(field_builder->Reserve(static_cast(num_elements))); + for (size_t elem_idx = 0; elem_idx < num_elements; elem_idx += 1) { + ARROW_RETURN_NOT_OK(field_builder->Append(elements[elem_idx].is_expanded)); + } + } + ARROW_RETURN_NOT_OK(builder->AppendValues(static_cast(num_elements), nullptr)); + + return Error::ok(); + } + } // namespace blueprint +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/panel_view.hpp b/rerun_cpp/src/rerun/blueprint/panel_view.hpp new file mode 100644 index 000000000000..b68e7b86af58 --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/panel_view.hpp @@ -0,0 +1,50 @@ +// DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/cpp/mod.rs +// Based on "crates/re_types/definitions/rerun/blueprint/panel_view.fbs". + +#pragma once + +#include "../result.hpp" + +#include +#include +#include + +namespace arrow { + class DataType; + class MemoryPool; + class StructBuilder; +} // namespace arrow + +namespace rerun { + namespace blueprint { + /// **Blueprint**: The state of the panels. + /// + /// Unstable. Used for the ongoing blueprint experimentations. + struct PanelView { + bool is_expanded; + + public: + PanelView() = default; + + PanelView(bool _is_expanded) : is_expanded(std::move(_is_expanded)) {} + + PanelView& operator=(bool _is_expanded) { + is_expanded = std::move(_is_expanded); + return *this; + } + + /// Returns the arrow data type this type corresponds to. + static const std::shared_ptr& arrow_datatype(); + + /// Creates a new array builder with an array of this type. + static Result> new_arrow_array_builder( + arrow::MemoryPool* memory_pool + ); + + /// Fills an arrow array builder with an array of this type. + static Error fill_arrow_array_builder( + arrow::StructBuilder* builder, const PanelView* elements, size_t num_elements + ); + }; + } // namespace blueprint +} // namespace rerun diff --git a/rerun_cpp/tests/generated/blueprint.hpp b/rerun_cpp/tests/generated/blueprint.hpp new file mode 100644 index 000000000000..dcdf9bcbede6 --- /dev/null +++ b/rerun_cpp/tests/generated/blueprint.hpp @@ -0,0 +1,3 @@ +// DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/cpp/mod.rs + +#pragma once diff --git a/rerun_py/rerun_sdk/rerun/.gitattributes b/rerun_py/rerun_sdk/rerun/.gitattributes index 7e7a30cc8973..ca3ad1f0014f 100644 --- a/rerun_py/rerun_sdk/rerun/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/.gitattributes @@ -25,6 +25,9 @@ archetypes/text_log.py linguist-generated=true archetypes/time_series_scalar.py linguist-generated=true archetypes/transform3d.py linguist-generated=true archetypes/view_coordinates.py linguist-generated=true +blueprint/__init__.py linguist-generated=true +blueprint/auto_space_views.py linguist-generated=true +blueprint/panel_view.py linguist-generated=true components/__init__.py linguist-generated=true components/annotation_context.py linguist-generated=true components/blob.py linguist-generated=true diff --git a/rerun_py/rerun_sdk/rerun/blueprint/__init__.py b/rerun_py/rerun_sdk/rerun/blueprint/__init__.py new file mode 100644 index 000000000000..c806aec91c8e --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/__init__.py @@ -0,0 +1,25 @@ +# DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/python.rs + +from __future__ import annotations + +from .auto_space_views import ( + AutoSpaceViews, + AutoSpaceViewsArrayLike, + AutoSpaceViewsBatch, + AutoSpaceViewsLike, + AutoSpaceViewsType, +) +from .panel_view import PanelView, PanelViewArrayLike, PanelViewBatch, PanelViewLike, PanelViewType + +__all__ = [ + "AutoSpaceViews", + "AutoSpaceViewsArrayLike", + "AutoSpaceViewsBatch", + "AutoSpaceViewsLike", + "AutoSpaceViewsType", + "PanelView", + "PanelViewArrayLike", + "PanelViewBatch", + "PanelViewLike", + "PanelViewType", +] diff --git a/rerun_py/rerun_sdk/rerun/blueprint/auto_space_views.py b/rerun_py/rerun_sdk/rerun/blueprint/auto_space_views.py new file mode 100644 index 000000000000..c2529872ce8b --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/auto_space_views.py @@ -0,0 +1,52 @@ +# DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/python.rs +# Based on "crates/re_types/definitions/rerun/blueprint/auto_space_views.fbs". + +# You can extend this class by creating a "AutoSpaceViewsExt" class in "auto_space_views_ext.py". + +from __future__ import annotations + +from typing import Any, Sequence, Union + +from attrs import define, field + +from .._baseclasses import BaseBatch, BaseExtensionType + +__all__ = [ + "AutoSpaceViews", + "AutoSpaceViewsArrayLike", + "AutoSpaceViewsBatch", + "AutoSpaceViewsLike", + "AutoSpaceViewsType", +] + + +@define(init=False) +class AutoSpaceViews: + """ + **Blueprint**: A flag indicating space views should be automatically populated. + + Unstable. Used for the ongoing blueprint experimentations. + """ + + def __init__(self: Any, enabled: AutoSpaceViewsLike): + """Create a new instance of the AutoSpaceViews blueprint.""" + + # You can define your own __init__ function as a member of AutoSpaceViewsExt in auto_space_views_ext.py + self.__attrs_init__(enabled=enabled) + + enabled: bool = field(converter=bool) + + +AutoSpaceViewsLike = AutoSpaceViews +AutoSpaceViewsArrayLike = Union[ + AutoSpaceViews, + Sequence[AutoSpaceViewsLike], +] + + +class AutoSpaceViewsType(BaseExtensionType): + _TYPE_NAME: str = "rerun.blueprint.AutoSpaceViews" + + +class AutoSpaceViewsBatch(BaseBatch[AutoSpaceViewsArrayLike]): + _ARROW_TYPE = AutoSpaceViewsType() diff --git a/rerun_py/rerun_sdk/rerun/blueprint/panel_view.py b/rerun_py/rerun_sdk/rerun/blueprint/panel_view.py new file mode 100644 index 000000000000..efaed31438d7 --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/panel_view.py @@ -0,0 +1,46 @@ +# DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/python.rs +# Based on "crates/re_types/definitions/rerun/blueprint/panel_view.fbs". + +# You can extend this class by creating a "PanelViewExt" class in "panel_view_ext.py". + +from __future__ import annotations + +from typing import Any, Sequence, Union + +from attrs import define, field + +from .._baseclasses import BaseBatch, BaseExtensionType + +__all__ = ["PanelView", "PanelViewArrayLike", "PanelViewBatch", "PanelViewLike", "PanelViewType"] + + +@define(init=False) +class PanelView: + """ + **Blueprint**: The state of the panels. + + Unstable. Used for the ongoing blueprint experimentations. + """ + + def __init__(self: Any, is_expanded: PanelViewLike): + """Create a new instance of the PanelView blueprint.""" + + # You can define your own __init__ function as a member of PanelViewExt in panel_view_ext.py + self.__attrs_init__(is_expanded=is_expanded) + + is_expanded: bool = field(converter=bool) + + +PanelViewLike = PanelView +PanelViewArrayLike = Union[ + PanelView, + Sequence[PanelViewLike], +] + + +class PanelViewType(BaseExtensionType): + _TYPE_NAME: str = "rerun.blueprint.PanelView" + + +class PanelViewBatch(BaseBatch[PanelViewArrayLike]): + _ARROW_TYPE = PanelViewType() diff --git a/rerun_py/src/python_bridge.rs b/rerun_py/src/python_bridge.rs index c72f831c8db1..c3c38b37f67b 100644 --- a/rerun_py/src/python_bridge.rs +++ b/rerun_py/src/python_bridge.rs @@ -11,10 +11,9 @@ use pyo3::{ types::{PyBytes, PyDict}, }; -use re_viewer::blueprint_components::panel::PanelState; use re_viewer_context::SpaceViewId; use re_viewport::{ - blueprint_components::{AutoSpaceViews, SpaceViewComponent, VIEWPORT_PATH}, + blueprint_components::{SpaceViewComponent, VIEWPORT_PATH}, SpaceViewBlueprint, }; @@ -694,26 +693,30 @@ fn set_panels( timeline_view_expanded: Option, blueprint: Option<&PyRecordingStream>, ) { + use rerun::external::re_types::blueprint::PanelView; + if let Some(expanded) = blueprint_view_expanded { - set_panel(PanelState::BLUEPRINT_VIEW_PATH, expanded, blueprint); + set_panel(PanelView::BLUEPRINT_VIEW_PATH, expanded, blueprint); } if let Some(expanded) = selection_view_expanded { - set_panel(PanelState::SELECTION_VIEW_PATH, expanded, blueprint); + set_panel(PanelView::SELECTION_VIEW_PATH, expanded, blueprint); } if let Some(expanded) = timeline_view_expanded { - set_panel(PanelState::TIMELINE_VIEW_PATH, expanded, blueprint); + set_panel(PanelView::TIMELINE_VIEW_PATH, expanded, blueprint); } } -fn set_panel(entity_path: &str, expanded: bool, blueprint: Option<&PyRecordingStream>) { +fn set_panel(entity_path: &str, is_expanded: bool, blueprint: Option<&PyRecordingStream>) { let Some(blueprint) = get_blueprint_recording(blueprint) else { return; }; + use rerun::external::re_types::blueprint::PanelView; + // TODO(jleibs): Validation this is a valid blueprint path? let entity_path = parse_entity_path(entity_path); - let panel_state = PanelState { expanded }; + let panel_state = PanelView { is_expanded }; let row = DataRow::from_cells1( RowId::random(), @@ -778,6 +781,8 @@ fn set_auto_space_views(enabled: bool, blueprint: Option<&PyRecordingStream>) { return; }; + use rerun::external::re_types::blueprint::AutoSpaceViews; + let enable_auto_space = AutoSpaceViews(enabled); let row = DataRow::from_cells1( diff --git a/rerun_py/tests/test_types/.gitattributes b/rerun_py/tests/test_types/.gitattributes index fda84e6a69e4..1c99c30f4223 100644 --- a/rerun_py/tests/test_types/.gitattributes +++ b/rerun_py/tests/test_types/.gitattributes @@ -6,6 +6,7 @@ archetypes/affix_fuzzer1.py linguist-generated=true archetypes/affix_fuzzer2.py linguist-generated=true archetypes/affix_fuzzer3.py linguist-generated=true archetypes/affix_fuzzer4.py linguist-generated=true +blueprint/__init__.py linguist-generated=true components/__init__.py linguist-generated=true components/affix_fuzzer1.py linguist-generated=true components/affix_fuzzer10.py linguist-generated=true diff --git a/rerun_py/tests/test_types/blueprint/__init__.py b/rerun_py/tests/test_types/blueprint/__init__.py new file mode 100644 index 000000000000..b848838d60eb --- /dev/null +++ b/rerun_py/tests/test_types/blueprint/__init__.py @@ -0,0 +1,3 @@ +# DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/python.rs + +from __future__ import annotations