use re_data_store::{DataStore, LatestAtQuery, RangeQuery, TimeInt, TimeRange, Timeline};
use re_log_types::EntityPath;
use re_types_core::Archetype;
use crate::{query_archetype, range::range_archetype, ArchetypeView};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum VisibleHistoryBoundary {
RelativeToTimeCursor(i64),
Absolute(i64),
Infinite,
}
impl VisibleHistoryBoundary {
pub const AT_CURSOR: Self = Self::RelativeToTimeCursor(0);
}
impl Default for VisibleHistoryBoundary {
fn default() -> Self {
Self::AT_CURSOR
}
}
#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)]
pub struct VisibleHistory {
pub from: VisibleHistoryBoundary,
pub to: VisibleHistoryBoundary,
}
impl VisibleHistory {
pub const OFF: Self = Self {
from: VisibleHistoryBoundary::AT_CURSOR,
to: VisibleHistoryBoundary::AT_CURSOR,
};
pub const ALL: Self = Self {
from: VisibleHistoryBoundary::Infinite,
to: VisibleHistoryBoundary::Infinite,
};
#[doc(hidden)]
pub fn range_start_from_cursor(&self, cursor: TimeInt) -> TimeInt {
match self.from {
VisibleHistoryBoundary::Absolute(value) => TimeInt::from(value),
VisibleHistoryBoundary::RelativeToTimeCursor(value) => cursor + TimeInt::from(value),
VisibleHistoryBoundary::Infinite => TimeInt::MIN,
}
}
#[doc(hidden)]
pub fn range_end_from_cursor(&self, cursor: TimeInt) -> TimeInt {
match self.to {
VisibleHistoryBoundary::Absolute(value) => TimeInt::from(value),
VisibleHistoryBoundary::RelativeToTimeCursor(value) => cursor + TimeInt::from(value),
VisibleHistoryBoundary::Infinite => TimeInt::MAX,
}
}
pub fn time_range(&self, cursor: TimeInt) -> TimeRange {
let mut from = self.range_start_from_cursor(cursor);
let mut to = self.range_end_from_cursor(cursor);
if from > to {
std::mem::swap(&mut from, &mut to);
}
TimeRange::new(from, to)
}
}
#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)]
pub struct ExtraQueryHistory {
pub enabled: bool,
pub nanos: VisibleHistory,
pub sequences: VisibleHistory,
}
pub fn query_archetype_with_history<'a, A: Archetype + 'a, const N: usize>(
store: &'a DataStore,
timeline: &'a Timeline,
time: &'a TimeInt,
history: &ExtraQueryHistory,
ent_path: &'a EntityPath,
) -> crate::Result<impl Iterator<Item = ArchetypeView<A>> + 'a> {
let visible_history = match timeline.typ() {
re_log_types::TimeType::Time => history.nanos,
re_log_types::TimeType::Sequence => history.sequences,
};
let time_range = visible_history.time_range(*time);
if !history.enabled || time_range.min == time_range.max {
let latest_query = LatestAtQuery::new(*timeline, time_range.min);
let latest = query_archetype::<A>(store, &latest_query, ent_path)?;
Ok(itertools::Either::Left(std::iter::once(latest)))
} else {
let range_query = RangeQuery::new(*timeline, time_range);
let range = range_archetype::<A, N>(store, &range_query, ent_path);
Ok(itertools::Either::Right(range))
}
}