#![warn(clippy::iter_over_hash_type)]
use re_log_types::EntityPath;
use re_sdk_types::reflection::ComponentDescriptorExt as _;
use re_sdk_types::{ComponentDescriptor, RowId};
use re_ui::UiExt as _;
use re_viewer_context::{UiLayout, ViewerContext};
mod annotation_context;
mod app_id;
mod blob;
mod component;
mod component_path;
mod component_type;
mod component_ui_registry;
mod data_source;
mod entity_db;
mod entity_path;
mod image;
mod instance_path;
mod store_id;
mod tensor;
mod transform_frames;
mod video;
mod extra_data_ui;
pub mod item_ui;
pub use component::ComponentPathLatestAtResults;
pub use component_ui_registry::{add_to_registry, register_component_uis};
pub use image::image_preview_ui;
pub use instance_path::archetype_label_list_item_ui;
use re_chunk_store::UnitChunkShared;
use re_types_core::reflection::Reflection;
use re_types_core::{ArchetypeName, Component};
pub use crate::tensor::tensor_summary_ui_grid_contents;
pub type ArchetypeComponentMap =
std::collections::BTreeMap<Option<ArchetypeName>, Vec<ComponentDescriptor>>;
pub fn sorted_component_list_by_archetype_for_ui(
reflection: &Reflection,
iter: impl IntoIterator<Item = ComponentDescriptor>,
) -> ArchetypeComponentMap {
let mut map = iter
.into_iter()
.fold(ArchetypeComponentMap::default(), |mut acc, descriptor| {
acc.entry(descriptor.archetype)
.or_default()
.push(descriptor);
acc
});
for (archetype, components) in &mut map {
if let Some(reflection) = archetype
.as_ref()
.and_then(|a| reflection.archetypes.get(a))
{
components.sort_by_key(|c| {
reflection
.fields
.iter()
.position(|field| field.name == c.archetype_field_name())
.unwrap_or(usize::MAX)
});
} else {
components.sort_by_key(|c| c.display_name().to_owned());
}
}
map
}
pub trait DataUi {
fn data_ui(
&self,
ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
ui_layout: UiLayout,
query: &re_chunk_store::LatestAtQuery,
db: &re_entity_db::EntityDb,
);
fn data_ui_recording(&self, ctx: &ViewerContext<'_>, ui: &mut egui::Ui, ui_layout: UiLayout) {
ui.sanity_check();
self.data_ui(ctx, ui, ui_layout, &ctx.current_query(), ctx.recording());
ui.sanity_check();
}
}
pub trait EntityDataUi {
#[expect(clippy::too_many_arguments)]
fn entity_data_ui(
&self,
ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
ui_layout: UiLayout,
entity_path: &EntityPath,
component_descriptor: &ComponentDescriptor,
row_id: Option<RowId>,
query: &re_chunk_store::LatestAtQuery,
db: &re_entity_db::EntityDb,
);
}
impl<T> EntityDataUi for T
where
T: DataUi,
{
fn entity_data_ui(
&self,
ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
ui_layout: UiLayout,
entity_path: &EntityPath,
_component_descriptor: &ComponentDescriptor,
_row_id: Option<RowId>,
query: &re_chunk_store::LatestAtQuery,
db: &re_entity_db::EntityDb,
) {
ui.push_id(entity_path.hash(), |ui| {
self.data_ui(ctx, ui, ui_layout, query, db);
});
}
}
pub fn annotations(
ctx: &ViewerContext<'_>,
query: &re_chunk_store::LatestAtQuery,
entity_path: &re_entity_db::EntityPath,
) -> std::sync::Arc<re_viewer_context::Annotations> {
re_tracing::profile_function!();
let mut annotation_map = re_viewer_context::AnnotationMap::default();
annotation_map.load(ctx, query);
annotation_map.find(entity_path)
}
fn find_and_deserialize_archetype_mono_component<C: Component>(
components: &[(ComponentDescriptor, UnitChunkShared)],
archetype_name: Option<ArchetypeName>,
) -> Option<C> {
components.iter().find_map(|(descr, chunk)| {
(descr.component_type == Some(C::name()) && descr.archetype == archetype_name)
.then(|| chunk.component_mono::<C>(descr.component)?.ok())
.flatten()
})
}