re_view 0.38.1

Types & utilities for defining view classes and communicating with the viewport.
Documentation
//! Rerun View utilities
//!
//! Types & utilities for defining View classes and communicating with the Viewport.

pub mod controls;

mod annotation_context_resolver;
mod annotation_context_utils;
mod annotation_map_cache;
mod blueprint_resolved_results;
mod chunks_with_component;
mod clears;
mod component_drop;
mod component_mapping_error;
mod component_mapping_query_plan;
mod instance_hash_conversions;
mod outlines;
mod query;
mod source_selector;
mod system_execution;
mod time_axis;
mod view_highlights;
mod view_loading_indicator;
mod view_property_ui;
mod visualizer_query;

use std::borrow::Cow;

pub use annotation_context_utils::{process_color_slice, process_keypoint_slices};
pub use annotation_map_cache::AnnotationMapCache;
pub use blueprint_resolved_results::{
    BlueprintResolvedLatestAtResults, BlueprintResolvedRangeResults, BlueprintResolvedResults,
    BlueprintResolvedResultsExt, HybridResultsChunkIter,
};
pub use chunks_with_component::{
    ChunkWithComponent, ChunksWithComponent, MaybeChunksWithComponent,
};
pub use clears::collect_recursive_clears;
pub use component_drop::{ComponentDropResult, handle_component_drop};
pub use component_mapping_error::ComponentMappingError;
pub use instance_hash_conversions::{
    instance_path_hash_from_picking_layer_id, picking_layer_id_from_instance_path_hash,
};
pub use outlines::{
    SIZE_BOOST_IN_POINTS_FOR_LINE_OUTLINES, SIZE_BOOST_IN_POINTS_FOR_POINT_OUTLINES, outline_config,
};
pub use query::{
    ComponentCastRule, DataResultQuery, latest_at_with_blueprint_resolved_data,
    latest_at_with_blueprint_resolved_data_polymorphic, range_with_blueprint_resolved_data,
    range_with_blueprint_resolved_data_polymorphic, resolve_visible_time_range,
};
pub use source_selector::{
    SourceMappingContext, SourceSelectorContext, raw_default_or_fallback,
    raw_default_without_fallback, raw_value_for_mapping, save_component_mapping,
    source_selector_ui, visualizers_for_entity,
};
pub use system_execution::{execute_systems_for_view, new_view_query};
pub use time_axis::{
    cursor_centered_default_range, recover_relative_boundaries_after_zoom_or_pan,
    resolve_time_axis_range, set_time_cursor, time_axis_range_after_cursor_move,
    time_axis_time_from_plot,
};
pub use view_highlights::highlights_for_view;
pub use view_loading_indicator::paint_view_loading_indicator;
pub use view_property_ui::{
    view_property_component_ui, view_property_component_ui_custom, view_property_ui,
    view_property_ui_with_hidden_components, view_property_ui_with_redirect,
};
pub use visualizer_query::VisualizerInstructionQueryResults;

pub mod external {
    pub use re_entity_db::external::*;
}

/// Clamp the last value in `values` in order to reach a length of `clamped_len`.
///
/// Returns an empty iterator if values is empty.
#[inline]
pub fn clamped_or_nothing<T>(values: &[T], clamped_len: usize) -> impl Iterator<Item = &T> + Clone {
    let Some(last) = values.last() else {
        return itertools::Either::Left(std::iter::empty());
    };

    itertools::Either::Right(std::iter::chain(values, std::iter::repeat(last)).take(clamped_len))
}

/// Iterate over all the values in the slice, then repeat the last value forever.
///
/// If the input slice is empty, the second argument is returned forever.
#[inline]
pub fn clamped_or<'a, T>(values: &'a [T], if_empty: &'a T) -> impl Iterator<Item = &'a T> + Clone {
    let repeated = values.last().unwrap_or(if_empty);
    std::iter::chain(values, std::iter::repeat(repeated))
}

/// Iterate over all the values in the slice, then repeat the last value forever.
///
/// If the input slice is empty, the second argument is returned forever.
#[inline]
pub fn clamped_or_else<T: Clone>(
    values: &[T],
    if_empty: impl Fn() -> T,
) -> impl Iterator<Item = T> {
    let repeated = values.last().cloned().unwrap_or_else(if_empty);
    std::iter::chain(values.iter().cloned(), std::iter::repeat(repeated))
}

/// Clamp the last value in `values` in order to reach a length of `clamped_len`.
///
/// Returns an empty vector if values is empty.
#[inline]
pub fn clamped_vec_or_empty<T: Clone>(values: &[T], clamped_len: usize) -> Cow<'_, [T]> {
    if values.len() == clamped_len {
        // Happy path
        values.into()
    } else if let Some(last) = values.last() {
        if values.len() == 1 {
            // Commo happy path
            vec![last.clone(); clamped_len].into()
        } else if values.len() < clamped_len {
            // Clamp
            let mut vec = Vec::with_capacity(clamped_len);
            vec.extend(values.iter().cloned());
            vec.extend(std::iter::repeat_n(
                last.clone(),
                clamped_len - values.len(),
            ));
            vec.into()
        } else {
            // Trim
            values.iter().take(clamped_len).cloned().collect()
        }
    } else {
        // Empty input
        Vec::new().into()
    }
}

/// Clamp the last value in `values` in order to reach a length of `clamped_len`.
///
/// If the input slice is empty, the second argument is repeated `clamped_len` times.
#[inline]
pub fn clamped_vec_or<'a, T: Clone>(
    values: &'a [T],
    clamped_len: usize,
    if_empty: &T,
) -> Cow<'a, [T]> {
    let clamped = clamped_vec_or_empty(values, clamped_len);
    if clamped.is_empty() {
        vec![if_empty.clone(); clamped_len].into()
    } else {
        clamped
    }
}

/// Clamp the last value in `values` in order to reach a length of `clamped_len`.
///
/// If the input slice is empty, the second argument is repeated `clamped_len` times.
#[inline]
pub fn clamped_vec_or_else<T: Clone>(
    values: &[T],
    clamped_len: usize,
    if_empty: impl Fn() -> T,
) -> Cow<'_, [T]> {
    let clamped = clamped_vec_or_empty(values, clamped_len);
    if clamped.is_empty() {
        vec![if_empty(); clamped_len].into()
    } else {
        clamped
    }
}

#[test]
fn test_clamped_vec() {
    assert_eq!(clamped_vec_or_empty::<i32>(&[], 0), Vec::<i32>::default());
    assert_eq!(clamped_vec_or_empty::<i32>(&[], 3), Vec::<i32>::default());
    assert_eq!(
        clamped_vec_or_empty::<i32>(&[1, 2, 3], 0),
        Vec::<i32>::default()
    );
    assert_eq!(clamped_vec_or_empty::<i32>(&[1, 2, 3], 1), vec![1]);
    assert_eq!(clamped_vec_or_empty::<i32>(&[1, 2, 3], 2), vec![1, 2]);
    assert_eq!(clamped_vec_or_empty::<i32>(&[1, 2, 3], 3), vec![1, 2, 3]);
    assert_eq!(
        clamped_vec_or_empty::<i32>(&[1, 2, 3], 5),
        vec![1, 2, 3, 3, 3]
    );
}