1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
use arrow2::datatypes::{DataType, TimeUnit};
use crate::{time::TimeZone, TimeRange, TimeType};
re_string_interner::declare_new_type!(
/// The name of a timeline. Often something like `"log_time"` or `"frame_nr"`.
pub struct TimelineName;
);
impl Default for TimelineName {
fn default() -> Self {
Self::from(String::default())
}
}
// ----------------------------------------------------------------------------
/// A time frame/space, e.g. `log_time` or `frame_nr`, coupled with the type of time
/// it keeps.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Timeline {
/// Name of the timeline (e.g. "log_time").
name: TimelineName,
/// Sequence or time?
typ: TimeType,
}
impl Default for Timeline {
fn default() -> Self {
Self {
name: TimelineName::default(),
typ: TimeType::Sequence,
}
}
}
impl Timeline {
/// For absolute or relative time.
#[inline]
pub fn new_temporal(name: impl Into<TimelineName>) -> Self {
Self {
name: name.into(),
typ: TimeType::Time,
}
}
/// For things like camera frames or iteration count.
#[inline]
pub fn new_sequence(name: impl Into<TimelineName>) -> Self {
Self {
name: name.into(),
typ: TimeType::Sequence,
}
}
#[inline]
pub fn new(name: impl Into<TimelineName>, typ: TimeType) -> Self {
Self {
name: name.into(),
typ,
}
}
#[inline]
pub fn name(&self) -> &TimelineName {
&self.name
}
#[inline]
pub fn typ(&self) -> TimeType {
self.typ
}
/// The log time timeline to which all API functions will always log.
///
/// This timeline is automatically maintained by the SDKs and captures the wall-clock time at
/// which point the data was logged (according to the client's wall-clock).
#[inline]
pub fn log_time() -> Self {
Timeline::new("log_time", TimeType::Time)
}
/// The log tick timeline to which all API functions will always log.
///
/// This timeline is automatically maintained by the SDKs and captures the logging tick at
/// which point the data was logged.
/// The logging tick is monotically incremented each time the client calls one of the logging
/// methods on a `RecordingStream`.
#[inline]
pub fn log_tick() -> Self {
Timeline::new("log_tick", TimeType::Sequence)
}
/// Returns a formatted string of `time_range` on this `Timeline`.
#[inline]
pub fn format_time_range(
&self,
time_range: &TimeRange,
time_zone_for_timestamps: TimeZone,
) -> String {
format!(
"{}..={}",
self.typ.format(time_range.min, time_zone_for_timestamps),
self.typ.format(time_range.max, time_zone_for_timestamps),
)
}
/// Returns a formatted string of `time_range` on this `Timeline`.
#[inline]
pub fn format_time_range_utc(&self, time_range: &TimeRange) -> String {
self.format_time_range(time_range, TimeZone::Utc)
}
/// Returns the appropriate arrow datatype to represent this timeline.
#[inline]
pub fn datatype(&self) -> DataType {
match self.typ {
TimeType::Time => DataType::Timestamp(TimeUnit::Nanosecond, None),
TimeType::Sequence => DataType::Int64,
}
}
}
impl nohash_hasher::IsEnabled for Timeline {}
impl re_types_core::SizeBytes for Timeline {
#[inline]
fn heap_size_bytes(&self) -> u64 {
0
}
}
// required for [`nohash_hasher`].
#[allow(clippy::derived_hash_with_manual_eq)]
impl std::hash::Hash for Timeline {
#[inline]
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
state.write_u64(self.name.hash() ^ self.typ.hash());
}
}