diff --git a/crates/re_entity_db/src/entity_properties.rs b/crates/re_entity_db/src/entity_properties.rs index 02f6e29325a1..fb50dc0d39bc 100644 --- a/crates/re_entity_db/src/entity_properties.rs +++ b/crates/re_entity_db/src/entity_properties.rs @@ -94,7 +94,6 @@ impl FromIterator<(EntityPath, EntityProperties)> for EntityPropertyMap { #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", serde(default))] pub struct EntityProperties { - pub visible_history: re_query::ExtraQueryHistory, pub interactive: bool, /// What kind of color mapping should be applied (none, map, texture, transfer..)? @@ -143,7 +142,6 @@ pub struct EntityProperties { impl Default for EntityProperties { fn default() -> Self { Self { - visible_history: re_query::ExtraQueryHistory::default(), interactive: true, color_mapper: EditableAutoValue::default(), pinhole_image_plane_distance: EditableAutoValue::Auto(1.0), @@ -164,7 +162,6 @@ impl EntityProperties { /// Multiply/and these together. pub fn with_child(&self, child: &Self) -> Self { Self { - visible_history: self.visible_history.with_child(&child.visible_history), interactive: self.interactive && child.interactive, color_mapper: self.color_mapper.or(&child.color_mapper).clone(), @@ -208,7 +205,6 @@ impl EntityProperties { /// loaded from the Blueprint store where the Auto values are not up-to-date. pub fn merge_with(&self, other: &Self) -> Self { Self { - visible_history: self.visible_history.with_child(&other.visible_history), interactive: other.interactive, color_mapper: other.color_mapper.or(&self.color_mapper).clone(), @@ -246,7 +242,6 @@ impl EntityProperties { /// Determine whether this `EntityProperty` has user-edits relative to another `EntityProperty` pub fn has_edits(&self, other: &Self) -> bool { let Self { - visible_history, interactive, color_mapper, pinhole_image_plane_distance, @@ -260,8 +255,7 @@ impl EntityProperties { time_series_aggregator, } = self; - visible_history != &other.visible_history - || interactive != &other.interactive + interactive != &other.interactive || color_mapper.has_edits(&other.color_mapper) || pinhole_image_plane_distance.has_edits(&other.pinhole_image_plane_distance) || backproject_depth.has_edits(&other.backproject_depth) diff --git a/crates/re_log_types/src/time_point/time_int.rs b/crates/re_log_types/src/time_point/time_int.rs index fa633336323a..de13e0d624df 100644 --- a/crates/re_log_types/src/time_point/time_int.rs +++ b/crates/re_log_types/src/time_point/time_int.rs @@ -113,6 +113,13 @@ impl From for Duration { } } +impl From for re_types_core::datatypes::TimeInt { + #[inline] + fn from(int: TimeInt) -> Self { + Self(int.as_i64()) + } +} + impl std::ops::Neg for TimeInt { type Output = Self; diff --git a/crates/re_query/src/util.rs b/crates/re_query/src/util.rs index d1c72298bdf9..11cfe034e48f 100644 --- a/crates/re_query/src/util.rs +++ b/crates/re_query/src/util.rs @@ -11,7 +11,6 @@ use crate::{query_archetype, range::range_archetype, ArchetypeView}; /// For [`VisibleHistoryBoundary::RelativeToTimeCursor`] and [`VisibleHistoryBoundary::Absolute`], /// the value are either nanos or frames, depending on the type of timeline. #[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub enum VisibleHistoryBoundary { /// Boundary is a value relative to the time cursor RelativeToTimeCursor(i64), @@ -36,7 +35,6 @@ impl Default for VisibleHistoryBoundary { /// Visible history bounds. #[derive(Clone, Copy, Default, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct VisibleHistory { /// Low time boundary. pub from: VisibleHistoryBoundary, @@ -99,8 +97,6 @@ impl VisibleHistory { /// When showing an entity in the history view, add this much history to it. #[derive(Clone, Copy, Default, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] -#[cfg_attr(feature = "serde", serde(default))] pub struct ExtraQueryHistory { /// Is the feature enabled? pub enabled: bool, @@ -112,19 +108,6 @@ pub struct ExtraQueryHistory { pub sequences: VisibleHistory, } -impl ExtraQueryHistory { - /// Multiply/and these together. - pub fn with_child(&self, child: &Self) -> Self { - if child.enabled { - *child - } else if self.enabled { - *self - } else { - Self::default() - } - } -} - // --- pub fn query_archetype_with_history<'a, A: Archetype + 'a, const N: usize>( diff --git a/crates/re_space_view/src/lib.rs b/crates/re_space_view/src/lib.rs index dea050e7ca05..fc879706ef7d 100644 --- a/crates/re_space_view/src/lib.rs +++ b/crates/re_space_view/src/lib.rs @@ -9,6 +9,7 @@ mod screenshot; mod space_view; mod space_view_contents; mod sub_archetypes; // TODO(andreas): better name before `sub_archetype` sticks around? +mod visual_time_range; mod visualizable; pub use data_query::{DataQuery, EntityOverrideContext, PropertyResolver}; @@ -20,6 +21,10 @@ pub use sub_archetypes::{ entity_path_for_space_view_sub_archetype, query_space_view_sub_archetype, query_space_view_sub_archetype_or_default, }; +pub use visual_time_range::{ + default_time_range, query_visual_history, time_range_boundary_to_visible_history_boundary, + visible_history_boundary_to_time_range_boundary, visible_time_range_to_time_range, +}; pub use visualizable::determine_visualizable_entities; // ----------- diff --git a/crates/re_space_view/src/space_view.rs b/crates/re_space_view/src/space_view.rs index 02804b85b60b..4b8dc2214af7 100644 --- a/crates/re_space_view/src/space_view.rs +++ b/crates/re_space_view/src/space_view.rs @@ -1,9 +1,9 @@ use itertools::{FoldWhile, Itertools}; -use re_data_store::LatestAtQuery; -use re_entity_db::{EntityDb, EntityPath, EntityProperties, VisibleHistory}; -use re_entity_db::{EntityPropertiesComponent, EntityPropertyMap}; +use nohash_hasher::IntMap; use crate::SpaceViewContents; +use re_data_store::LatestAtQuery; +use re_entity_db::{EntityDb, EntityPath, EntityPropertiesComponent, EntityPropertyMap}; use re_log_types::{DataRow, EntityPathSubs, RowId}; use re_query::query_archetype; use re_types::blueprint::archetypes as blueprint_archetypes; @@ -14,9 +14,9 @@ use re_types::{ use re_types_core::archetypes::Clear; use re_types_core::Archetype as _; use re_viewer_context::{ - DataResult, PerSystemEntities, PropertyOverrides, RecommendedSpaceView, SpaceViewClass, - SpaceViewClassIdentifier, SpaceViewId, SpaceViewState, StoreContext, SystemCommand, - SystemCommandSender as _, SystemExecutionOutput, ViewQuery, ViewerContext, + DataResult, OverridePath, PerSystemEntities, PropertyOverrides, RecommendedSpaceView, + SpaceViewClass, SpaceViewClassIdentifier, SpaceViewId, SpaceViewState, StoreContext, + SystemCommand, SystemCommandSender as _, SystemExecutionOutput, ViewQuery, ViewerContext, }; // ---------------------------------------------------------------------------- @@ -416,46 +416,56 @@ impl SpaceViewBlueprint { } pub fn root_data_result(&self, ctx: &StoreContext<'_>, query: &LatestAtQuery) -> DataResult { - let entity_path = self.entity_path(); - - let is_time_series = self.class_identifier == "Time Series"; + let base_override_root = self.entity_path(); + let individual_override_path = + base_override_root.join(&DataResult::INDIVIDUAL_OVERRIDES_PREFIX.into()); + let recursive_override_path = + base_override_root.join(&DataResult::RECURSIVE_OVERRIDES_PREFIX.into()); - let mut individual_properties = ctx + let individual_properties = ctx .blueprint .store() - .query_latest_component_quiet::(&self.entity_path(), query) + .query_latest_component_quiet::( + &individual_override_path, + query, + ) .map(|result| result.value.0); + let accumulated_properties = individual_properties.clone().unwrap_or_default(); - // TODO(#4194): this should come from delegation to the space-view-class - if individual_properties.is_none() && is_time_series { - let mut time_series_defaults = EntityProperties::default(); - time_series_defaults.visible_history.nanos = VisibleHistory::ALL; - time_series_defaults.visible_history.sequences = VisibleHistory::ALL; - individual_properties = Some(time_series_defaults); - } - - let mut accumulated_properties = individual_properties.clone().unwrap_or_default(); - - if is_time_series { - // TODO(#4194): enabled == false means use defaults - if !accumulated_properties.visible_history.enabled { - accumulated_properties.visible_history.enabled = true; - accumulated_properties.visible_history.nanos = VisibleHistory::ALL; - accumulated_properties.visible_history.sequences = VisibleHistory::ALL; + // Gather recursive component overrides. + // Ignore individual overrides on SpaceView root. + let mut recursive_component_overrides = IntMap::default(); + if let Some(recursive_override_subtree) = + ctx.blueprint.tree().subtree(&recursive_override_path) + { + for component in recursive_override_subtree.entity.components.keys() { + if let Some(component_data) = ctx + .blueprint + .store() + .latest_at(query, &recursive_override_path, *component, &[*component]) + .and_then(|(_, _, cells)| cells[0].clone()) + { + if !component_data.is_empty() { + recursive_component_overrides.insert( + *component, + OverridePath::blueprint_path(recursive_override_path.clone()), + ); + } + } } } DataResult { - entity_path: entity_path.clone(), + entity_path: base_override_root, visualizers: Default::default(), tree_prefix_only: false, property_overrides: Some(PropertyOverrides { accumulated_properties, individual_properties, recursive_properties: Default::default(), - resolved_component_overrides: Default::default(), - recursive_override_path: entity_path.clone(), - individual_override_path: entity_path, + resolved_component_overrides: recursive_component_overrides, + recursive_override_path, + individual_override_path, }), } } @@ -464,7 +474,7 @@ impl SpaceViewBlueprint { #[cfg(test)] mod tests { use crate::data_query::{DataQuery, PropertyResolver}; - use re_entity_db::EntityDb; + use re_entity_db::{EntityDb, EntityProperties, EntityPropertiesComponent}; use re_log_types::{ example_components::{MyColor, MyLabel, MyPoint}, DataCell, DataRow, RowId, StoreId, StoreKind, TimePoint, @@ -673,110 +683,6 @@ mod tests { assert!(!result.accumulated_properties().interactive); } } - - // Override interactive range on root - { - let root = space_view.root_data_result( - &StoreContext { - app_id: re_log_types::ApplicationId::unknown(), - blueprint: &blueprint, - recording: Some(&recording), - all_recordings: vec![], - }, - &blueprint_query, - ); - let mut overrides = root.individual_properties().cloned().unwrap_or_default(); - overrides.visible_history.enabled = true; - overrides.visible_history.nanos = VisibleHistory::ALL; - - save_override( - overrides, - root.recursive_override_path().unwrap(), - &mut blueprint, - ); - } - - // Everyone has interactive history - { - let ctx = StoreContext { - app_id: re_log_types::ApplicationId::unknown(), - blueprint: &blueprint, - recording: Some(&recording), - all_recordings: vec![], - }; - let mut query_result = contents.execute_query(&ctx, &visualizable_entities); - resolver.update_overrides(&ctx, &blueprint_query, &mut query_result); - - let parent = query_result - .tree - .lookup_result_by_path(&EntityPath::from("parent")) - .unwrap(); - let child1 = query_result - .tree - .lookup_result_by_path(&EntityPath::from("parent/skip/child1")) - .unwrap(); - let child2 = query_result - .tree - .lookup_result_by_path(&EntityPath::from("parent/skip/child2")) - .unwrap(); - - for result in [parent, child1, child2] { - assert!(result.accumulated_properties().visible_history.enabled); - assert_eq!( - result.accumulated_properties().visible_history.nanos, - VisibleHistory::ALL - ); - } - - let mut overrides = child2.individual_properties().cloned().unwrap_or_default(); - overrides.visible_history.enabled = true; - - save_override( - overrides, - child2.individual_override_path().unwrap(), - &mut blueprint, - ); - } - - // Child2 has its own interactive history - { - let ctx = StoreContext { - app_id: re_log_types::ApplicationId::unknown(), - blueprint: &blueprint, - recording: Some(&recording), - all_recordings: vec![], - }; - - let mut query_result = contents.execute_query(&ctx, &visualizable_entities); - resolver.update_overrides(&ctx, &blueprint_query, &mut query_result); - - let parent = query_result - .tree - .lookup_result_by_path(&EntityPath::from("parent")) - .unwrap(); - let child1 = query_result - .tree - .lookup_result_by_path(&EntityPath::from("parent/skip/child1")) - .unwrap(); - let child2 = query_result - .tree - .lookup_result_by_path(&EntityPath::from("parent/skip/child2")) - .unwrap(); - - for result in [parent, child1] { - assert!(result.accumulated_properties().visible_history.enabled); - assert_eq!( - result.accumulated_properties().visible_history.nanos, - VisibleHistory::ALL - ); - } - - assert!(child2.accumulated_properties().visible_history.enabled); - assert_eq!( - child2.accumulated_properties().visible_history.nanos, - VisibleHistory::OFF - ); - } } #[test] diff --git a/crates/re_space_view/src/visual_time_range.rs b/crates/re_space_view/src/visual_time_range.rs new file mode 100644 index 000000000000..b07261f7b4f9 --- /dev/null +++ b/crates/re_space_view/src/visual_time_range.rs @@ -0,0 +1,114 @@ +//! For the most part this module bridges older visual history types to the newer +//! visual range types that are defined in the `re_types` crate. +//! +//! Historically there was a special `EntityProperty` bag that was used to store the visual history. +//! Now, visual history makes use of the component override system (components stored at special paths in the blueprint store). +//! +//! The intent is to eventually remove the old types, but this bridge here is there in order +//! to reduce the amount of changes in code that is likely to be refactored soon anyways. + +use re_log_types::TimeRange; +use re_query::{ExtraQueryHistory, VisibleHistory, VisibleHistoryBoundary}; +use re_types::blueprint::{ + components::VisibleTimeRange, + datatypes::{VisibleTimeRangeBoundary, VisibleTimeRangeBoundaryKind}, +}; +use re_viewer_context::{SpaceViewClassIdentifier, ViewerContext}; + +pub fn time_range_boundary_to_visible_history_boundary( + boundary: &VisibleTimeRangeBoundary, +) -> VisibleHistoryBoundary { + match boundary.kind { + VisibleTimeRangeBoundaryKind::RelativeToTimeCursor => { + VisibleHistoryBoundary::RelativeToTimeCursor(boundary.time.0) + } + VisibleTimeRangeBoundaryKind::Absolute => VisibleHistoryBoundary::Absolute(boundary.time.0), + VisibleTimeRangeBoundaryKind::Infinite => VisibleHistoryBoundary::Infinite, + } +} + +pub fn visible_history_boundary_to_time_range_boundary( + boundary: &VisibleHistoryBoundary, +) -> VisibleTimeRangeBoundary { + match boundary { + VisibleHistoryBoundary::RelativeToTimeCursor(v) => VisibleTimeRangeBoundary { + kind: VisibleTimeRangeBoundaryKind::RelativeToTimeCursor, + time: (*v).into(), + }, + VisibleHistoryBoundary::Absolute(v) => VisibleTimeRangeBoundary { + kind: VisibleTimeRangeBoundaryKind::Absolute, + time: (*v).into(), + }, + VisibleHistoryBoundary::Infinite => VisibleTimeRangeBoundary { + kind: VisibleTimeRangeBoundaryKind::Infinite, + time: 0.into(), + }, + } +} + +pub fn visible_time_range_to_time_range( + range: &VisibleTimeRange, + time_type: re_log_types::TimeType, + cursor: re_log_types::TimeInt, +) -> re_log_types::TimeRange { + let cursor = cursor.as_i64().into(); + + let mut min = match time_type { + re_log_types::TimeType::Sequence => range.0.from_sequence.start_boundary_time(cursor).0, + re_log_types::TimeType::Time => range.0.from_time.start_boundary_time(cursor).0, + }; + let mut max = match time_type { + re_log_types::TimeType::Sequence => range.0.to_sequence.end_boundary_time(cursor).0, + re_log_types::TimeType::Time => range.0.to_time.end_boundary_time(cursor).0, + }; + + if min > max { + std::mem::swap(&mut min, &mut max); + } + + TimeRange::new(min.into(), max.into()) +} + +pub fn query_visual_history( + ctx: &ViewerContext<'_>, + data_result: &re_viewer_context::DataResult, +) -> ExtraQueryHistory { + let visual_time_range_component = + data_result.lookup_override::(ctx); + if let Some(visual_time_range_component) = visual_time_range_component { + ExtraQueryHistory { + enabled: true, + nanos: VisibleHistory { + from: time_range_boundary_to_visible_history_boundary( + &visual_time_range_component.0.from_time, + ), + to: time_range_boundary_to_visible_history_boundary( + &visual_time_range_component.0.to_time, + ), + }, + sequences: VisibleHistory { + from: time_range_boundary_to_visible_history_boundary( + &visual_time_range_component.0.from_sequence, + ), + to: time_range_boundary_to_visible_history_boundary( + &visual_time_range_component.0.to_sequence, + ), + }, + } + } else { + ExtraQueryHistory { + enabled: false, + nanos: VisibleHistory::default(), + sequences: VisibleHistory::default(), + } + } +} + +// TODO(#4194): this should come from delegation to the space-view-class +pub fn default_time_range(class_identifier: SpaceViewClassIdentifier) -> VisibleTimeRange { + if class_identifier == "Time Series" { + VisibleTimeRange::EVERYTHING.clone() + } else { + VisibleTimeRange::EMPTY.clone() + } +} diff --git a/crates/re_space_view_spatial/src/visualizers/entity_iterator.rs b/crates/re_space_view_spatial/src/visualizers/entity_iterator.rs index 986c40c7db18..8b37590166dc 100644 --- a/crates/re_space_view_spatial/src/visualizers/entity_iterator.rs +++ b/crates/re_space_view_spatial/src/visualizers/entity_iterator.rs @@ -2,6 +2,7 @@ use re_entity_db::EntityProperties; use re_log_types::{EntityPath, RowId, TimeInt}; use re_query::{query_archetype_with_history, ArchetypeView, QueryError}; use re_renderer::DepthOffset; +use re_space_view::query_visual_history; use re_types::{components::InstanceKey, Archetype, Component}; use re_viewer_context::{ IdentifiedViewSystem, SpaceViewClass, SpaceViewSystemExecutionError, ViewContextCollection, @@ -71,11 +72,13 @@ where space_view_class_identifier: view_ctx.space_view_class_identifier(), }; + let extra_history = query_visual_history(ctx, data_result); + match query_archetype_with_history::( ctx.entity_db.store(), &query.timeline, &query.latest_at, - &data_result.accumulated_properties().visible_history, + &extra_history, &data_result.entity_path, ) .and_then(|arch_views| { @@ -179,11 +182,13 @@ macro_rules! impl_process_archetype { space_view_class_identifier: view_ctx.space_view_class_identifier(), }; + let extra_history = query_visual_history(ctx, data_result); + match ctx.entity_db.query_caches().[]::( ctx.entity_db.store(), &query.timeline, &query.latest_at, - &data_result.accumulated_properties().visible_history, + &extra_history, &data_result.entity_path, |(t, keys, $($pov,)+ $($comp,)*)| { counter @@ -257,11 +262,13 @@ pub fn count_instances_in_archetype_views< let mut num_instances = 0; for data_result in query.iter_visible_data_results(ctx, System::identifier()) { + let extra_history = query_visual_history(ctx, data_result); + match query_archetype_with_history::( ctx.entity_db.store(), &query.timeline, &query.latest_at, - &data_result.accumulated_properties().visible_history, + &extra_history, &data_result.entity_path, ) .map(|arch_views| { diff --git a/crates/re_space_view_time_series/src/legacy_visualizer_system.rs b/crates/re_space_view_time_series/src/legacy_visualizer_system.rs index 6d71a991ed03..bd9753f1d33c 100644 --- a/crates/re_space_view_time_series/src/legacy_visualizer_system.rs +++ b/crates/re_space_view_time_series/src/legacy_visualizer_system.rs @@ -140,6 +140,7 @@ impl LegacyTimeSeriesSystem { let mut points = Vec::new(); let time_range = determine_time_range( + ctx, query, data_result, plot_bounds, diff --git a/crates/re_space_view_time_series/src/line_visualizer_system.rs b/crates/re_space_view_time_series/src/line_visualizer_system.rs index 5672f84770f5..4668bb409c53 100644 --- a/crates/re_space_view_time_series/src/line_visualizer_system.rs +++ b/crates/re_space_view_time_series/src/line_visualizer_system.rs @@ -184,6 +184,7 @@ fn load_series( let mut points = Vec::new(); let time_range = determine_time_range( + ctx, query, data_result, plot_bounds, diff --git a/crates/re_space_view_time_series/src/point_visualizer_system.rs b/crates/re_space_view_time_series/src/point_visualizer_system.rs index f0b612798773..58a7d5423639 100644 --- a/crates/re_space_view_time_series/src/point_visualizer_system.rs +++ b/crates/re_space_view_time_series/src/point_visualizer_system.rs @@ -138,6 +138,7 @@ impl SeriesPointSystem { let mut points = Vec::new(); let time_range = determine_time_range( + ctx, query, data_result, plot_bounds, diff --git a/crates/re_space_view_time_series/src/util.rs b/crates/re_space_view_time_series/src/util.rs index d58faaeb51ee..b703b7d20ae7 100644 --- a/crates/re_space_view_time_series/src/util.rs +++ b/crates/re_space_view_time_series/src/util.rs @@ -1,10 +1,13 @@ use re_log_types::{EntityPath, TimeInt, TimeRange}; +use re_space_view::{default_time_range, visible_time_range_to_time_range}; use re_types::datatypes::Utf8; -use re_viewer_context::{external::re_entity_db::TimeSeriesAggregator, ViewQuery, ViewerContext}; +use re_viewer_context::{ + external::re_entity_db::TimeSeriesAggregator, SpaceViewClass, ViewQuery, ViewerContext, +}; use crate::{ aggregation::{AverageAggregator, MinMaxAggregator}, - PlotPoint, PlotSeries, PlotSeriesKind, ScatterAttrs, + PlotPoint, PlotSeries, PlotSeriesKind, ScatterAttrs, TimeSeriesSpaceView, }; /// Find the plot bounds and the per-ui-point delta from egui. @@ -28,26 +31,21 @@ pub fn determine_plot_bounds_and_time_per_pixel( } pub fn determine_time_range( + ctx: &ViewerContext<'_>, query: &ViewQuery<'_>, data_result: &re_viewer_context::DataResult, plot_bounds: Option, enable_query_clamping: bool, ) -> TimeRange { - let visible_history = match query.timeline.typ() { - re_log_types::TimeType::Time => data_result.accumulated_properties().visible_history.nanos, - re_log_types::TimeType::Sequence => { - data_result - .accumulated_properties() - .visible_history - .sequences - } - }; - - let mut time_range = if data_result.accumulated_properties().visible_history.enabled { - visible_history.time_range(query.latest_at) - } else { - TimeRange::new(TimeInt::MIN, TimeInt::MAX) - }; + let visible_time_range_override = data_result + .lookup_override::(ctx) + .unwrap_or(default_time_range(TimeSeriesSpaceView::identifier())); + + let mut time_range = visible_time_range_to_time_range( + &visible_time_range_override, + query.timeline.typ(), + query.latest_at, + ); // TODO(cmc): We would love to reduce the query to match the actual plot bounds, but because // the plot widget handles zoom after we provide it with data for the current frame, diff --git a/crates/re_types/definitions/rerun/blueprint.fbs b/crates/re_types/definitions/rerun/blueprint.fbs index 1d629523d648..c7056192eca7 100644 --- a/crates/re_types/definitions/rerun/blueprint.fbs +++ b/crates/re_types/definitions/rerun/blueprint.fbs @@ -1,3 +1,5 @@ +include "./blueprint/datatypes/visible_time_range.fbs"; + include "./blueprint/components/active_tab.fbs"; include "./blueprint/components/auto_layout.fbs"; include "./blueprint/components/auto_space_views.fbs"; @@ -18,6 +20,7 @@ include "./blueprint/components/space_view_class.fbs"; include "./blueprint/components/space_view_maximized.fbs"; include "./blueprint/components/space_view_origin.fbs"; include "./blueprint/components/viewer_recommendation_hash.fbs"; +include "./blueprint/components/visible_time_range.fbs"; include "./blueprint/components/visible.fbs"; include "./blueprint/archetypes/background_3d.fbs"; diff --git a/crates/re_types/definitions/rerun/blueprint/components/visible_time_range.fbs b/crates/re_types/definitions/rerun/blueprint/components/visible_time_range.fbs new file mode 100644 index 000000000000..7e71f15c0d08 --- /dev/null +++ b/crates/re_types/definitions/rerun/blueprint/components/visible_time_range.fbs @@ -0,0 +1,20 @@ +include "arrow/attributes.fbs"; +include "python/attributes.fbs"; +include "rust/attributes.fbs"; + +include "rerun/datatypes.fbs"; +include "rerun/attributes.fbs"; + +namespace rerun.blueprint.components; + +// --- + +/// The range of values that will be included in a Space View query. +table VisibleTimeRange ( + "attr.arrow.transparent", + "attr.rerun.scope": "blueprint", + "attr.rust.repr": "transparent", + "attr.rust.derive": "PartialEq, Eq" +) { + value: rerun.blueprint.datatypes.VisibleTimeRange (order: 100); +} diff --git a/crates/re_types/definitions/rerun/blueprint/datatypes/visible_time_range.fbs b/crates/re_types/definitions/rerun/blueprint/datatypes/visible_time_range.fbs new file mode 100644 index 000000000000..584a6f42366e --- /dev/null +++ b/crates/re_types/definitions/rerun/blueprint/datatypes/visible_time_range.fbs @@ -0,0 +1,58 @@ + +include "arrow/attributes.fbs"; +include "python/attributes.fbs"; +include "rust/attributes.fbs"; + +include "rerun/attributes.fbs"; + +include "../../datatypes/time_int.fbs"; + +namespace rerun.blueprint.datatypes; + +/// Kind of boundary for visible history, see `VisibleTimeRangeBoundary`. +enum VisibleTimeRangeBoundaryKind: byte ( + "attr.rerun.scope": "blueprint", + "attr.docs.unreleased" +) { + /// Boundary is a value relative to the time cursor. + RelativeToTimeCursor, + + /// Boundary is an absolute value. + Absolute, + + /// The boundary extends to infinity. + Infinite, +} + +/// Type of boundary for visible history. +struct VisibleTimeRangeBoundary ( + "attr.rerun.scope": "blueprint", + "attr.docs.unreleased" +) { + /// Type of the boundary. + kind: rerun.blueprint.datatypes.VisibleTimeRangeBoundaryKind (order: 100); + + /// Value of the boundary (ignored for `Infinite` type). + time: rerun.datatypes.TimeInt (order: 200); +} + +/// Visible time range bounds. +struct VisibleTimeRange ( + "attr.rerun.scope": "blueprint", + "attr.rust.derive": "PartialEq, Eq", + "attr.docs.unreleased" +) { + // TODO(andreas): Split this up into two separate components. + + /// Low time boundary for sequence timeline. + from_sequence: rerun.blueprint.datatypes.VisibleTimeRangeBoundary (order: 100); + + /// High time boundary for sequence timeline. + to_sequence: rerun.blueprint.datatypes.VisibleTimeRangeBoundary (order: 200); + + /// Low time boundary for time timeline. + from_time: rerun.blueprint.datatypes.VisibleTimeRangeBoundary (order: 300); + + /// High time boundary for time timeline. + to_time: rerun.blueprint.datatypes.VisibleTimeRangeBoundary (order: 400); +} diff --git a/crates/re_types/definitions/rerun/datatypes.fbs b/crates/re_types/definitions/rerun/datatypes.fbs index 3b8adb39a597..74d5fc31fea0 100644 --- a/crates/re_types/definitions/rerun/datatypes.fbs +++ b/crates/re_types/definitions/rerun/datatypes.fbs @@ -1,8 +1,8 @@ include "./datatypes/angle.fbs"; include "./datatypes/annotation_info.fbs"; include "./datatypes/bool.fbs"; -include "./datatypes/class_description.fbs"; include "./datatypes/class_description_map_elem.fbs"; +include "./datatypes/class_description.fbs"; include "./datatypes/class_id.fbs"; include "./datatypes/entity_path.fbs"; include "./datatypes/float32.fbs"; @@ -14,12 +14,13 @@ include "./datatypes/material.fbs"; include "./datatypes/mesh_properties.fbs"; include "./datatypes/quaternion.fbs"; include "./datatypes/rgba32.fbs"; -include "./datatypes/rotation3d.fbs"; include "./datatypes/rotation_axis_angle.fbs"; +include "./datatypes/rotation3d.fbs"; include "./datatypes/scale3d.fbs"; include "./datatypes/tensor_buffer.fbs"; include "./datatypes/tensor_data.fbs"; include "./datatypes/tensor_dimension.fbs"; +include "./datatypes/time_int.fbs"; include "./datatypes/transform3d.fbs"; include "./datatypes/translation_and_mat3x3.fbs"; include "./datatypes/translation_rotation_scale3d.fbs"; diff --git a/crates/re_types/definitions/rerun/datatypes/time_int.fbs b/crates/re_types/definitions/rerun/datatypes/time_int.fbs new file mode 100644 index 000000000000..dfecb256d70b --- /dev/null +++ b/crates/re_types/definitions/rerun/datatypes/time_int.fbs @@ -0,0 +1,19 @@ + +include "arrow/attributes.fbs"; +include "python/attributes.fbs"; +include "rust/attributes.fbs"; + +include "rerun/attributes.fbs"; + +namespace rerun.datatypes; + +/// A 64-bit number describing either nanoseconds OR sequence numbers. +struct TimeInt ( + "attr.docs.unreleased", + "attr.arrow.transparent", + "attr.rust.derive": "Copy, PartialEq, Eq, PartialOrd, Ord", + "attr.rust.tuple_struct", + "attr.rust.override_crate": "re_types_core" +) { + value: long (order: 100); +} diff --git a/crates/re_types/src/blueprint/components/.gitattributes b/crates/re_types/src/blueprint/components/.gitattributes index 9f8d0a8dd3bf..02afa95257cd 100644 --- a/crates/re_types/src/blueprint/components/.gitattributes +++ b/crates/re_types/src/blueprint/components/.gitattributes @@ -15,3 +15,4 @@ space_view_class.rs linguist-generated=true space_view_origin.rs linguist-generated=true viewer_recommendation_hash.rs linguist-generated=true visible.rs linguist-generated=true +visible_time_range.rs linguist-generated=true diff --git a/crates/re_types/src/blueprint/components/mod.rs b/crates/re_types/src/blueprint/components/mod.rs index 0b873668d40b..d3670e91167c 100644 --- a/crates/re_types/src/blueprint/components/mod.rs +++ b/crates/re_types/src/blueprint/components/mod.rs @@ -15,6 +15,8 @@ mod space_view_origin; mod viewer_recommendation_hash; mod visible; mod visible_ext; +mod visible_time_range; +mod visible_time_range_ext; pub use self::active_tab::ActiveTab; pub use self::background3d_kind::Background3DKind; @@ -29,3 +31,4 @@ pub use self::space_view_class::SpaceViewClass; pub use self::space_view_origin::SpaceViewOrigin; pub use self::viewer_recommendation_hash::ViewerRecommendationHash; pub use self::visible::Visible; +pub use self::visible_time_range::VisibleTimeRange; diff --git a/crates/re_types/src/blueprint/components/visible_time_range.rs b/crates/re_types/src/blueprint/components/visible_time_range.rs new file mode 100644 index 000000000000..053681357c0c --- /dev/null +++ b/crates/re_types/src/blueprint/components/visible_time_range.rs @@ -0,0 +1,153 @@ +// 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/components/visible_time_range.fbs". + +#![allow(trivial_numeric_casts)] +#![allow(unused_imports)] +#![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)] + +use ::re_types_core::external::arrow2; +use ::re_types_core::ComponentName; +use ::re_types_core::SerializationResult; +use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch}; +use ::re_types_core::{DeserializationError, DeserializationResult}; + +/// **Component**: The range of values that will be included in a Space View query. +#[derive(Clone, Debug, PartialEq, Eq)] +#[repr(transparent)] +pub struct VisibleTimeRange(pub crate::blueprint::datatypes::VisibleTimeRange); + +impl ::re_types_core::SizeBytes for VisibleTimeRange { + #[inline] + fn heap_size_bytes(&self) -> u64 { + self.0.heap_size_bytes() + } + + #[inline] + fn is_pod() -> bool { + ::is_pod() + } +} + +impl> From for VisibleTimeRange { + fn from(v: T) -> Self { + Self(v.into()) + } +} + +impl std::borrow::Borrow for VisibleTimeRange { + #[inline] + fn borrow(&self) -> &crate::blueprint::datatypes::VisibleTimeRange { + &self.0 + } +} + +impl std::ops::Deref for VisibleTimeRange { + type Target = crate::blueprint::datatypes::VisibleTimeRange; + + #[inline] + fn deref(&self) -> &crate::blueprint::datatypes::VisibleTimeRange { + &self.0 + } +} + +::re_types_core::macros::impl_into_cow!(VisibleTimeRange); + +impl ::re_types_core::Loggable for VisibleTimeRange { + type Name = ::re_types_core::ComponentName; + + #[inline] + fn name() -> Self::Name { + "rerun.blueprint.components.VisibleTimeRange".into() + } + + #[allow(clippy::wildcard_imports)] + #[inline] + fn arrow_datatype() -> arrow2::datatypes::DataType { + use arrow2::datatypes::*; + DataType::Struct(std::sync::Arc::new(vec![ + Field::new( + "from_sequence", + ::arrow_datatype(), + false, + ), + Field::new( + "to_sequence", + ::arrow_datatype(), + false, + ), + Field::new( + "from_time", + ::arrow_datatype(), + false, + ), + Field::new( + "to_time", + ::arrow_datatype(), + false, + ), + ])) + } + + #[allow(clippy::wildcard_imports)] + fn to_arrow_opt<'a>( + data: impl IntoIterator>>>, + ) -> SerializationResult> + where + Self: Clone + 'a, + { + use ::re_types_core::{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 = { + let any_nones = somes.iter().any(|some| !*some); + any_nones.then(|| somes.into()) + }; + { + _ = data0_bitmap; + crate::blueprint::datatypes::VisibleTimeRange::to_arrow_opt(data0)? + } + }) + } + + #[allow(clippy::wildcard_imports)] + fn from_arrow_opt( + arrow_data: &dyn arrow2::array::Array, + ) -> DeserializationResult>> + where + Self: Sized, + { + use ::re_types_core::{Loggable as _, ResultExt as _}; + use arrow2::{array::*, buffer::*, datatypes::*}; + Ok( + crate::blueprint::datatypes::VisibleTimeRange::from_arrow_opt(arrow_data) + .with_context("rerun.blueprint.components.VisibleTimeRange#value")? + .into_iter() + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .map(|res| res.map(|v| Some(Self(v)))) + .collect::>>>() + .with_context("rerun.blueprint.components.VisibleTimeRange#value") + .with_context("rerun.blueprint.components.VisibleTimeRange")?, + ) + } +} diff --git a/crates/re_types/src/blueprint/components/visible_time_range_ext.rs b/crates/re_types/src/blueprint/components/visible_time_range_ext.rs new file mode 100644 index 000000000000..051f3d145a13 --- /dev/null +++ b/crates/re_types/src/blueprint/components/visible_time_range_ext.rs @@ -0,0 +1,6 @@ +use super::VisibleTimeRange; + +impl VisibleTimeRange { + pub const EMPTY: Self = Self(crate::blueprint::datatypes::VisibleTimeRange::EMPTY); + pub const EVERYTHING: Self = Self(crate::blueprint::datatypes::VisibleTimeRange::EVERYTHING); +} diff --git a/crates/re_types/src/blueprint/datatypes/.gitattributes b/crates/re_types/src/blueprint/datatypes/.gitattributes index f8cc2be56035..788b8f6860a3 100644 --- a/crates/re_types/src/blueprint/datatypes/.gitattributes +++ b/crates/re_types/src/blueprint/datatypes/.gitattributes @@ -1,5 +1,7 @@ # DO NOT EDIT! This file is generated by crates/re_types_builder/src/lib.rs .gitattributes linguist-generated=true -legend.rs linguist-generated=true mod.rs linguist-generated=true +visible_time_range.rs linguist-generated=true +visible_time_range_boundary.rs linguist-generated=true +visible_time_range_boundary_kind.rs linguist-generated=true diff --git a/crates/re_types/src/blueprint/datatypes/mod.rs b/crates/re_types/src/blueprint/datatypes/mod.rs index af61829b13e1..c843412e734b 100644 --- a/crates/re_types/src/blueprint/datatypes/mod.rs +++ b/crates/re_types/src/blueprint/datatypes/mod.rs @@ -1,5 +1,11 @@ // DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/rust/api.rs -mod legend; +mod visible_time_range; +mod visible_time_range_boundary; +mod visible_time_range_boundary_ext; +mod visible_time_range_boundary_kind; +mod visible_time_range_ext; -pub use self::legend::Legend; +pub use self::visible_time_range::VisibleTimeRange; +pub use self::visible_time_range_boundary::VisibleTimeRangeBoundary; +pub use self::visible_time_range_boundary_kind::VisibleTimeRangeBoundaryKind; diff --git a/crates/re_types/src/blueprint/datatypes/visible_time_range.rs b/crates/re_types/src/blueprint/datatypes/visible_time_range.rs new file mode 100644 index 000000000000..bc1bd84fef03 --- /dev/null +++ b/crates/re_types/src/blueprint/datatypes/visible_time_range.rs @@ -0,0 +1,340 @@ +// 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/datatypes/visible_time_range.fbs". + +#![allow(trivial_numeric_casts)] +#![allow(unused_imports)] +#![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)] + +use ::re_types_core::external::arrow2; +use ::re_types_core::ComponentName; +use ::re_types_core::SerializationResult; +use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch}; +use ::re_types_core::{DeserializationError, DeserializationResult}; + +/// **Datatype**: Visible time range bounds. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct VisibleTimeRange { + /// Low time boundary for sequence timeline. + pub from_sequence: crate::blueprint::datatypes::VisibleTimeRangeBoundary, + + /// High time boundary for sequence timeline. + pub to_sequence: crate::blueprint::datatypes::VisibleTimeRangeBoundary, + + /// Low time boundary for time timeline. + pub from_time: crate::blueprint::datatypes::VisibleTimeRangeBoundary, + + /// High time boundary for time timeline. + pub to_time: crate::blueprint::datatypes::VisibleTimeRangeBoundary, +} + +impl ::re_types_core::SizeBytes for VisibleTimeRange { + #[inline] + fn heap_size_bytes(&self) -> u64 { + self.from_sequence.heap_size_bytes() + + self.to_sequence.heap_size_bytes() + + self.from_time.heap_size_bytes() + + self.to_time.heap_size_bytes() + } + + #[inline] + fn is_pod() -> bool { + ::is_pod() + && ::is_pod() + && ::is_pod() + && ::is_pod() + } +} + +::re_types_core::macros::impl_into_cow!(VisibleTimeRange); + +impl ::re_types_core::Loggable for VisibleTimeRange { + type Name = ::re_types_core::DatatypeName; + + #[inline] + fn name() -> Self::Name { + "rerun.blueprint.datatypes.VisibleTimeRange".into() + } + + #[allow(clippy::wildcard_imports)] + #[inline] + fn arrow_datatype() -> arrow2::datatypes::DataType { + use arrow2::datatypes::*; + DataType::Struct(std::sync::Arc::new(vec![ + Field::new( + "from_sequence", + ::arrow_datatype(), + false, + ), + Field::new( + "to_sequence", + ::arrow_datatype(), + false, + ), + Field::new( + "from_time", + ::arrow_datatype(), + false, + ), + Field::new( + "to_time", + ::arrow_datatype(), + false, + ), + ])) + } + + #[allow(clippy::wildcard_imports)] + fn to_arrow_opt<'a>( + data: impl IntoIterator>>>, + ) -> SerializationResult> + where + Self: Clone + 'a, + { + use ::re_types_core::{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 = { + let any_nones = somes.iter().any(|some| !*some); + any_nones.then(|| somes.into()) + }; + StructArray::new( + ::arrow_datatype(), + vec![ + { + let (somes, from_sequence): (Vec<_>, Vec<_>) = data + .iter() + .map(|datum| { + let datum = datum.as_ref().map(|datum| { + let Self { from_sequence, .. } = &**datum; + from_sequence.clone() + }); + (datum.is_some(), datum) + }) + .unzip(); + let from_sequence_bitmap: Option = { + let any_nones = somes.iter().any(|some| !*some); + any_nones.then(|| somes.into()) + }; + { + _ = from_sequence_bitmap; + crate::blueprint::datatypes::VisibleTimeRangeBoundary::to_arrow_opt( + from_sequence, + )? + } + }, + { + let (somes, to_sequence): (Vec<_>, Vec<_>) = data + .iter() + .map(|datum| { + let datum = datum.as_ref().map(|datum| { + let Self { to_sequence, .. } = &**datum; + to_sequence.clone() + }); + (datum.is_some(), datum) + }) + .unzip(); + let to_sequence_bitmap: Option = { + let any_nones = somes.iter().any(|some| !*some); + any_nones.then(|| somes.into()) + }; + { + _ = to_sequence_bitmap; + crate::blueprint::datatypes::VisibleTimeRangeBoundary::to_arrow_opt( + to_sequence, + )? + } + }, + { + let (somes, from_time): (Vec<_>, Vec<_>) = data + .iter() + .map(|datum| { + let datum = datum.as_ref().map(|datum| { + let Self { from_time, .. } = &**datum; + from_time.clone() + }); + (datum.is_some(), datum) + }) + .unzip(); + let from_time_bitmap: Option = { + let any_nones = somes.iter().any(|some| !*some); + any_nones.then(|| somes.into()) + }; + { + _ = from_time_bitmap; + crate::blueprint::datatypes::VisibleTimeRangeBoundary::to_arrow_opt( + from_time, + )? + } + }, + { + let (somes, to_time): (Vec<_>, Vec<_>) = data + .iter() + .map(|datum| { + let datum = datum.as_ref().map(|datum| { + let Self { to_time, .. } = &**datum; + to_time.clone() + }); + (datum.is_some(), datum) + }) + .unzip(); + let to_time_bitmap: Option = { + let any_nones = somes.iter().any(|some| !*some); + any_nones.then(|| somes.into()) + }; + { + _ = to_time_bitmap; + crate::blueprint::datatypes::VisibleTimeRangeBoundary::to_arrow_opt( + to_time, + )? + } + }, + ], + bitmap, + ) + .boxed() + }) + } + + #[allow(clippy::wildcard_imports)] + fn from_arrow_opt( + arrow_data: &dyn arrow2::array::Array, + ) -> DeserializationResult>> + where + Self: Sized, + { + use ::re_types_core::{Loggable as _, ResultExt as _}; + use arrow2::{array::*, buffer::*, datatypes::*}; + Ok({ + let arrow_data = arrow_data + .as_any() + .downcast_ref::() + .ok_or_else(|| { + let expected = Self::arrow_datatype(); + let actual = arrow_data.data_type().clone(); + DeserializationError::datatype_mismatch(expected, actual) + }) + .with_context("rerun.blueprint.datatypes.VisibleTimeRange")?; + 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 from_sequence = { + if !arrays_by_name.contains_key("from_sequence") { + return Err(DeserializationError::missing_struct_field( + Self::arrow_datatype(), + "from_sequence", + )) + .with_context("rerun.blueprint.datatypes.VisibleTimeRange"); + } + let arrow_data = &**arrays_by_name["from_sequence"]; + crate::blueprint::datatypes::VisibleTimeRangeBoundary::from_arrow_opt( + arrow_data, + ) + .with_context("rerun.blueprint.datatypes.VisibleTimeRange#from_sequence")? + .into_iter() + }; + let to_sequence = { + if !arrays_by_name.contains_key("to_sequence") { + return Err(DeserializationError::missing_struct_field( + Self::arrow_datatype(), + "to_sequence", + )) + .with_context("rerun.blueprint.datatypes.VisibleTimeRange"); + } + let arrow_data = &**arrays_by_name["to_sequence"]; + crate::blueprint::datatypes::VisibleTimeRangeBoundary::from_arrow_opt( + arrow_data, + ) + .with_context("rerun.blueprint.datatypes.VisibleTimeRange#to_sequence")? + .into_iter() + }; + let from_time = { + if !arrays_by_name.contains_key("from_time") { + return Err(DeserializationError::missing_struct_field( + Self::arrow_datatype(), + "from_time", + )) + .with_context("rerun.blueprint.datatypes.VisibleTimeRange"); + } + let arrow_data = &**arrays_by_name["from_time"]; + crate::blueprint::datatypes::VisibleTimeRangeBoundary::from_arrow_opt( + arrow_data, + ) + .with_context("rerun.blueprint.datatypes.VisibleTimeRange#from_time")? + .into_iter() + }; + let to_time = { + if !arrays_by_name.contains_key("to_time") { + return Err(DeserializationError::missing_struct_field( + Self::arrow_datatype(), + "to_time", + )) + .with_context("rerun.blueprint.datatypes.VisibleTimeRange"); + } + let arrow_data = &**arrays_by_name["to_time"]; + crate::blueprint::datatypes::VisibleTimeRangeBoundary::from_arrow_opt( + arrow_data, + ) + .with_context("rerun.blueprint.datatypes.VisibleTimeRange#to_time")? + .into_iter() + }; + arrow2::bitmap::utils::ZipValidity::new_with_validity( + ::itertools::izip!(from_sequence, to_sequence, from_time, to_time), + arrow_data.validity(), + ) + .map(|opt| { + opt.map(|(from_sequence, to_sequence, from_time, to_time)| { + Ok(Self { + from_sequence: from_sequence + .ok_or_else(DeserializationError::missing_data) + .with_context( + "rerun.blueprint.datatypes.VisibleTimeRange#from_sequence", + )?, + to_sequence: to_sequence + .ok_or_else(DeserializationError::missing_data) + .with_context( + "rerun.blueprint.datatypes.VisibleTimeRange#to_sequence", + )?, + from_time: from_time + .ok_or_else(DeserializationError::missing_data) + .with_context( + "rerun.blueprint.datatypes.VisibleTimeRange#from_time", + )?, + to_time: to_time + .ok_or_else(DeserializationError::missing_data) + .with_context( + "rerun.blueprint.datatypes.VisibleTimeRange#to_time", + )?, + }) + }) + .transpose() + }) + .collect::>>() + .with_context("rerun.blueprint.datatypes.VisibleTimeRange")? + } + }) + } +} diff --git a/crates/re_types/src/blueprint/datatypes/legend.rs b/crates/re_types/src/blueprint/datatypes/visible_time_range_boundary.rs similarity index 53% rename from crates/re_types/src/blueprint/datatypes/legend.rs rename to crates/re_types/src/blueprint/datatypes/visible_time_range_boundary.rs index a75e3bc464e4..2307d5fcf906 100644 --- a/crates/re_types/src/blueprint/datatypes/legend.rs +++ b/crates/re_types/src/blueprint/datatypes/visible_time_range_boundary.rs @@ -1,5 +1,5 @@ // 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/datatypes/legend.fbs". +// Based on "crates/re_types/definitions/rerun/blueprint/datatypes/visible_time_range.fbs". #![allow(trivial_numeric_casts)] #![allow(unused_imports)] @@ -21,42 +21,37 @@ use ::re_types_core::SerializationResult; use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch}; use ::re_types_core::{DeserializationError, DeserializationResult}; -/// **Datatype**: Configuration for the legend of a plot. -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub struct Legend { - /// Whether or not the legend should be displayed. - pub visible: bool, +/// **Datatype**: Type of boundary for visible history. +#[derive(Clone, Debug)] +pub struct VisibleTimeRangeBoundary { + /// Type of the boundary. + pub kind: crate::blueprint::datatypes::VisibleTimeRangeBoundaryKind, - /// Where should the legend be located. - /// - /// Allowed values: - /// - LeftTop = 1, - /// - RightTop = 2, - /// - LeftBottom = 3, - /// - RightBottom = 4 - pub location: Option, + /// Value of the boundary (ignored for `Infinite` type). + pub time: crate::datatypes::TimeInt, } -impl ::re_types_core::SizeBytes for Legend { +impl ::re_types_core::SizeBytes for VisibleTimeRangeBoundary { #[inline] fn heap_size_bytes(&self) -> u64 { - self.visible.heap_size_bytes() + self.location.heap_size_bytes() + self.kind.heap_size_bytes() + self.time.heap_size_bytes() } #[inline] fn is_pod() -> bool { - ::is_pod() && >::is_pod() + ::is_pod() + && ::is_pod() } } -::re_types_core::macros::impl_into_cow!(Legend); +::re_types_core::macros::impl_into_cow!(VisibleTimeRangeBoundary); -impl ::re_types_core::Loggable for Legend { +impl ::re_types_core::Loggable for VisibleTimeRangeBoundary { type Name = ::re_types_core::DatatypeName; #[inline] fn name() -> Self::Name { - "rerun.blueprint.datatypes.Legend".into() + "rerun.blueprint.datatypes.VisibleTimeRangeBoundary".into() } #[allow(clippy::wildcard_imports)] @@ -64,18 +59,12 @@ impl ::re_types_core::Loggable for Legend { fn arrow_datatype() -> arrow2::datatypes::DataType { use arrow2::datatypes::*; DataType::Struct(std::sync::Arc::new(vec![ - Field { - name: "visible".to_owned(), - data_type: DataType::Boolean, - is_nullable: false, - metadata: [].into(), - }, - Field { - name: "location".to_owned(), - data_type: DataType::UInt8, - is_nullable: true, - metadata: [].into(), - }, + Field::new( + "kind", + ::arrow_datatype(), + false, + ), + Field::new("time", ::arrow_datatype(), false), ])) } @@ -101,55 +90,58 @@ impl ::re_types_core::Loggable for Legend { any_nones.then(|| somes.into()) }; StructArray::new( - ::arrow_datatype(), + ::arrow_datatype(), vec![ { - let (somes, visible): (Vec<_>, Vec<_>) = data + let (somes, kind): (Vec<_>, Vec<_>) = data .iter() .map(|datum| { let datum = datum.as_ref().map(|datum| { - let Self { visible, .. } = &**datum; - visible.clone() + let Self { kind, .. } = &**datum; + kind.clone() }); (datum.is_some(), datum) }) .unzip(); - let visible_bitmap: Option = { + let kind_bitmap: Option = { let any_nones = somes.iter().any(|some| !*some); any_nones.then(|| somes.into()) }; - BooleanArray::new( - DataType::Boolean, - visible.into_iter().map(|v| v.unwrap_or_default()).collect(), - visible_bitmap, - ) - .boxed() + { + _ = kind_bitmap; + crate::blueprint::datatypes::VisibleTimeRangeBoundaryKind::to_arrow_opt( + kind, + )? + } }, { - let (somes, location): (Vec<_>, Vec<_>) = data + let (somes, time): (Vec<_>, Vec<_>) = data .iter() .map(|datum| { - let datum = datum - .as_ref() - .map(|datum| { - let Self { location, .. } = &**datum; - location.clone() - }) - .flatten(); + let datum = datum.as_ref().map(|datum| { + let Self { time, .. } = &**datum; + time.clone() + }); (datum.is_some(), datum) }) .unzip(); - let location_bitmap: Option = { + let time_bitmap: Option = { let any_nones = somes.iter().any(|some| !*some); any_nones.then(|| somes.into()) }; PrimitiveArray::new( - DataType::UInt8, - location - .into_iter() - .map(|v| v.unwrap_or_default()) + DataType::Int64, + time.into_iter() + .map(|datum| { + datum + .map(|datum| { + let crate::datatypes::TimeInt(data0) = datum; + data0 + }) + .unwrap_or_default() + }) .collect(), - location_bitmap, + time_bitmap, ) .boxed() }, @@ -174,25 +166,11 @@ impl ::re_types_core::Loggable for Legend { .as_any() .downcast_ref::() .ok_or_else(|| { - DeserializationError::datatype_mismatch( - DataType::Struct(std::sync::Arc::new(vec![ - Field { - name: "visible".to_owned(), - data_type: DataType::Boolean, - is_nullable: false, - metadata: [].into(), - }, - Field { - name: "location".to_owned(), - data_type: DataType::UInt8, - is_nullable: true, - metadata: [].into(), - }, - ])), - arrow_data.data_type().clone(), - ) + let expected = Self::arrow_datatype(); + let actual = arrow_data.data_type().clone(); + DeserializationError::datatype_mismatch(expected, actual) }) - .with_context("rerun.blueprint.datatypes.Legend")?; + .with_context("rerun.blueprint.datatypes.VisibleTimeRangeBoundary")?; if arrow_data.is_empty() { Vec::new() } else { @@ -203,66 +181,66 @@ impl ::re_types_core::Loggable for Legend { .map(|field| field.name.as_str()) .zip(arrow_data_arrays) .collect(); - let visible = { - if !arrays_by_name.contains_key("visible") { + let kind = { + if !arrays_by_name.contains_key("kind") { return Err(DeserializationError::missing_struct_field( Self::arrow_datatype(), - "visible", + "kind", )) - .with_context("rerun.blueprint.datatypes.Legend"); + .with_context("rerun.blueprint.datatypes.VisibleTimeRangeBoundary"); } - let arrow_data = &**arrays_by_name["visible"]; - arrow_data - .as_any() - .downcast_ref::() - .ok_or_else(|| { - DeserializationError::datatype_mismatch( - DataType::Boolean, - arrow_data.data_type().clone(), - ) - }) - .with_context("rerun.blueprint.datatypes.Legend#visible")? - .into_iter() + let arrow_data = &**arrays_by_name["kind"]; + crate::blueprint::datatypes::VisibleTimeRangeBoundaryKind::from_arrow_opt( + arrow_data, + ) + .with_context("rerun.blueprint.datatypes.VisibleTimeRangeBoundary#kind")? + .into_iter() }; - let location = { - if !arrays_by_name.contains_key("location") { + let time = { + if !arrays_by_name.contains_key("time") { return Err(DeserializationError::missing_struct_field( Self::arrow_datatype(), - "location", + "time", )) - .with_context("rerun.blueprint.datatypes.Legend"); + .with_context("rerun.blueprint.datatypes.VisibleTimeRangeBoundary"); } - let arrow_data = &**arrays_by_name["location"]; + let arrow_data = &**arrays_by_name["time"]; arrow_data .as_any() - .downcast_ref::() + .downcast_ref::() .ok_or_else(|| { - DeserializationError::datatype_mismatch( - DataType::UInt8, - arrow_data.data_type().clone(), - ) + let expected = DataType::Int64; + let actual = arrow_data.data_type().clone(); + DeserializationError::datatype_mismatch(expected, actual) }) - .with_context("rerun.blueprint.datatypes.Legend#location")? + .with_context("rerun.blueprint.datatypes.VisibleTimeRangeBoundary#time")? .into_iter() .map(|opt| opt.copied()) + .map(|res_or_opt| res_or_opt.map(|v| crate::datatypes::TimeInt(v))) }; arrow2::bitmap::utils::ZipValidity::new_with_validity( - ::itertools::izip!(visible, location), + ::itertools::izip!(kind, time), arrow_data.validity(), ) .map(|opt| { - opt.map(|(visible, location)| { + opt.map(|(kind, time)| { Ok(Self { - visible: visible + kind: kind + .ok_or_else(DeserializationError::missing_data) + .with_context( + "rerun.blueprint.datatypes.VisibleTimeRangeBoundary#kind", + )?, + time: time .ok_or_else(DeserializationError::missing_data) - .with_context("rerun.blueprint.datatypes.Legend#visible")?, - location, + .with_context( + "rerun.blueprint.datatypes.VisibleTimeRangeBoundary#time", + )?, }) }) .transpose() }) .collect::>>() - .with_context("rerun.blueprint.datatypes.Legend")? + .with_context("rerun.blueprint.datatypes.VisibleTimeRangeBoundary")? } }) } diff --git a/crates/re_types/src/blueprint/datatypes/visible_time_range_boundary_ext.rs b/crates/re_types/src/blueprint/datatypes/visible_time_range_boundary_ext.rs new file mode 100644 index 000000000000..a93c32dce2be --- /dev/null +++ b/crates/re_types/src/blueprint/datatypes/visible_time_range_boundary_ext.rs @@ -0,0 +1,47 @@ +use super::{VisibleTimeRangeBoundary, VisibleTimeRangeBoundaryKind}; +use re_types_core::datatypes::TimeInt; + +impl VisibleTimeRangeBoundary { + pub const AT_CURSOR: Self = Self { + kind: VisibleTimeRangeBoundaryKind::RelativeToTimeCursor, + time: TimeInt(0), + }; + + pub const INFINITE: Self = Self { + kind: VisibleTimeRangeBoundaryKind::Infinite, + time: TimeInt(0), + }; + + /// Returns the time assuming this boundary is a start boundary. + pub fn start_boundary_time(&self, cursor: TimeInt) -> TimeInt { + match self.kind { + VisibleTimeRangeBoundaryKind::Absolute => self.time, + VisibleTimeRangeBoundaryKind::RelativeToTimeCursor => TimeInt(cursor.0 + self.time.0), + VisibleTimeRangeBoundaryKind::Infinite => TimeInt::MIN, + } + } + + /// Returns the correct time assuming this boundary is an end boundary. + pub fn end_boundary_time(&self, cursor: TimeInt) -> TimeInt { + match self.kind { + VisibleTimeRangeBoundaryKind::Absolute => self.time, + VisibleTimeRangeBoundaryKind::RelativeToTimeCursor => TimeInt(cursor.0 + self.time.0), + VisibleTimeRangeBoundaryKind::Infinite => TimeInt::MAX, + } + } +} + +impl PartialEq for VisibleTimeRangeBoundary { + fn eq(&self, other: &Self) -> bool { + match self.kind { + VisibleTimeRangeBoundaryKind::Absolute + | VisibleTimeRangeBoundaryKind::RelativeToTimeCursor => { + other.kind == self.kind && other.time == self.time + } + // Ignore the time value for infinite boundaries. + VisibleTimeRangeBoundaryKind::Infinite => other.kind == self.kind, + } + } +} + +impl Eq for VisibleTimeRangeBoundary {} diff --git a/crates/re_types/src/blueprint/datatypes/visible_time_range_boundary_kind.rs b/crates/re_types/src/blueprint/datatypes/visible_time_range_boundary_kind.rs new file mode 100644 index 000000000000..46b3d8f37750 --- /dev/null +++ b/crates/re_types/src/blueprint/datatypes/visible_time_range_boundary_kind.rs @@ -0,0 +1,166 @@ +// 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/datatypes/visible_time_range.fbs". + +#![allow(trivial_numeric_casts)] +#![allow(unused_imports)] +#![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)] + +use ::re_types_core::external::arrow2; +use ::re_types_core::ComponentName; +use ::re_types_core::SerializationResult; +use ::re_types_core::{ComponentBatch, MaybeOwnedComponentBatch}; +use ::re_types_core::{DeserializationError, DeserializationResult}; + +/// **Datatype**: Kind of boundary for visible history, see `VisibleTimeRangeBoundary`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum VisibleTimeRangeBoundaryKind { + /// Boundary is a value relative to the time cursor. + RelativeToTimeCursor = 1, + + /// Boundary is an absolute value. + Absolute = 2, + + /// The boundary extends to infinity. + Infinite = 3, +} + +impl VisibleTimeRangeBoundaryKind { + /// All the different enum variants. + pub const ALL: [Self; 3] = [Self::RelativeToTimeCursor, Self::Absolute, Self::Infinite]; +} + +impl ::re_types_core::SizeBytes for VisibleTimeRangeBoundaryKind { + #[inline] + fn heap_size_bytes(&self) -> u64 { + 0 + } + + #[inline] + fn is_pod() -> bool { + true + } +} + +impl std::fmt::Display for VisibleTimeRangeBoundaryKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::RelativeToTimeCursor => write!(f, "RelativeToTimeCursor"), + Self::Absolute => write!(f, "Absolute"), + Self::Infinite => write!(f, "Infinite"), + } + } +} + +::re_types_core::macros::impl_into_cow!(VisibleTimeRangeBoundaryKind); + +impl ::re_types_core::Loggable for VisibleTimeRangeBoundaryKind { + type Name = ::re_types_core::DatatypeName; + + #[inline] + fn name() -> Self::Name { + "rerun.blueprint.datatypes.VisibleTimeRangeBoundaryKind".into() + } + + #[allow(clippy::wildcard_imports)] + #[inline] + fn arrow_datatype() -> arrow2::datatypes::DataType { + use arrow2::datatypes::*; + DataType::Union( + std::sync::Arc::new(vec![ + Field::new("_null_markers", DataType::Null, true), + Field::new("RelativeToTimeCursor", DataType::Null, true), + Field::new("Absolute", DataType::Null, true), + Field::new("Infinite", DataType::Null, true), + ]), + Some(std::sync::Arc::new(vec![0i32, 1i32, 2i32, 3i32])), + UnionMode::Sparse, + ) + } + + #[allow(clippy::wildcard_imports)] + fn to_arrow_opt<'a>( + data: impl IntoIterator>>>, + ) -> SerializationResult> + where + Self: Clone + 'a, + { + use ::re_types_core::{Loggable as _, ResultExt as _}; + use arrow2::{array::*, datatypes::*}; + Ok({ + let data: Vec<_> = data + .into_iter() + .map(|datum| { + let datum: Option<::std::borrow::Cow<'a, Self>> = datum.map(Into::into); + datum + }) + .collect(); + let num_variants = 3usize; + let types = data + .iter() + .map(|a| match a.as_deref() { + None => 0, + Some(value) => *value as i8, + }) + .collect(); + let fields: Vec<_> = + std::iter::repeat(NullArray::new(DataType::Null, data.len()).boxed()) + .take(1 + num_variants) + .collect(); + UnionArray::new( + ::arrow_datatype(), + types, + fields, + None, + ) + .boxed() + }) + } + + #[allow(clippy::wildcard_imports)] + fn from_arrow_opt( + arrow_data: &dyn arrow2::array::Array, + ) -> DeserializationResult>> + where + Self: Sized, + { + use ::re_types_core::{Loggable as _, ResultExt as _}; + use arrow2::{array::*, buffer::*, datatypes::*}; + Ok({ + let arrow_data = arrow_data + .as_any() + .downcast_ref::() + .ok_or_else(|| { + let expected = Self::arrow_datatype(); + let actual = arrow_data.data_type().clone(); + DeserializationError::datatype_mismatch(expected, actual) + }) + .with_context("rerun.blueprint.datatypes.VisibleTimeRangeBoundaryKind")?; + let arrow_data_types = arrow_data.types(); + arrow_data_types + .iter() + .map(|typ| match typ { + 0 => Ok(None), + 1 => Ok(Some(VisibleTimeRangeBoundaryKind::RelativeToTimeCursor)), + 2 => Ok(Some(VisibleTimeRangeBoundaryKind::Absolute)), + 3 => Ok(Some(VisibleTimeRangeBoundaryKind::Infinite)), + _ => Err(DeserializationError::missing_union_arm( + Self::arrow_datatype(), + "", + *typ as _, + )), + }) + .collect::>>() + .with_context("rerun.blueprint.datatypes.VisibleTimeRangeBoundaryKind")? + }) + } +} diff --git a/crates/re_types/src/blueprint/datatypes/visible_time_range_ext.rs b/crates/re_types/src/blueprint/datatypes/visible_time_range_ext.rs new file mode 100644 index 000000000000..d558b143e343 --- /dev/null +++ b/crates/re_types/src/blueprint/datatypes/visible_time_range_ext.rs @@ -0,0 +1,17 @@ +use super::{VisibleTimeRange, VisibleTimeRangeBoundary}; + +impl VisibleTimeRange { + pub const EMPTY: Self = Self { + from_sequence: VisibleTimeRangeBoundary::AT_CURSOR, + to_sequence: VisibleTimeRangeBoundary::AT_CURSOR, + from_time: VisibleTimeRangeBoundary::AT_CURSOR, + to_time: VisibleTimeRangeBoundary::AT_CURSOR, + }; + + pub const EVERYTHING: Self = Self { + from_sequence: VisibleTimeRangeBoundary::INFINITE, + to_sequence: VisibleTimeRangeBoundary::INFINITE, + from_time: VisibleTimeRangeBoundary::INFINITE, + to_time: VisibleTimeRangeBoundary::INFINITE, + }; +} diff --git a/crates/re_types_builder/src/codegen/python/mod.rs b/crates/re_types_builder/src/codegen/python/mod.rs index 41769667124e..d9dd3d71402a 100644 --- a/crates/re_types_builder/src/codegen/python/mod.rs +++ b/crates/re_types_builder/src/codegen/python/mod.rs @@ -587,7 +587,7 @@ fn code_for_struct( if obj.is_delegating_component() { let delegate = obj.delegate_datatype(objects).unwrap(); let scope = match delegate.scope() { - Some(scope) => format!("{scope}."), + Some(scope) => format!("{scope}_"), None => String::new(), }; superclasses.push(format!( diff --git a/crates/re_types_core/src/datatypes/.gitattributes b/crates/re_types_core/src/datatypes/.gitattributes index 5d1c22973176..8d8025b30391 100644 --- a/crates/re_types_core/src/datatypes/.gitattributes +++ b/crates/re_types_core/src/datatypes/.gitattributes @@ -4,6 +4,7 @@ entity_path.rs linguist-generated=true float32.rs linguist-generated=true mod.rs linguist-generated=true +time_int.rs linguist-generated=true uint32.rs linguist-generated=true uint64.rs linguist-generated=true utf8.rs linguist-generated=true diff --git a/crates/re_types_core/src/datatypes/mod.rs b/crates/re_types_core/src/datatypes/mod.rs index dd64cf5f950c..b3afd8508146 100644 --- a/crates/re_types_core/src/datatypes/mod.rs +++ b/crates/re_types_core/src/datatypes/mod.rs @@ -2,6 +2,8 @@ mod entity_path; mod float32; +mod time_int; +mod time_int_ext; mod uint32; mod uint64; mod utf8; @@ -9,6 +11,7 @@ mod utf8_ext; pub use self::entity_path::EntityPath; pub use self::float32::Float32; +pub use self::time_int::TimeInt; pub use self::uint32::UInt32; pub use self::uint64::UInt64; pub use self::utf8::Utf8; diff --git a/crates/re_types_core/src/datatypes/time_int.rs b/crates/re_types_core/src/datatypes/time_int.rs new file mode 100644 index 000000000000..1f488806ca0d --- /dev/null +++ b/crates/re_types_core/src/datatypes/time_int.rs @@ -0,0 +1,131 @@ +// 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/datatypes/time_int.fbs". + +#![allow(trivial_numeric_casts)] +#![allow(unused_imports)] +#![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)] + +use crate::external::arrow2; +use crate::ComponentName; +use crate::SerializationResult; +use crate::{ComponentBatch, MaybeOwnedComponentBatch}; +use crate::{DeserializationError, DeserializationResult}; + +/// **Datatype**: A 64-bit number describing either nanoseconds OR sequence numbers. +#[derive(Clone, Debug, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct TimeInt(pub i64); + +impl crate::SizeBytes for TimeInt { + #[inline] + fn heap_size_bytes(&self) -> u64 { + self.0.heap_size_bytes() + } + + #[inline] + fn is_pod() -> bool { + ::is_pod() + } +} + +impl From for TimeInt { + #[inline] + fn from(value: i64) -> Self { + Self(value) + } +} + +impl From for i64 { + #[inline] + fn from(value: TimeInt) -> Self { + value.0 + } +} + +crate::macros::impl_into_cow!(TimeInt); + +impl crate::Loggable for TimeInt { + type Name = crate::DatatypeName; + + #[inline] + fn name() -> Self::Name { + "rerun.datatypes.TimeInt".into() + } + + #[allow(clippy::wildcard_imports)] + #[inline] + fn arrow_datatype() -> arrow2::datatypes::DataType { + use arrow2::datatypes::*; + DataType::Int64 + } + + #[allow(clippy::wildcard_imports)] + fn to_arrow_opt<'a>( + data: impl IntoIterator>>>, + ) -> SerializationResult> + where + Self: Clone + 'a, + { + 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 = { + let any_nones = somes.iter().any(|some| !*some); + any_nones.then(|| somes.into()) + }; + PrimitiveArray::new( + Self::arrow_datatype(), + data0.into_iter().map(|v| v.unwrap_or_default()).collect(), + data0_bitmap, + ) + .boxed() + }) + } + + #[allow(clippy::wildcard_imports)] + fn from_arrow_opt( + arrow_data: &dyn arrow2::array::Array, + ) -> DeserializationResult>> + where + Self: Sized, + { + use crate::{Loggable as _, ResultExt as _}; + use arrow2::{array::*, buffer::*, datatypes::*}; + Ok(arrow_data + .as_any() + .downcast_ref::() + .ok_or_else(|| { + let expected = Self::arrow_datatype(); + let actual = arrow_data.data_type().clone(); + DeserializationError::datatype_mismatch(expected, actual) + }) + .with_context("rerun.datatypes.TimeInt#value")? + .into_iter() + .map(|opt| opt.copied()) + .map(|v| v.ok_or_else(DeserializationError::missing_data)) + .map(|res| res.map(|v| Some(Self(v)))) + .collect::>>>() + .with_context("rerun.datatypes.TimeInt#value") + .with_context("rerun.datatypes.TimeInt")?) + } +} diff --git a/crates/re_types_core/src/datatypes/time_int_ext.rs b/crates/re_types_core/src/datatypes/time_int_ext.rs new file mode 100644 index 000000000000..511f0efc2676 --- /dev/null +++ b/crates/re_types_core/src/datatypes/time_int_ext.rs @@ -0,0 +1,6 @@ +use super::TimeInt; + +impl TimeInt { + pub const MIN: Self = Self(i64::MIN); + pub const MAX: Self = Self(i64::MAX); +} diff --git a/crates/re_viewer/src/blueprint/validation_gen/mod.rs b/crates/re_viewer/src/blueprint/validation_gen/mod.rs index e33d2eb05e11..032557e39f0a 100644 --- a/crates/re_viewer/src/blueprint/validation_gen/mod.rs +++ b/crates/re_viewer/src/blueprint/validation_gen/mod.rs @@ -15,6 +15,7 @@ pub use re_types::blueprint::components::SpaceViewClass; pub use re_types::blueprint::components::SpaceViewOrigin; pub use re_types::blueprint::components::ViewerRecommendationHash; pub use re_types::blueprint::components::Visible; +pub use re_types::blueprint::components::VisibleTimeRange; pub use re_viewport::blueprint::components::AutoLayout; pub use re_viewport::blueprint::components::AutoSpaceViews; pub use re_viewport::blueprint::components::ContainerKind; @@ -48,4 +49,5 @@ pub fn is_valid_blueprint(blueprint: &EntityDb) -> bool { && validate_component::(blueprint) && validate_component::(blueprint) && validate_component::(blueprint) + && validate_component::(blueprint) } diff --git a/crates/re_viewer/src/ui/selection_panel.rs b/crates/re_viewer/src/ui/selection_panel.rs index 7368804694ba..9dd09ffad9e8 100644 --- a/crates/re_viewer/src/ui/selection_panel.rs +++ b/crates/re_viewer/src/ui/selection_panel.rs @@ -26,9 +26,9 @@ use re_viewport::{ }; use crate::ui::override_ui::override_ui; -use crate::ui::{override_ui::override_visualizer_ui, visible_history::visible_history_ui}; +use crate::ui::override_ui::override_visualizer_ui; -use super::selection_history_ui::SelectionHistoryUi; +use super::{selection_history_ui::SelectionHistoryUi, visible_history::visual_time_range_ui}; // --- @@ -837,34 +837,42 @@ fn blueprint_ui_for_space_view( ui.add_space(ui.spacing().item_spacing.y / 2.0); if let Some(space_view) = viewport.blueprint.space_view(space_view_id) { - let space_view_class = *space_view.class_identifier(); + let class_identifier = *space_view.class_identifier(); let space_view_state = viewport.state.space_view_state_mut( ctx.space_view_class_registry, space_view.id, - space_view.class_identifier(), + &class_identifier, ); // Space View don't inherit properties. let root_data_result = space_view.root_data_result(ctx.store_context, ctx.blueprint_query); - let mut props = root_data_result - .individual_properties() - .cloned() - .unwrap_or_default(); + let query_result = ctx.lookup_query_result(space_view.id); + let Some(data_result) = query_result + .tree + .root_handle() + .and_then(|root| query_result.tree.lookup_result(root)) + else { + re_log::error!("Could not find root data result for Space View {space_view_id:?}"); + return; + }; - visible_history_ui( + visual_time_range_ui( ctx, ui, - &space_view_class, + &query_result.tree, + data_result, + class_identifier, true, - None, - &mut props.visible_history, - &root_data_result.accumulated_properties().visible_history, ); - let space_view_class = space_view.class(ctx.space_view_class_registry); + let mut props = root_data_result + .individual_properties() + .cloned() + .unwrap_or_default(); + let space_view_class = space_view.class(ctx.space_view_class_registry); if let Err(err) = space_view_class.selection_ui( ctx, ui, @@ -880,7 +888,7 @@ fn blueprint_ui_for_space_view( ); } - root_data_result.save_individual_override(Some(props), ctx); + root_data_result.save_individual_override_properties(ctx, Some(props)); } } @@ -915,9 +923,8 @@ fn blueprint_ui_for_data_result( &space_view_class, entity_path, &mut props, - data_result.accumulated_properties(), ); - data_result.save_individual_override(Some(props), ctx); + data_result.save_individual_override_properties(ctx, Some(props)); } } } @@ -1073,7 +1080,6 @@ fn entity_props_ui( space_view_class: &SpaceViewClassIdentifier, entity_path: &EntityPath, entity_props: &mut EntityProperties, - resolved_entity_props: &EntityProperties, ) { use re_types::blueprint::components::Visible; use re_types::Loggable as _; @@ -1112,14 +1118,13 @@ fn entity_props_ui( .checkbox(ui, &mut entity_props.interactive, "Interactive") .on_hover_text("If disabled, the entity will not react to any mouse interaction"); - visible_history_ui( + visual_time_range_ui( ctx, ui, - space_view_class, + &query_result.tree, + data_result, + *space_view_class, false, - Some(entity_path), - &mut entity_props.visible_history, - &resolved_entity_props.visible_history, ); egui::Grid::new("entity_properties") diff --git a/crates/re_viewer/src/ui/visible_history.rs b/crates/re_viewer/src/ui/visible_history.rs index 831f2f4fd4ee..f223f3eca65d 100644 --- a/crates/re_viewer/src/ui/visible_history.rs +++ b/crates/re_viewer/src/ui/visible_history.rs @@ -3,11 +3,16 @@ use std::ops::RangeInclusive; use egui::{NumExt as _, Response, Ui}; -use re_entity_db::{ExtraQueryHistory, TimeHistogram, VisibleHistory, VisibleHistoryBoundary}; +use re_entity_db::{TimeHistogram, VisibleHistory, VisibleHistoryBoundary}; use re_log_types::{EntityPath, TimeType, TimeZone}; +use re_space_view::{ + default_time_range, time_range_boundary_to_visible_history_boundary, + visible_history_boundary_to_time_range_boundary, visible_time_range_to_time_range, +}; use re_space_view_spatial::{SpatialSpaceView2D, SpatialSpaceView3D}; use re_space_view_time_series::TimeSeriesSpaceView; -use re_types_core::ComponentName; +use re_types::blueprint::components::VisibleTimeRange; +use re_types_core::{ComponentName, Loggable as _}; use re_ui::{markdown_ui, ReUi}; use re_viewer_context::{SpaceViewClass, SpaceViewClassIdentifier, TimeControl, ViewerContext}; @@ -44,45 +49,37 @@ static VISIBLE_HISTORY_SUPPORTED_COMPONENT_NAMES: once_cell::sync::Lazy bool { + VISIBLE_HISTORY_SUPPORTED_SPACE_VIEWS.contains(&space_view_class) +} + +fn entity_with_visible_history( ctx: &ViewerContext<'_>, time_ctrl: &TimeControl, - space_view_class: &SpaceViewClassIdentifier, - entity_path: Option<&EntityPath>, + entity_path: &EntityPath, ) -> bool { - if !VISIBLE_HISTORY_SUPPORTED_SPACE_VIEWS.contains(space_view_class) { - return false; - } - - if let Some(entity_path) = entity_path { - let store = ctx.entity_db.store(); - let component_names = store.all_components(time_ctrl.timeline(), entity_path); - if let Some(component_names) = component_names { - if !component_names - .iter() - .any(|name| VISIBLE_HISTORY_SUPPORTED_COMPONENT_NAMES.contains(name)) - { - return false; - } - } else { - return false; - } - } - - true + let store = ctx.entity_db.store(); + let component_names = store.all_components(time_ctrl.timeline(), entity_path); + component_names + .iter() + .flatten() + .any(|name| VISIBLE_HISTORY_SUPPORTED_COMPONENT_NAMES.contains(name)) } -pub fn visible_history_ui( +pub fn visual_time_range_ui( ctx: &ViewerContext<'_>, - ui: &mut egui::Ui, - space_view_class: &SpaceViewClassIdentifier, + ui: &mut Ui, + data_result_tree: &re_viewer_context::DataResultTree, + data_result: &re_viewer_context::DataResult, + space_view_class: SpaceViewClassIdentifier, is_space_view: bool, - entity_path: Option<&EntityPath>, - visible_history_prop: &mut ExtraQueryHistory, - resolved_visible_history_prop: &ExtraQueryHistory, ) { let time_ctrl = ctx.rec_cfg.time_ctrl.read().clone(); - if !has_visible_history(ctx, &time_ctrl, space_view_class, entity_path) { + + if is_space_view && !space_view_with_visible_history(space_view_class) { + return; + } + if !is_space_view && !entity_with_visible_history(ctx, &time_ctrl, &data_result.entity_path) { return; } @@ -92,24 +89,33 @@ pub fn visible_history_ui( let mut interacting_with_controls = false; + let mut resolved_range = data_result + .lookup_override::(ctx) + .unwrap_or(default_time_range(space_view_class)); + let mut has_individual_range = data_result + .component_override_source(data_result_tree, &VisibleTimeRange::name()) + .as_ref() + == Some(&data_result.entity_path); + let collapsing_response = re_ui.collapsing_header(ui, "Visible time range", false, |ui| { + let has_individual_range_before = has_individual_range; + let resolved_range_before = resolved_range.clone(); + ui.horizontal(|ui| { re_ui - .radio_value(ui, &mut visible_history_prop.enabled, false, "Default") + .radio_value(ui, &mut has_individual_range, false, "Default") .on_hover_text(if is_space_view { "Default visible time range settings for this kind of Space View" } else { - "Visible time range settings inherited from parent Group(s) or enclosing \ + "Visible time range settings inherited from parent Entity or enclosing \ Space View" }); re_ui - .radio_value(ui, &mut visible_history_prop.enabled, true, "Override") + .radio_value(ui, &mut has_individual_range, true, "Override") .on_hover_text(if is_space_view { "Set visible time range settings for the contents of this Space View" - } else if entity_path.is_some() { - "Set visible time range settings for this entity" } else { - "Set visible time range settings for he contents of this Group" + "Set visible time range settings for this entity" }); }); @@ -125,22 +131,29 @@ pub fn visible_history_ui( .unwrap_or_default() .at_least(*timeline_spec.range.start()); // accounts for timeless time (TimeInt::BEGINNING) - let (resolved_visible_history, visible_history) = match time_type { + // pick right from/to depending on the timeline type. + let (from, to) = match time_type { TimeType::Time => ( - &resolved_visible_history_prop.nanos, - &mut visible_history_prop.nanos, + &mut resolved_range.0.from_time, + &mut resolved_range.0.to_time, ), TimeType::Sequence => ( - &resolved_visible_history_prop.sequences, - &mut visible_history_prop.sequences, + &mut resolved_range.0.from_sequence, + &mut resolved_range.0.to_sequence, ), }; - if visible_history_prop.enabled { - let current_low_boundary = visible_history + // Convert to legacy visual history type. + let mut visible_history = VisibleHistory { + from: time_range_boundary_to_visible_history_boundary(from), + to: time_range_boundary_to_visible_history_boundary(to), + }; + + if has_individual_range { + let current_from = visible_history .range_start_from_cursor(current_time.into()) .as_i64(); - let current_high_boundary = visible_history + let current_to = visible_history .range_end_from_cursor(current_time.into()) .as_i64(); @@ -156,7 +169,7 @@ pub fn visible_history_ui( current_time, &timeline_spec, true, - current_high_boundary, + current_to, ) }) .inner; @@ -173,23 +186,23 @@ pub fn visible_history_ui( current_time, &timeline_spec, false, - current_low_boundary, + current_from, ) }) .inner; ui.end_row(); }); - current_range_ui(ctx, ui, current_time, time_type, visible_history); + current_range_ui(ctx, ui, current_time, time_type, &visible_history); } else { // Show the resolved visible range as labels (user can't edit them): - if resolved_visible_history.from == VisibleHistoryBoundary::Infinite - && resolved_visible_history.to == VisibleHistoryBoundary::Infinite + if visible_history.from == VisibleHistoryBoundary::Infinite + && visible_history.to == VisibleHistoryBoundary::Infinite { ui.label("Entire timeline"); - } else if resolved_visible_history.from == VisibleHistoryBoundary::AT_CURSOR - && resolved_visible_history.to == VisibleHistoryBoundary::AT_CURSOR + } else if visible_history.from == VisibleHistoryBoundary::AT_CURSOR + && visible_history.to == VisibleHistoryBoundary::AT_CURSOR { let current_time = time_type.format(current_time.into(), ctx.app_options.time_zone); match time_type { @@ -206,7 +219,7 @@ pub fn visible_history_ui( resolved_visible_history_boundary_ui( ctx, ui, - &resolved_visible_history.from, + &visible_history.from, time_type, true, ); @@ -216,14 +229,31 @@ pub fn visible_history_ui( resolved_visible_history_boundary_ui( ctx, ui, - &resolved_visible_history.to, + &visible_history.to, time_type, false, ); ui.end_row(); }); - current_range_ui(ctx, ui, current_time, time_type, resolved_visible_history); + current_range_ui(ctx, ui, current_time, time_type, &visible_history); + } + } + + // Convert back from visual history type. + *from = visible_history_boundary_to_time_range_boundary(&visible_history.from); + *to = visible_history_boundary_to_time_range_boundary(&visible_history.to); + + // Save to blueprint store if anything has changed. + if has_individual_range != has_individual_range_before + || resolved_range != resolved_range_before + { + if has_individual_range { + re_log::debug!("override!"); + data_result.save_recursive_override(ctx, &resolved_range); + } else { + re_log::debug!("clear!"); + data_result.clear_recursive_override::(ctx); } } }); @@ -251,22 +281,15 @@ pub fn visible_history_ui( if should_display_visible_history { if let Some(current_time) = time_ctrl.time_int() { - let visible_history = match (visible_history_prop.enabled, time_type) { - (true, TimeType::Sequence) => visible_history_prop.sequences, - (true, TimeType::Time) => visible_history_prop.nanos, - (false, TimeType::Sequence) => resolved_visible_history_prop.sequences, - (false, TimeType::Time) => resolved_visible_history_prop.nanos, - }; - - ctx.rec_cfg.time_ctrl.write().highlighted_range = - Some(visible_history.time_range(current_time)); + let range = visible_time_range_to_time_range(&resolved_range, time_type, current_time); + ctx.rec_cfg.time_ctrl.write().highlighted_range = Some(range); } } let markdown = format!("# Visible time range\n This feature controls the time range used to display data in the Space View. -The settings are inherited from parent Group(s) or enclosing Space View if not overridden. +The settings are inherited from the parent Entity or enclosing Space View if not overridden. Visible time range properties are stored separately for each _type_ of timelines. They may differ depending on \ whether the current timeline is temporal or a sequence. The current settings apply to all _{}_ timelines. diff --git a/crates/re_viewer_context/src/space_view/view_query.rs b/crates/re_viewer_context/src/space_view/view_query.rs index 9847cc516536..24a2ebcd15ad 100644 --- a/crates/re_viewer_context/src/space_view/view_query.rs +++ b/crates/re_viewer_context/src/space_view/view_query.rs @@ -171,17 +171,57 @@ impl DataResult { } } + /// Saves a recursive override, does not take into current or default values. + /// + /// Ignores individual overrides and current value. + pub fn save_recursive_override( + &self, + ctx: &ViewerContext<'_>, + desired_override: &C, + ) { + re_tracing::profile_function!(); + + // TODO(jleibs): Make it impossible for this to happen with different type structure + // This should never happen unless we're doing something with a partially processed + // query. + let Some(recursive_override_path) = self.recursive_override_path() else { + re_log::warn!( + "Tried to save override for {:?} but it has no override path", + self.entity_path + ); + return; + }; + + ctx.save_blueprint_component(recursive_override_path, desired_override); + } + + /// Clears the recursive override for a given component + pub fn clear_recursive_override(&self, ctx: &ViewerContext<'_>) { + // TODO(jleibs): Make it impossible for this to happen with different type structure + // This should never happen unless we're doing something with a partially processed + // query. + let Some(recursive_override_path) = self.recursive_override_path() else { + re_log::warn!( + "Tried to save override for {:?} but it has no override path", + self.entity_path + ); + return; + }; + + ctx.save_empty_blueprint_component::(recursive_override_path); + } + /// Write the [`EntityProperties`] for this result back to the Blueprint store on the recursive override. /// /// Setting `new_recursive_props` to `None` will always clear the override. /// Otherwise, writes only if the recursive properties aren't already the same value. /// (does *not* take into account what the accumulated properties are which are a combination of recursive and individual overwrites) - pub fn save_recursive_override( + pub fn save_recursive_override_properties( &self, ctx: &ViewerContext<'_>, new_recursive_props: Option, ) { - self.save_override_internal( + self.save_override_properties_internal( ctx, new_recursive_props, self.recursive_override_path(), @@ -194,12 +234,12 @@ impl DataResult { /// Setting `new_individual_props` to `None` will always clear the override. /// Otherwise, writes only if the individual properties aren't already the same value. /// (does *not* take into account what the accumulated properties are which are a combination of recursive and individual overwrites) - pub fn save_individual_override( + pub fn save_individual_override_properties( &self, - new_individual_props: Option, ctx: &ViewerContext<'_>, + new_individual_props: Option, ) { - self.save_override_internal( + self.save_override_properties_internal( ctx, new_individual_props, self.individual_override_path(), @@ -207,7 +247,7 @@ impl DataResult { ); } - fn save_override_internal( + fn save_override_properties_internal( &self, ctx: &ViewerContext<'_>, new_individual_props: Option, diff --git a/docs/content/reference/types/datatypes.md b/docs/content/reference/types/datatypes.md index 57ab7ca7b854..95daf97ca8f7 100644 --- a/docs/content/reference/types/datatypes.md +++ b/docs/content/reference/types/datatypes.md @@ -29,6 +29,7 @@ Data types are the lowest layer of the data model hierarchy * [`TensorBuffer`](datatypes/tensor_buffer.md) * [`TensorData`](datatypes/tensor_data.md) * [`TensorDimension`](datatypes/tensor_dimension.md) +* [`TimeInt`](datatypes/time_int.md) * [`Transform3D`](datatypes/transform3d.md) * [`TranslationAndMat3x3`](datatypes/translation_and_mat3x3.md) * [`TranslationRotationScale3D`](datatypes/translation_rotation_scale3d.md) diff --git a/docs/content/reference/types/datatypes/.gitattributes b/docs/content/reference/types/datatypes/.gitattributes index 6e766a712369..1ef35ab8e55a 100644 --- a/docs/content/reference/types/datatypes/.gitattributes +++ b/docs/content/reference/types/datatypes/.gitattributes @@ -23,6 +23,7 @@ scale3d.md linguist-generated=true tensor_buffer.md linguist-generated=true tensor_data.md linguist-generated=true tensor_dimension.md linguist-generated=true +time_int.md linguist-generated=true transform3d.md linguist-generated=true translation_and_mat3x3.md linguist-generated=true translation_rotation_scale3d.md linguist-generated=true diff --git a/docs/content/reference/types/datatypes/time_int.md b/docs/content/reference/types/datatypes/time_int.md new file mode 100644 index 000000000000..de6030538958 --- /dev/null +++ b/docs/content/reference/types/datatypes/time_int.md @@ -0,0 +1,16 @@ +--- +title: "TimeInt" +--- + +A 64-bit number describing either nanoseconds OR sequence numbers. + +## Fields + +* value: `i64` + +## Links + * 🌊 [C++ API docs for `TimeInt`](https://ref.rerun.io/docs/cpp/stable/structrerun_1_1datatypes_1_1TimeInt.html?speculative-link) + * 🐍 [Python API docs for `TimeInt`](https://ref.rerun.io/docs/python/stable/common/datatypes?speculative-link#rerun.datatypes.TimeInt) + * 🦀 [Rust API docs for `TimeInt`](https://docs.rs/rerun/latest/rerun/datatypes/struct.TimeInt.html?speculative-link) + + diff --git a/rerun_cpp/src/rerun/blueprint/.gitattributes b/rerun_cpp/src/rerun/blueprint/.gitattributes index 0661cd67c5ea..435e1f8fe40d 100644 --- a/rerun_cpp/src/rerun/blueprint/.gitattributes +++ b/rerun_cpp/src/rerun/blueprint/.gitattributes @@ -3,3 +3,4 @@ .gitattributes linguist-generated=true archetypes.hpp linguist-generated=true components.hpp linguist-generated=true +datatypes.hpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/blueprint/components.hpp b/rerun_cpp/src/rerun/blueprint/components.hpp index fc45185e5696..715845efe9dd 100644 --- a/rerun_cpp/src/rerun/blueprint/components.hpp +++ b/rerun_cpp/src/rerun/blueprint/components.hpp @@ -23,3 +23,4 @@ #include "blueprint/components/space_view_origin.hpp" #include "blueprint/components/viewer_recommendation_hash.hpp" #include "blueprint/components/visible.hpp" +#include "blueprint/components/visible_time_range.hpp" diff --git a/rerun_cpp/src/rerun/blueprint/components/.gitattributes b/rerun_cpp/src/rerun/blueprint/components/.gitattributes index c013fc7cd820..7b4380fbe687 100644 --- a/rerun_cpp/src/rerun/blueprint/components/.gitattributes +++ b/rerun_cpp/src/rerun/blueprint/components/.gitattributes @@ -33,3 +33,4 @@ space_view_origin.hpp linguist-generated=true viewer_recommendation_hash.hpp linguist-generated=true visible.cpp linguist-generated=true visible.hpp linguist-generated=true +visible_time_range.hpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/blueprint/components/visible_time_range.hpp b/rerun_cpp/src/rerun/blueprint/components/visible_time_range.hpp new file mode 100644 index 000000000000..f55840689b09 --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/components/visible_time_range.hpp @@ -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/components/visible_time_range.fbs". + +#pragma once + +#include "../../blueprint/datatypes/visible_time_range.hpp" +#include "../../result.hpp" + +#include +#include + +namespace rerun::blueprint::components { + /// **Component**: The range of values that will be included in a Space View query. + struct VisibleTimeRange { + rerun::blueprint::datatypes::VisibleTimeRange value; + + public: + VisibleTimeRange() = default; + + VisibleTimeRange(rerun::blueprint::datatypes::VisibleTimeRange value_) : value(value_) {} + + VisibleTimeRange& operator=(rerun::blueprint::datatypes::VisibleTimeRange value_) { + value = value_; + return *this; + } + + /// Cast to the underlying VisibleTimeRange datatype + operator rerun::blueprint::datatypes::VisibleTimeRange() const { + return value; + } + }; +} // namespace rerun::blueprint::components + +namespace rerun { + static_assert( + sizeof(rerun::blueprint::datatypes::VisibleTimeRange) == + sizeof(blueprint::components::VisibleTimeRange) + ); + + /// \private + template <> + struct Loggable { + static constexpr const char Name[] = "rerun.blueprint.components.VisibleTimeRange"; + + /// Returns the arrow data type this type corresponds to. + static const std::shared_ptr& arrow_datatype() { + return Loggable::arrow_datatype(); + } + + /// Serializes an array of `rerun::blueprint:: components::VisibleTimeRange` into an arrow array. + static Result> to_arrow( + const blueprint::components::VisibleTimeRange* instances, size_t num_instances + ) { + return Loggable::to_arrow( + &instances->value, + num_instances + ); + } + }; +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/datatypes.hpp b/rerun_cpp/src/rerun/blueprint/datatypes.hpp new file mode 100644 index 000000000000..361e00061d0e --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/datatypes.hpp @@ -0,0 +1,7 @@ +// DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/cpp/mod.rs + +#pragma once + +#include "blueprint/datatypes/visible_time_range.hpp" +#include "blueprint/datatypes/visible_time_range_boundary.hpp" +#include "blueprint/datatypes/visible_time_range_boundary_kind.hpp" diff --git a/rerun_cpp/src/rerun/blueprint/datatypes/.gitattributes b/rerun_cpp/src/rerun/blueprint/datatypes/.gitattributes index da03d4b96e87..06328369afaa 100644 --- a/rerun_cpp/src/rerun/blueprint/datatypes/.gitattributes +++ b/rerun_cpp/src/rerun/blueprint/datatypes/.gitattributes @@ -1,5 +1,9 @@ # DO NOT EDIT! This file is generated by crates/re_types_builder/src/lib.rs .gitattributes linguist-generated=true -legend.cpp linguist-generated=true -legend.hpp linguist-generated=true +visible_time_range.cpp linguist-generated=true +visible_time_range.hpp linguist-generated=true +visible_time_range_boundary.cpp linguist-generated=true +visible_time_range_boundary.hpp linguist-generated=true +visible_time_range_boundary_kind.cpp linguist-generated=true +visible_time_range_boundary_kind.hpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/blueprint/datatypes/legend.cpp b/rerun_cpp/src/rerun/blueprint/datatypes/legend.cpp deleted file mode 100644 index 948dd620e8bc..000000000000 --- a/rerun_cpp/src/rerun/blueprint/datatypes/legend.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// 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/datatypes/legend.fbs". - -#include "legend.hpp" - -#include -#include - -namespace rerun::blueprint::datatypes {} - -namespace rerun { - const std::shared_ptr& Loggable::arrow_datatype( - ) { - static const auto datatype = arrow::struct_({ - arrow::field("visible", arrow::boolean(), false), - arrow::field("location", arrow::uint8(), true), - }); - return datatype; - } - - rerun::Error Loggable::fill_arrow_array_builder( - arrow::StructBuilder* builder, const blueprint::datatypes::Legend* elements, - size_t num_elements - ) { - if (builder == nullptr) { - return rerun::Error(ErrorCode::UnexpectedNullArgument, "Passed array builder is null."); - } - if (elements == nullptr) { - return rerun::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].visible)); - } - } - { - auto field_builder = static_cast(builder->field_builder(1)); - ARROW_RETURN_NOT_OK(field_builder->Reserve(static_cast(num_elements))); - for (size_t elem_idx = 0; elem_idx < num_elements; elem_idx += 1) { - const auto& element = elements[elem_idx]; - if (element.location.has_value()) { - ARROW_RETURN_NOT_OK(field_builder->Append(element.location.value())); - } else { - ARROW_RETURN_NOT_OK(field_builder->AppendNull()); - } - } - } - ARROW_RETURN_NOT_OK(builder->AppendValues(static_cast(num_elements), nullptr)); - - return Error::ok(); - } - - Result> Loggable::to_arrow( - const blueprint::datatypes::Legend* instances, size_t num_instances - ) { - // TODO(andreas): Allow configuring the memory pool. - arrow::MemoryPool* pool = arrow::default_memory_pool(); - auto datatype = arrow_datatype(); - - ARROW_ASSIGN_OR_RAISE(auto builder, arrow::MakeBuilder(datatype, pool)) - if (instances && num_instances > 0) { - RR_RETURN_NOT_OK(Loggable::fill_arrow_array_builder( - static_cast(builder.get()), - instances, - num_instances - )); - } - std::shared_ptr array; - ARROW_RETURN_NOT_OK(builder->Finish(&array)); - return array; - } -} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range.cpp b/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range.cpp new file mode 100644 index 000000000000..36f9e1bdaa5b --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range.cpp @@ -0,0 +1,124 @@ +// 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/datatypes/visible_time_range.fbs". + +#include "visible_time_range.hpp" + +#include "visible_time_range_boundary.hpp" + +#include +#include + +namespace rerun::blueprint::datatypes {} + +namespace rerun { + const std::shared_ptr& + Loggable::arrow_datatype() { + static const auto datatype = arrow::struct_({ + arrow::field( + "from_sequence", + Loggable::arrow_datatype(), + false + ), + arrow::field( + "to_sequence", + Loggable::arrow_datatype(), + false + ), + arrow::field( + "from_time", + Loggable::arrow_datatype(), + false + ), + arrow::field( + "to_time", + Loggable::arrow_datatype(), + false + ), + }); + return datatype; + } + + Result> + Loggable::to_arrow( + const blueprint::datatypes::VisibleTimeRange* instances, size_t num_instances + ) { + // TODO(andreas): Allow configuring the memory pool. + arrow::MemoryPool* pool = arrow::default_memory_pool(); + auto datatype = arrow_datatype(); + + ARROW_ASSIGN_OR_RAISE(auto builder, arrow::MakeBuilder(datatype, pool)) + if (instances && num_instances > 0) { + RR_RETURN_NOT_OK( + Loggable::fill_arrow_array_builder( + static_cast(builder.get()), + instances, + num_instances + ) + ); + } + std::shared_ptr array; + ARROW_RETURN_NOT_OK(builder->Finish(&array)); + return array; + } + + rerun::Error Loggable::fill_arrow_array_builder( + arrow::StructBuilder* builder, const blueprint::datatypes::VisibleTimeRange* elements, + size_t num_elements + ) { + if (builder == nullptr) { + return rerun::Error(ErrorCode::UnexpectedNullArgument, "Passed array builder is null."); + } + if (elements == nullptr) { + return rerun::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) { + RR_RETURN_NOT_OK(Loggable:: + fill_arrow_array_builder( + field_builder, + &elements[elem_idx].from_sequence, + 1 + )); + } + } + { + auto field_builder = static_cast(builder->field_builder(1)); + ARROW_RETURN_NOT_OK(field_builder->Reserve(static_cast(num_elements))); + for (size_t elem_idx = 0; elem_idx < num_elements; elem_idx += 1) { + RR_RETURN_NOT_OK( + Loggable:: + fill_arrow_array_builder(field_builder, &elements[elem_idx].to_sequence, 1) + ); + } + } + { + auto field_builder = static_cast(builder->field_builder(2)); + ARROW_RETURN_NOT_OK(field_builder->Reserve(static_cast(num_elements))); + for (size_t elem_idx = 0; elem_idx < num_elements; elem_idx += 1) { + RR_RETURN_NOT_OK( + Loggable:: + fill_arrow_array_builder(field_builder, &elements[elem_idx].from_time, 1) + ); + } + } + { + auto field_builder = static_cast(builder->field_builder(3)); + ARROW_RETURN_NOT_OK(field_builder->Reserve(static_cast(num_elements))); + for (size_t elem_idx = 0; elem_idx < num_elements; elem_idx += 1) { + RR_RETURN_NOT_OK( + Loggable:: + fill_arrow_array_builder(field_builder, &elements[elem_idx].to_time, 1) + ); + } + } + ARROW_RETURN_NOT_OK(builder->AppendValues(static_cast(num_elements), nullptr)); + + return Error::ok(); + } +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range.hpp b/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range.hpp new file mode 100644 index 000000000000..6a0dc250edf7 --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range.hpp @@ -0,0 +1,61 @@ +// 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/datatypes/visible_time_range.fbs". + +#pragma once + +#include "../../result.hpp" +#include "visible_time_range_boundary.hpp" + +#include +#include + +namespace arrow { + class Array; + class DataType; + class StructBuilder; +} // namespace arrow + +namespace rerun::blueprint::datatypes { + /// **Datatype**: Visible time range bounds. + struct VisibleTimeRange { + /// Low time boundary for sequence timeline. + rerun::blueprint::datatypes::VisibleTimeRangeBoundary from_sequence; + + /// High time boundary for sequence timeline. + rerun::blueprint::datatypes::VisibleTimeRangeBoundary to_sequence; + + /// Low time boundary for time timeline. + rerun::blueprint::datatypes::VisibleTimeRangeBoundary from_time; + + /// High time boundary for time timeline. + rerun::blueprint::datatypes::VisibleTimeRangeBoundary to_time; + + public: + VisibleTimeRange() = default; + }; +} // namespace rerun::blueprint::datatypes + +namespace rerun { + template + struct Loggable; + + /// \private + template <> + struct Loggable { + static constexpr const char Name[] = "rerun.blueprint.datatypes.VisibleTimeRange"; + + /// Returns the arrow data type this type corresponds to. + static const std::shared_ptr& arrow_datatype(); + + /// Serializes an array of `rerun::blueprint:: datatypes::VisibleTimeRange` into an arrow array. + static Result> to_arrow( + const blueprint::datatypes::VisibleTimeRange* instances, size_t num_instances + ); + + /// Fills an arrow array builder with an array of this type. + static rerun::Error fill_arrow_array_builder( + arrow::StructBuilder* builder, const blueprint::datatypes::VisibleTimeRange* elements, + size_t num_elements + ); + }; +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range_boundary.cpp b/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range_boundary.cpp new file mode 100644 index 000000000000..6e4820a69c1f --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range_boundary.cpp @@ -0,0 +1,91 @@ +// 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/datatypes/visible_time_range.fbs". + +#include "visible_time_range_boundary.hpp" + +#include "../../datatypes/time_int.hpp" +#include "visible_time_range_boundary_kind.hpp" + +#include +#include + +namespace rerun::blueprint::datatypes {} + +namespace rerun { + const std::shared_ptr& + Loggable::arrow_datatype() { + static const auto datatype = arrow::struct_({ + arrow::field( + "kind", + Loggable::arrow_datatype( + ), + false + ), + arrow::field("time", Loggable::arrow_datatype(), false), + }); + return datatype; + } + + Result> + Loggable::to_arrow( + const blueprint::datatypes::VisibleTimeRangeBoundary* instances, size_t num_instances + ) { + // TODO(andreas): Allow configuring the memory pool. + arrow::MemoryPool* pool = arrow::default_memory_pool(); + auto datatype = arrow_datatype(); + + ARROW_ASSIGN_OR_RAISE(auto builder, arrow::MakeBuilder(datatype, pool)) + if (instances && num_instances > 0) { + RR_RETURN_NOT_OK( + Loggable::fill_arrow_array_builder( + static_cast(builder.get()), + instances, + num_instances + ) + ); + } + std::shared_ptr array; + ARROW_RETURN_NOT_OK(builder->Finish(&array)); + return array; + } + + rerun::Error Loggable::fill_arrow_array_builder( + arrow::StructBuilder* builder, + const blueprint::datatypes::VisibleTimeRangeBoundary* elements, size_t num_elements + ) { + if (builder == nullptr) { + return rerun::Error(ErrorCode::UnexpectedNullArgument, "Passed array builder is null."); + } + if (elements == nullptr) { + return rerun::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) { + RR_RETURN_NOT_OK( + Loggable:: + fill_arrow_array_builder(field_builder, &elements[elem_idx].kind, 1) + ); + } + } + { + auto field_builder = static_cast(builder->field_builder(1)); + ARROW_RETURN_NOT_OK(field_builder->Reserve(static_cast(num_elements))); + for (size_t elem_idx = 0; elem_idx < num_elements; elem_idx += 1) { + RR_RETURN_NOT_OK(Loggable::fill_arrow_array_builder( + field_builder, + &elements[elem_idx].time, + 1 + )); + } + } + ARROW_RETURN_NOT_OK(builder->AppendValues(static_cast(num_elements), nullptr)); + + return Error::ok(); + } +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/datatypes/legend.hpp b/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range_boundary.hpp similarity index 55% rename from rerun_cpp/src/rerun/blueprint/datatypes/legend.hpp rename to rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range_boundary.hpp index b8efd53df620..317bf804ec91 100644 --- a/rerun_cpp/src/rerun/blueprint/datatypes/legend.hpp +++ b/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range_boundary.hpp @@ -1,13 +1,14 @@ // 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/datatypes/legend.fbs". +// Based on "crates/re_types/definitions/rerun/blueprint/datatypes/visible_time_range.fbs". #pragma once +#include "../../datatypes/time_int.hpp" #include "../../result.hpp" +#include "visible_time_range_boundary_kind.hpp" #include #include -#include namespace arrow { class Array; @@ -16,22 +17,16 @@ namespace arrow { } // namespace arrow namespace rerun::blueprint::datatypes { - /// **Datatype**: Configuration for the legend of a plot. - struct Legend { - /// Whether or not the legend should be displayed. - bool visible; - - /// Where should the legend be located. - /// - /// Allowed values: - /// - LeftTop = 1, - /// - RightTop = 2, - /// - LeftBottom = 3, - /// - RightBottom = 4 - std::optional location; + /// **Datatype**: Type of boundary for visible history. + struct VisibleTimeRangeBoundary { + /// Type of the boundary. + rerun::blueprint::datatypes::VisibleTimeRangeBoundaryKind kind; + + /// Value of the boundary (ignored for `Infinite` type). + rerun::datatypes::TimeInt time; public: - Legend() = default; + VisibleTimeRangeBoundary() = default; }; } // namespace rerun::blueprint::datatypes @@ -41,21 +36,21 @@ namespace rerun { /// \private template <> - struct Loggable { - static constexpr const char Name[] = "rerun.blueprint.datatypes.Legend"; + struct Loggable { + static constexpr const char Name[] = "rerun.blueprint.datatypes.VisibleTimeRangeBoundary"; /// Returns the arrow data type this type corresponds to. static const std::shared_ptr& arrow_datatype(); - /// Fills an arrow array builder with an array of this type. - static rerun::Error fill_arrow_array_builder( - arrow::StructBuilder* builder, const blueprint::datatypes::Legend* elements, - size_t num_elements + /// Serializes an array of `rerun::blueprint:: datatypes::VisibleTimeRangeBoundary` into an arrow array. + static Result> to_arrow( + const blueprint::datatypes::VisibleTimeRangeBoundary* instances, size_t num_instances ); - /// Serializes an array of `rerun::blueprint:: datatypes::Legend` into an arrow array. - static Result> to_arrow( - const blueprint::datatypes::Legend* instances, size_t num_instances + /// Fills an arrow array builder with an array of this type. + static rerun::Error fill_arrow_array_builder( + arrow::StructBuilder* builder, + const blueprint::datatypes::VisibleTimeRangeBoundary* elements, size_t num_elements ); }; } // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range_boundary_kind.cpp b/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range_boundary_kind.cpp new file mode 100644 index 000000000000..08a67a5061bf --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range_boundary_kind.cpp @@ -0,0 +1,67 @@ +// 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/datatypes/visible_time_range.fbs". + +#include "visible_time_range_boundary_kind.hpp" + +#include +#include + +namespace rerun { + const std::shared_ptr& + Loggable::arrow_datatype() { + static const auto datatype = arrow::sparse_union({ + arrow::field("_null_markers", arrow::null(), true, nullptr), + arrow::field("RelativeToTimeCursor", arrow::null(), true), + arrow::field("Absolute", arrow::null(), true), + arrow::field("Infinite", arrow::null(), true), + }); + return datatype; + } + + Result> + Loggable::to_arrow( + const blueprint::datatypes::VisibleTimeRangeBoundaryKind* instances, + size_t num_instances + ) { + // TODO(andreas): Allow configuring the memory pool. + arrow::MemoryPool* pool = arrow::default_memory_pool(); + auto datatype = arrow_datatype(); + + ARROW_ASSIGN_OR_RAISE(auto builder, arrow::MakeBuilder(datatype, pool)) + if (instances && num_instances > 0) { + RR_RETURN_NOT_OK(Loggable:: + fill_arrow_array_builder( + static_cast(builder.get()), + instances, + num_instances + )); + } + std::shared_ptr array; + ARROW_RETURN_NOT_OK(builder->Finish(&array)); + return array; + } + + rerun::Error + Loggable::fill_arrow_array_builder( + arrow::SparseUnionBuilder* builder, + const blueprint::datatypes::VisibleTimeRangeBoundaryKind* elements, size_t num_elements + ) { + if (builder == nullptr) { + return rerun::Error(ErrorCode::UnexpectedNullArgument, "Passed array builder is null."); + } + if (elements == nullptr) { + return rerun::Error( + ErrorCode::UnexpectedNullArgument, + "Cannot serialize null pointer to arrow array." + ); + } + + ARROW_RETURN_NOT_OK(builder->Reserve(static_cast(num_elements))); + for (size_t elem_idx = 0; elem_idx < num_elements; elem_idx += 1) { + const auto variant = elements[elem_idx]; + ARROW_RETURN_NOT_OK(builder->Append(static_cast(variant))); + } + + return Error::ok(); + } +} // namespace rerun diff --git a/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range_boundary_kind.hpp b/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range_boundary_kind.hpp new file mode 100644 index 000000000000..59025d01da86 --- /dev/null +++ b/rerun_cpp/src/rerun/blueprint/datatypes/visible_time_range_boundary_kind.hpp @@ -0,0 +1,57 @@ +// 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/datatypes/visible_time_range.fbs". + +#pragma once + +#include "../../result.hpp" + +#include +#include + +namespace arrow { + class Array; + class DataType; + class SparseUnionBuilder; +} // namespace arrow + +namespace rerun::blueprint::datatypes { + /// **Datatype**: Kind of boundary for visible history, see `VisibleTimeRangeBoundary`. + enum class VisibleTimeRangeBoundaryKind : uint8_t { + + /// Boundary is a value relative to the time cursor. + RelativeToTimeCursor = 1, + + /// Boundary is an absolute value. + Absolute = 2, + + /// The boundary extends to infinity. + Infinite = 3, + }; +} // namespace rerun::blueprint::datatypes + +namespace rerun { + template + struct Loggable; + + /// \private + template <> + struct Loggable { + static constexpr const char Name[] = + "rerun.blueprint.datatypes.VisibleTimeRangeBoundaryKind"; + + /// Returns the arrow data type this type corresponds to. + static const std::shared_ptr& arrow_datatype(); + + /// Serializes an array of `rerun::blueprint:: datatypes::VisibleTimeRangeBoundaryKind` into an arrow array. + static Result> to_arrow( + const blueprint::datatypes::VisibleTimeRangeBoundaryKind* instances, + size_t num_instances + ); + + /// Fills an arrow array builder with an array of this type. + static rerun::Error fill_arrow_array_builder( + arrow::SparseUnionBuilder* builder, + const blueprint::datatypes::VisibleTimeRangeBoundaryKind* elements, size_t num_elements + ); + }; +} // namespace rerun diff --git a/rerun_cpp/src/rerun/datatypes.hpp b/rerun_cpp/src/rerun/datatypes.hpp index 7f33e559abe9..81c850bdde6f 100644 --- a/rerun_cpp/src/rerun/datatypes.hpp +++ b/rerun_cpp/src/rerun/datatypes.hpp @@ -24,6 +24,7 @@ #include "datatypes/tensor_buffer.hpp" #include "datatypes/tensor_data.hpp" #include "datatypes/tensor_dimension.hpp" +#include "datatypes/time_int.hpp" #include "datatypes/transform3d.hpp" #include "datatypes/translation_and_mat3x3.hpp" #include "datatypes/translation_rotation_scale3d.hpp" diff --git a/rerun_cpp/src/rerun/datatypes/.gitattributes b/rerun_cpp/src/rerun/datatypes/.gitattributes index 5c61073231da..83fde1441f4b 100644 --- a/rerun_cpp/src/rerun/datatypes/.gitattributes +++ b/rerun_cpp/src/rerun/datatypes/.gitattributes @@ -45,6 +45,8 @@ tensor_data.cpp linguist-generated=true tensor_data.hpp linguist-generated=true tensor_dimension.cpp linguist-generated=true tensor_dimension.hpp linguist-generated=true +time_int.cpp linguist-generated=true +time_int.hpp linguist-generated=true transform3d.cpp linguist-generated=true transform3d.hpp linguist-generated=true translation_and_mat3x3.cpp linguist-generated=true diff --git a/rerun_cpp/src/rerun/datatypes/time_int.cpp b/rerun_cpp/src/rerun/datatypes/time_int.cpp new file mode 100644 index 000000000000..7b368b716fcd --- /dev/null +++ b/rerun_cpp/src/rerun/datatypes/time_int.cpp @@ -0,0 +1,57 @@ +// 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/datatypes/time_int.fbs". + +#include "time_int.hpp" + +#include +#include + +namespace rerun::datatypes {} + +namespace rerun { + const std::shared_ptr& Loggable::arrow_datatype() { + static const auto datatype = arrow::int64(); + return datatype; + } + + Result> Loggable::to_arrow( + const datatypes::TimeInt* instances, size_t num_instances + ) { + // TODO(andreas): Allow configuring the memory pool. + arrow::MemoryPool* pool = arrow::default_memory_pool(); + auto datatype = arrow_datatype(); + + ARROW_ASSIGN_OR_RAISE(auto builder, arrow::MakeBuilder(datatype, pool)) + if (instances && num_instances > 0) { + RR_RETURN_NOT_OK(Loggable::fill_arrow_array_builder( + static_cast(builder.get()), + instances, + num_instances + )); + } + std::shared_ptr array; + ARROW_RETURN_NOT_OK(builder->Finish(&array)); + return array; + } + + rerun::Error Loggable::fill_arrow_array_builder( + arrow::Int64Builder* builder, const datatypes::TimeInt* elements, size_t num_elements + ) { + if (builder == nullptr) { + return rerun::Error(ErrorCode::UnexpectedNullArgument, "Passed array builder is null."); + } + if (elements == nullptr) { + return rerun::Error( + ErrorCode::UnexpectedNullArgument, + "Cannot serialize null pointer to arrow array." + ); + } + + static_assert(sizeof(*elements) == sizeof(elements->value)); + ARROW_RETURN_NOT_OK( + builder->AppendValues(&elements->value, static_cast(num_elements)) + ); + + return Error::ok(); + } +} // namespace rerun diff --git a/rerun_cpp/src/rerun/datatypes/time_int.hpp b/rerun_cpp/src/rerun/datatypes/time_int.hpp new file mode 100644 index 000000000000..75b090690811 --- /dev/null +++ b/rerun_cpp/src/rerun/datatypes/time_int.hpp @@ -0,0 +1,61 @@ +// 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/datatypes/time_int.fbs". + +#pragma once + +#include "../result.hpp" + +#include +#include + +namespace arrow { + /// \private + template + class NumericBuilder; + + class Array; + class DataType; + class Int64Type; + using Int64Builder = NumericBuilder; +} // namespace arrow + +namespace rerun::datatypes { + /// **Datatype**: A 64-bit number describing either nanoseconds OR sequence numbers. + struct TimeInt { + int64_t value; + + public: + TimeInt() = default; + + TimeInt(int64_t value_) : value(value_) {} + + TimeInt& operator=(int64_t value_) { + value = value_; + return *this; + } + }; +} // namespace rerun::datatypes + +namespace rerun { + template + struct Loggable; + + /// \private + template <> + struct Loggable { + static constexpr const char Name[] = "rerun.datatypes.TimeInt"; + + /// Returns the arrow data type this type corresponds to. + static const std::shared_ptr& arrow_datatype(); + + /// Serializes an array of `rerun::datatypes::TimeInt` into an arrow array. + static Result> to_arrow( + const datatypes::TimeInt* instances, size_t num_instances + ); + + /// Fills an arrow array builder with an array of this type. + static rerun::Error fill_arrow_array_builder( + arrow::Int64Builder* builder, const datatypes::TimeInt* elements, size_t num_elements + ); + }; +} // namespace rerun diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes b/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes index 2ad52015791a..a8e9e72f9c7e 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/.gitattributes @@ -23,3 +23,4 @@ space_view_maximized.py linguist-generated=true space_view_origin.py linguist-generated=true viewer_recommendation_hash.py linguist-generated=true visible.py linguist-generated=true +visible_time_range.py linguist-generated=true diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py b/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py index 94f3b1e26008..1dbd8f8d98c3 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/__init__.py @@ -57,6 +57,7 @@ ViewerRecommendationHashType, ) from .visible import Visible, VisibleArrayLike, VisibleBatch, VisibleLike, VisibleType +from .visible_time_range import VisibleTimeRange, VisibleTimeRangeBatch, VisibleTimeRangeType __all__ = [ "ActiveTab", @@ -143,5 +144,8 @@ "VisibleArrayLike", "VisibleBatch", "VisibleLike", + "VisibleTimeRange", + "VisibleTimeRangeBatch", + "VisibleTimeRangeType", "VisibleType", ] diff --git a/rerun_py/rerun_sdk/rerun/blueprint/components/visible_time_range.py b/rerun_py/rerun_sdk/rerun/blueprint/components/visible_time_range.py new file mode 100644 index 000000000000..7ffed4d09f56 --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/components/visible_time_range.py @@ -0,0 +1,28 @@ +# DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/python/mod.rs +# Based on "crates/re_types/definitions/rerun/blueprint/components/visible_time_range.fbs". + +# You can extend this class by creating a "VisibleTimeRangeExt" class in "visible_time_range_ext.py". + +from __future__ import annotations + +from ..._baseclasses import ComponentBatchMixin +from ...blueprint import datatypes as blueprint_datatypes + +__all__ = ["VisibleTimeRange", "VisibleTimeRangeBatch", "VisibleTimeRangeType"] + + +class VisibleTimeRange(blueprint_datatypes.VisibleTimeRange): + """**Component**: The range of values that will be included in a Space View query.""" + + # You can define your own __init__ function as a member of VisibleTimeRangeExt in visible_time_range_ext.py + + # Note: there are no fields here because VisibleTimeRange delegates to datatypes.VisibleTimeRange + pass + + +class VisibleTimeRangeType(blueprint_datatypes.VisibleTimeRangeType): + _TYPE_NAME: str = "rerun.blueprint.components.VisibleTimeRange" + + +class VisibleTimeRangeBatch(blueprint_datatypes.VisibleTimeRangeBatch, ComponentBatchMixin): + _ARROW_TYPE = VisibleTimeRangeType() diff --git a/rerun_py/rerun_sdk/rerun/blueprint/datatypes/.gitattributes b/rerun_py/rerun_sdk/rerun/blueprint/datatypes/.gitattributes index d7d100d86518..5f25eb77dacd 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/datatypes/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/blueprint/datatypes/.gitattributes @@ -2,4 +2,6 @@ .gitattributes linguist-generated=true __init__.py linguist-generated=true -legend.py linguist-generated=true +visible_time_range.py linguist-generated=true +visible_time_range_boundary.py linguist-generated=true +visible_time_range_boundary_kind.py linguist-generated=true diff --git a/rerun_py/rerun_sdk/rerun/blueprint/datatypes/__init__.py b/rerun_py/rerun_sdk/rerun/blueprint/datatypes/__init__.py index e18ca0758275..cfcebd2abc65 100644 --- a/rerun_py/rerun_sdk/rerun/blueprint/datatypes/__init__.py +++ b/rerun_py/rerun_sdk/rerun/blueprint/datatypes/__init__.py @@ -1,7 +1,43 @@ -# DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/python.rs +# DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/python/mod.rs from __future__ import annotations -from .legend import Legend, LegendArrayLike, LegendBatch, LegendLike, LegendType +from .visible_time_range import ( + VisibleTimeRange, + VisibleTimeRangeArrayLike, + VisibleTimeRangeBatch, + VisibleTimeRangeLike, + VisibleTimeRangeType, +) +from .visible_time_range_boundary import ( + VisibleTimeRangeBoundary, + VisibleTimeRangeBoundaryArrayLike, + VisibleTimeRangeBoundaryBatch, + VisibleTimeRangeBoundaryLike, + VisibleTimeRangeBoundaryType, +) +from .visible_time_range_boundary_kind import ( + VisibleTimeRangeBoundaryKind, + VisibleTimeRangeBoundaryKindArrayLike, + VisibleTimeRangeBoundaryKindBatch, + VisibleTimeRangeBoundaryKindLike, + VisibleTimeRangeBoundaryKindType, +) -__all__ = ["Legend", "LegendArrayLike", "LegendBatch", "LegendLike", "LegendType"] +__all__ = [ + "VisibleTimeRange", + "VisibleTimeRangeArrayLike", + "VisibleTimeRangeBatch", + "VisibleTimeRangeBoundary", + "VisibleTimeRangeBoundaryArrayLike", + "VisibleTimeRangeBoundaryBatch", + "VisibleTimeRangeBoundaryKind", + "VisibleTimeRangeBoundaryKindArrayLike", + "VisibleTimeRangeBoundaryKindBatch", + "VisibleTimeRangeBoundaryKindLike", + "VisibleTimeRangeBoundaryKindType", + "VisibleTimeRangeBoundaryLike", + "VisibleTimeRangeBoundaryType", + "VisibleTimeRangeLike", + "VisibleTimeRangeType", +] diff --git a/rerun_py/rerun_sdk/rerun/blueprint/datatypes/legend.py b/rerun_py/rerun_sdk/rerun/blueprint/datatypes/legend.py deleted file mode 100644 index 3c462c99938f..000000000000 --- a/rerun_py/rerun_sdk/rerun/blueprint/datatypes/legend.py +++ /dev/null @@ -1,92 +0,0 @@ -# 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/datatypes/legend.fbs". - -# You can extend this class by creating a "LegendExt" class in "legend_ext.py". - -from __future__ import annotations - -from typing import Any, Sequence, Union - -import pyarrow as pa -from attrs import define, field - -from ..._baseclasses import BaseBatch, BaseExtensionType -from ..._converters import ( - int_or_none, -) - -__all__ = ["Legend", "LegendArrayLike", "LegendBatch", "LegendLike", "LegendType"] - - -@define(init=False) -class Legend: - """**Datatype**: Configuration for the legend of a plot.""" - - def __init__(self: Any, visible: bool, location: int | None = None): - """ - Create a new instance of the Legend datatype. - - Parameters - ---------- - visible: - Whether or not the legend should be displayed. - location: - Where should the legend be located. - - Allowed values: - - LeftTop = 1, - - RightTop = 2, - - LeftBottom = 3, - - RightBottom = 4 - - """ - - # You can define your own __init__ function as a member of LegendExt in legend_ext.py - self.__attrs_init__(visible=visible, location=location) - - visible: bool = field(converter=bool) - # Whether or not the legend should be displayed. - # - # (Docstring intentionally commented out to hide this field from the docs) - - location: int | None = field(default=None, converter=int_or_none) - # Where should the legend be located. - # - # Allowed values: - # - LeftTop = 1, - # - RightTop = 2, - # - LeftBottom = 3, - # - RightBottom = 4 - # - # (Docstring intentionally commented out to hide this field from the docs) - - -LegendLike = Legend -LegendArrayLike = Union[ - Legend, - Sequence[LegendLike], -] - - -class LegendType(BaseExtensionType): - _TYPE_NAME: str = "rerun.blueprint.datatypes.Legend" - - def __init__(self) -> None: - pa.ExtensionType.__init__( - self, - pa.struct( - [ - pa.field("visible", pa.bool_(), nullable=False, metadata={}), - pa.field("location", pa.uint8(), nullable=True, metadata={}), - ] - ), - self._TYPE_NAME, - ) - - -class LegendBatch(BaseBatch[LegendArrayLike]): - _ARROW_TYPE = LegendType() - - @staticmethod - def _native_to_pa_array(data: LegendArrayLike, data_type: pa.DataType) -> pa.Array: - raise NotImplementedError # You need to implement native_to_pa_array_override in legend_ext.py diff --git a/rerun_py/rerun_sdk/rerun/blueprint/datatypes/visible_time_range.py b/rerun_py/rerun_sdk/rerun/blueprint/datatypes/visible_time_range.py new file mode 100644 index 000000000000..735c720b7a47 --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/datatypes/visible_time_range.py @@ -0,0 +1,194 @@ +# DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/python/mod.rs +# Based on "crates/re_types/definitions/rerun/blueprint/datatypes/visible_time_range.fbs". + +# You can extend this class by creating a "VisibleTimeRangeExt" class in "visible_time_range_ext.py". + +from __future__ import annotations + +from typing import Any, Sequence, Union + +import pyarrow as pa +from attrs import define, field + +from ..._baseclasses import BaseBatch, BaseExtensionType +from ...blueprint import datatypes as blueprint_datatypes + +__all__ = [ + "VisibleTimeRange", + "VisibleTimeRangeArrayLike", + "VisibleTimeRangeBatch", + "VisibleTimeRangeLike", + "VisibleTimeRangeType", +] + + +@define(init=False) +class VisibleTimeRange: + """**Datatype**: Visible time range bounds.""" + + def __init__( + self: Any, + from_sequence: blueprint_datatypes.VisibleTimeRangeBoundaryLike, + to_sequence: blueprint_datatypes.VisibleTimeRangeBoundaryLike, + from_time: blueprint_datatypes.VisibleTimeRangeBoundaryLike, + to_time: blueprint_datatypes.VisibleTimeRangeBoundaryLike, + ): + """ + Create a new instance of the VisibleTimeRange datatype. + + Parameters + ---------- + from_sequence: + Low time boundary for sequence timeline. + to_sequence: + High time boundary for sequence timeline. + from_time: + Low time boundary for time timeline. + to_time: + High time boundary for time timeline. + + """ + + # You can define your own __init__ function as a member of VisibleTimeRangeExt in visible_time_range_ext.py + self.__attrs_init__(from_sequence=from_sequence, to_sequence=to_sequence, from_time=from_time, to_time=to_time) + + from_sequence: blueprint_datatypes.VisibleTimeRangeBoundary = field() + # Low time boundary for sequence timeline. + # + # (Docstring intentionally commented out to hide this field from the docs) + + to_sequence: blueprint_datatypes.VisibleTimeRangeBoundary = field() + # High time boundary for sequence timeline. + # + # (Docstring intentionally commented out to hide this field from the docs) + + from_time: blueprint_datatypes.VisibleTimeRangeBoundary = field() + # Low time boundary for time timeline. + # + # (Docstring intentionally commented out to hide this field from the docs) + + to_time: blueprint_datatypes.VisibleTimeRangeBoundary = field() + # High time boundary for time timeline. + # + # (Docstring intentionally commented out to hide this field from the docs) + + +VisibleTimeRangeLike = VisibleTimeRange +VisibleTimeRangeArrayLike = Union[ + VisibleTimeRange, + Sequence[VisibleTimeRangeLike], +] + + +class VisibleTimeRangeType(BaseExtensionType): + _TYPE_NAME: str = "rerun.blueprint.datatypes.VisibleTimeRange" + + def __init__(self) -> None: + pa.ExtensionType.__init__( + self, + pa.struct( + [ + pa.field( + "from_sequence", + pa.struct( + [ + pa.field( + "kind", + pa.sparse_union( + [ + pa.field("_null_markers", pa.null(), nullable=True, metadata={}), + pa.field("RelativeToTimeCursor", pa.null(), nullable=True, metadata={}), + pa.field("Absolute", pa.null(), nullable=True, metadata={}), + pa.field("Infinite", pa.null(), nullable=True, metadata={}), + ] + ), + nullable=False, + metadata={}, + ), + pa.field("time", pa.int64(), nullable=False, metadata={}), + ] + ), + nullable=False, + metadata={}, + ), + pa.field( + "to_sequence", + pa.struct( + [ + pa.field( + "kind", + pa.sparse_union( + [ + pa.field("_null_markers", pa.null(), nullable=True, metadata={}), + pa.field("RelativeToTimeCursor", pa.null(), nullable=True, metadata={}), + pa.field("Absolute", pa.null(), nullable=True, metadata={}), + pa.field("Infinite", pa.null(), nullable=True, metadata={}), + ] + ), + nullable=False, + metadata={}, + ), + pa.field("time", pa.int64(), nullable=False, metadata={}), + ] + ), + nullable=False, + metadata={}, + ), + pa.field( + "from_time", + pa.struct( + [ + pa.field( + "kind", + pa.sparse_union( + [ + pa.field("_null_markers", pa.null(), nullable=True, metadata={}), + pa.field("RelativeToTimeCursor", pa.null(), nullable=True, metadata={}), + pa.field("Absolute", pa.null(), nullable=True, metadata={}), + pa.field("Infinite", pa.null(), nullable=True, metadata={}), + ] + ), + nullable=False, + metadata={}, + ), + pa.field("time", pa.int64(), nullable=False, metadata={}), + ] + ), + nullable=False, + metadata={}, + ), + pa.field( + "to_time", + pa.struct( + [ + pa.field( + "kind", + pa.sparse_union( + [ + pa.field("_null_markers", pa.null(), nullable=True, metadata={}), + pa.field("RelativeToTimeCursor", pa.null(), nullable=True, metadata={}), + pa.field("Absolute", pa.null(), nullable=True, metadata={}), + pa.field("Infinite", pa.null(), nullable=True, metadata={}), + ] + ), + nullable=False, + metadata={}, + ), + pa.field("time", pa.int64(), nullable=False, metadata={}), + ] + ), + nullable=False, + metadata={}, + ), + ] + ), + self._TYPE_NAME, + ) + + +class VisibleTimeRangeBatch(BaseBatch[VisibleTimeRangeArrayLike]): + _ARROW_TYPE = VisibleTimeRangeType() + + @staticmethod + def _native_to_pa_array(data: VisibleTimeRangeArrayLike, data_type: pa.DataType) -> pa.Array: + raise NotImplementedError # You need to implement native_to_pa_array_override in visible_time_range_ext.py diff --git a/rerun_py/rerun_sdk/rerun/blueprint/datatypes/visible_time_range_boundary.py b/rerun_py/rerun_sdk/rerun/blueprint/datatypes/visible_time_range_boundary.py new file mode 100644 index 000000000000..7d94422c9c4e --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/datatypes/visible_time_range_boundary.py @@ -0,0 +1,104 @@ +# DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/python/mod.rs +# Based on "crates/re_types/definitions/rerun/blueprint/datatypes/visible_time_range.fbs". + +# You can extend this class by creating a "VisibleTimeRangeBoundaryExt" class in "visible_time_range_boundary_ext.py". + +from __future__ import annotations + +from typing import Any, Sequence, Union + +import pyarrow as pa +from attrs import define, field + +from ... import datatypes +from ..._baseclasses import BaseBatch, BaseExtensionType +from ...blueprint import datatypes as blueprint_datatypes + +__all__ = [ + "VisibleTimeRangeBoundary", + "VisibleTimeRangeBoundaryArrayLike", + "VisibleTimeRangeBoundaryBatch", + "VisibleTimeRangeBoundaryLike", + "VisibleTimeRangeBoundaryType", +] + + +def _visible_time_range_boundary__time__special_field_converter_override(x: datatypes.TimeIntLike) -> datatypes.TimeInt: + if isinstance(x, datatypes.TimeInt): + return x + else: + return datatypes.TimeInt(x) + + +@define(init=False) +class VisibleTimeRangeBoundary: + """**Datatype**: Type of boundary for visible history.""" + + def __init__(self: Any, kind: blueprint_datatypes.VisibleTimeRangeBoundaryKindLike, time: datatypes.TimeIntLike): + """ + Create a new instance of the VisibleTimeRangeBoundary datatype. + + Parameters + ---------- + kind: + Type of the boundary. + time: + Value of the boundary (ignored for `Infinite` type). + + """ + + # You can define your own __init__ function as a member of VisibleTimeRangeBoundaryExt in visible_time_range_boundary_ext.py + self.__attrs_init__(kind=kind, time=time) + + kind: blueprint_datatypes.VisibleTimeRangeBoundaryKind = field() + # Type of the boundary. + # + # (Docstring intentionally commented out to hide this field from the docs) + + time: datatypes.TimeInt = field(converter=_visible_time_range_boundary__time__special_field_converter_override) + # Value of the boundary (ignored for `Infinite` type). + # + # (Docstring intentionally commented out to hide this field from the docs) + + +VisibleTimeRangeBoundaryLike = VisibleTimeRangeBoundary +VisibleTimeRangeBoundaryArrayLike = Union[ + VisibleTimeRangeBoundary, + Sequence[VisibleTimeRangeBoundaryLike], +] + + +class VisibleTimeRangeBoundaryType(BaseExtensionType): + _TYPE_NAME: str = "rerun.blueprint.datatypes.VisibleTimeRangeBoundary" + + def __init__(self) -> None: + pa.ExtensionType.__init__( + self, + pa.struct( + [ + pa.field( + "kind", + pa.sparse_union( + [ + pa.field("_null_markers", pa.null(), nullable=True, metadata={}), + pa.field("RelativeToTimeCursor", pa.null(), nullable=True, metadata={}), + pa.field("Absolute", pa.null(), nullable=True, metadata={}), + pa.field("Infinite", pa.null(), nullable=True, metadata={}), + ] + ), + nullable=False, + metadata={}, + ), + pa.field("time", pa.int64(), nullable=False, metadata={}), + ] + ), + self._TYPE_NAME, + ) + + +class VisibleTimeRangeBoundaryBatch(BaseBatch[VisibleTimeRangeBoundaryArrayLike]): + _ARROW_TYPE = VisibleTimeRangeBoundaryType() + + @staticmethod + def _native_to_pa_array(data: VisibleTimeRangeBoundaryArrayLike, data_type: pa.DataType) -> pa.Array: + raise NotImplementedError # You need to implement native_to_pa_array_override in visible_time_range_boundary_ext.py diff --git a/rerun_py/rerun_sdk/rerun/blueprint/datatypes/visible_time_range_boundary_kind.py b/rerun_py/rerun_sdk/rerun/blueprint/datatypes/visible_time_range_boundary_kind.py new file mode 100644 index 000000000000..e179602b070d --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/blueprint/datatypes/visible_time_range_boundary_kind.py @@ -0,0 +1,105 @@ +# DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/python/mod.rs +# Based on "crates/re_types/definitions/rerun/blueprint/datatypes/visible_time_range.fbs". + +# You can extend this class by creating a "VisibleTimeRangeBoundaryKindExt" class in "visible_time_range_boundary_kind_ext.py". + +from __future__ import annotations + +from typing import Sequence, Union + +import pyarrow as pa + +from ..._baseclasses import BaseBatch, BaseExtensionType + +__all__ = [ + "VisibleTimeRangeBoundaryKind", + "VisibleTimeRangeBoundaryKindArrayLike", + "VisibleTimeRangeBoundaryKindBatch", + "VisibleTimeRangeBoundaryKindLike", + "VisibleTimeRangeBoundaryKindType", +] + + +from enum import Enum + + +class VisibleTimeRangeBoundaryKind(Enum): + """**Datatype**: Kind of boundary for visible history, see `VisibleTimeRangeBoundary`.""" + + RelativeToTimeCursor = 1 + """Boundary is a value relative to the time cursor.""" + + Absolute = 2 + """Boundary is an absolute value.""" + + Infinite = 3 + """The boundary extends to infinity.""" + + +VisibleTimeRangeBoundaryKindLike = Union[VisibleTimeRangeBoundaryKind, str] +VisibleTimeRangeBoundaryKindArrayLike = Union[ + VisibleTimeRangeBoundaryKindLike, Sequence[VisibleTimeRangeBoundaryKindLike] +] + + +class VisibleTimeRangeBoundaryKindType(BaseExtensionType): + _TYPE_NAME: str = "rerun.blueprint.datatypes.VisibleTimeRangeBoundaryKind" + + def __init__(self) -> None: + pa.ExtensionType.__init__( + self, + pa.sparse_union( + [ + pa.field("_null_markers", pa.null(), nullable=True, metadata={}), + pa.field("RelativeToTimeCursor", pa.null(), nullable=True, metadata={}), + pa.field("Absolute", pa.null(), nullable=True, metadata={}), + pa.field("Infinite", pa.null(), nullable=True, metadata={}), + ] + ), + self._TYPE_NAME, + ) + + +class VisibleTimeRangeBoundaryKindBatch(BaseBatch[VisibleTimeRangeBoundaryKindArrayLike]): + _ARROW_TYPE = VisibleTimeRangeBoundaryKindType() + + @staticmethod + def _native_to_pa_array(data: VisibleTimeRangeBoundaryKindArrayLike, data_type: pa.DataType) -> pa.Array: + if isinstance(data, (VisibleTimeRangeBoundaryKind, int, str)): + data = [data] + + types: list[int] = [] + + for value in data: + if value is None: + types.append(0) + elif isinstance(value, VisibleTimeRangeBoundaryKind): + types.append(value.value) # Actual enum value + elif isinstance(value, int): + types.append(value) # By number + elif isinstance(value, str): + if hasattr(VisibleTimeRangeBoundaryKind, value): + types.append(VisibleTimeRangeBoundaryKind[value].value) # fast path + elif value.lower() == "relativetotimecursor": + types.append(VisibleTimeRangeBoundaryKind.RelativeToTimeCursor.value) + elif value.lower() == "absolute": + types.append(VisibleTimeRangeBoundaryKind.Absolute.value) + elif value.lower() == "infinite": + types.append(VisibleTimeRangeBoundaryKind.Infinite.value) + else: + raise ValueError(f"Unknown VisibleTimeRangeBoundaryKind kind: {value}") + else: + raise ValueError(f"Unknown VisibleTimeRangeBoundaryKind kind: {value}") + + buffers = [ + None, + pa.array(types, type=pa.int8()).buffers()[1], + ] + children = (1 + 3) * [pa.nulls(len(data))] + + return pa.UnionArray.from_buffers( + type=data_type, + length=len(data), + buffers=buffers, + children=children, + ) diff --git a/rerun_py/rerun_sdk/rerun/datatypes/.gitattributes b/rerun_py/rerun_sdk/rerun/datatypes/.gitattributes index 02728bf929d2..74fd88d4d968 100644 --- a/rerun_py/rerun_sdk/rerun/datatypes/.gitattributes +++ b/rerun_py/rerun_sdk/rerun/datatypes/.gitattributes @@ -24,6 +24,7 @@ scale3d.py linguist-generated=true tensor_buffer.py linguist-generated=true tensor_data.py linguist-generated=true tensor_dimension.py linguist-generated=true +time_int.py linguist-generated=true transform3d.py linguist-generated=true translation_and_mat3x3.py linguist-generated=true translation_rotation_scale3d.py linguist-generated=true diff --git a/rerun_py/rerun_sdk/rerun/datatypes/__init__.py b/rerun_py/rerun_sdk/rerun/datatypes/__init__.py index 36fcb289aa61..31fb9e4f05e4 100644 --- a/rerun_py/rerun_sdk/rerun/datatypes/__init__.py +++ b/rerun_py/rerun_sdk/rerun/datatypes/__init__.py @@ -60,6 +60,7 @@ TensorDimensionLike, TensorDimensionType, ) +from .time_int import TimeInt, TimeIntArrayLike, TimeIntBatch, TimeIntLike, TimeIntType from .transform3d import Transform3D, Transform3DArrayLike, Transform3DBatch, Transform3DLike, Transform3DType from .translation_and_mat3x3 import ( TranslationAndMat3x3, @@ -197,6 +198,11 @@ "TensorDimensionBatch", "TensorDimensionLike", "TensorDimensionType", + "TimeInt", + "TimeIntArrayLike", + "TimeIntBatch", + "TimeIntLike", + "TimeIntType", "Transform3D", "Transform3DArrayLike", "Transform3DBatch", diff --git a/rerun_py/rerun_sdk/rerun/datatypes/time_int.py b/rerun_py/rerun_sdk/rerun/datatypes/time_int.py new file mode 100644 index 000000000000..56b224544a7c --- /dev/null +++ b/rerun_py/rerun_sdk/rerun/datatypes/time_int.py @@ -0,0 +1,59 @@ +# DO NOT EDIT! This file was auto-generated by crates/re_types_builder/src/codegen/python/mod.rs +# Based on "crates/re_types/definitions/rerun/datatypes/time_int.fbs". + +# You can extend this class by creating a "TimeIntExt" class in "time_int_ext.py". + +from __future__ import annotations + +from typing import Any, Sequence, Union + +import numpy as np +import numpy.typing as npt +import pyarrow as pa +from attrs import define, field + +from .._baseclasses import BaseBatch, BaseExtensionType + +__all__ = ["TimeInt", "TimeIntArrayLike", "TimeIntBatch", "TimeIntLike", "TimeIntType"] + + +@define(init=False) +class TimeInt: + """**Datatype**: A 64-bit number describing either nanoseconds OR sequence numbers.""" + + def __init__(self: Any, value: TimeIntLike): + """Create a new instance of the TimeInt datatype.""" + + # You can define your own __init__ function as a member of TimeIntExt in time_int_ext.py + self.__attrs_init__(value=value) + + value: int = field(converter=int) + + def __array__(self, dtype: npt.DTypeLike = None) -> npt.NDArray[Any]: + # You can define your own __array__ function as a member of TimeIntExt in time_int_ext.py + return np.asarray(self.value, dtype=dtype) + + def __int__(self) -> int: + return int(self.value) + + +TimeIntLike = TimeInt +TimeIntArrayLike = Union[ + TimeInt, + Sequence[TimeIntLike], +] + + +class TimeIntType(BaseExtensionType): + _TYPE_NAME: str = "rerun.datatypes.TimeInt" + + def __init__(self) -> None: + pa.ExtensionType.__init__(self, pa.int64(), self._TYPE_NAME) + + +class TimeIntBatch(BaseBatch[TimeIntArrayLike]): + _ARROW_TYPE = TimeIntType() + + @staticmethod + def _native_to_pa_array(data: TimeIntArrayLike, data_type: pa.DataType) -> pa.Array: + raise NotImplementedError # You need to implement native_to_pa_array_override in time_int_ext.py