re_log_types/index/
time_point.rs1use std::collections::{BTreeMap, btree_map};
2
3use super::{NonMinI64, TimeCell, TimeInt, Timeline, TimelineName};
4
5#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
13#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
14pub struct TimePoint(BTreeMap<TimelineName, TimeCell>);
15
16impl From<BTreeMap<TimelineName, TimeCell>> for TimePoint {
17 fn from(map: BTreeMap<TimelineName, TimeCell>) -> Self {
18 Self(map)
19 }
20}
21
22impl TimePoint {
23 pub const STATIC: Self = Self(BTreeMap::new());
25
26 #[inline]
27 pub fn get(&self, timeline_name: &TimelineName) -> Option<NonMinI64> {
28 self.0.get(timeline_name).map(|cell| cell.value)
29 }
30
31 #[inline]
32 pub fn insert_cell(
33 &mut self,
34 timeline_name: impl Into<TimelineName>,
35 cell: impl Into<TimeCell>,
36 ) {
37 let timeline_name = timeline_name.into();
38 let cell = cell.into();
39
40 match self.0.entry(timeline_name) {
41 btree_map::Entry::Vacant(vacant_entry) => {
42 vacant_entry.insert(cell);
43 }
44 btree_map::Entry::Occupied(mut occupied_entry) => {
45 let existing_typ = occupied_entry.get().typ();
46 if existing_typ != cell.typ() {
47 re_log::warn_once!(
48 "Timeline {timeline_name:?} changed type from {existing_typ:?} to {:?}. \
49 Rerun does not support using different types for the same timeline.",
50 cell.typ()
51 );
52 }
53 occupied_entry.insert(cell);
54 }
55 }
56 }
57
58 #[inline]
59 pub fn insert(&mut self, timeline: Timeline, time: impl TryInto<TimeInt>) {
60 let cell = TimeCell::new(timeline.typ(), TimeInt::saturated_temporal(time).as_i64());
61 self.insert_cell(*timeline.name(), cell);
62 }
63
64 #[must_use]
65 #[inline]
66 pub fn with_index(
67 mut self,
68 timeline_name: impl Into<TimelineName>,
69 cell: impl Into<TimeCell>,
70 ) -> Self {
71 self.insert_cell(timeline_name, cell);
72 self
73 }
74
75 #[must_use]
76 #[inline]
77 pub fn with(mut self, timeline: Timeline, time: impl TryInto<TimeInt>) -> Self {
78 self.insert(timeline, time);
79 self
80 }
81
82 #[inline]
83 pub fn remove(&mut self, timeline: &TimelineName) {
84 self.0.remove(timeline);
85 }
86
87 #[inline]
88 pub fn is_static(&self) -> bool {
89 self.0.is_empty()
90 }
91
92 #[inline]
93 pub fn is_empty(&self) -> bool {
94 self.0.is_empty()
95 }
96
97 #[inline]
98 pub fn timeline_names(&self) -> impl ExactSizeIterator<Item = &TimelineName> {
99 self.0.keys()
100 }
101
102 #[inline]
103 pub fn iter(&self) -> impl ExactSizeIterator<Item = (&TimelineName, &TimeCell)> {
104 self.0.iter()
105 }
106}
107
108impl re_byte_size::SizeBytes for TimePoint {
109 #[inline]
110 fn heap_size_bytes(&self) -> u64 {
111 self.0.heap_size_bytes()
112 }
113}
114
115impl IntoIterator for TimePoint {
118 type Item = (TimelineName, TimeCell);
119
120 type IntoIter = btree_map::IntoIter<TimelineName, TimeCell>;
121
122 #[inline]
123 fn into_iter(self) -> Self::IntoIter {
124 self.0.into_iter()
125 }
126}
127
128impl<'a> IntoIterator for &'a TimePoint {
129 type Item = (&'a TimelineName, &'a TimeCell);
130
131 type IntoIter = btree_map::Iter<'a, TimelineName, TimeCell>;
132
133 #[inline]
134 fn into_iter(self) -> Self::IntoIter {
135 self.0.iter()
136 }
137}
138
139impl<Name, Cell> FromIterator<(Name, Cell)> for TimePoint
140where
141 Name: Into<TimelineName>,
142 Cell: Into<TimeCell>,
143{
144 #[inline]
145 fn from_iter<I: IntoIterator<Item = (Name, Cell)>>(iter: I) -> Self {
146 Self(
147 iter.into_iter()
148 .map(|(name, cell)| (name.into(), cell.into()))
149 .collect(),
150 )
151 }
152}
153
154impl<Name, Cell, const N: usize> From<[(Name, Cell); N]> for TimePoint
155where
156 Name: Into<TimelineName>,
157 Cell: Into<TimeCell>,
158{
159 #[inline]
160 fn from(timelines: [(Name, Cell); N]) -> Self {
161 Self(
162 timelines
163 .into_iter()
164 .map(|(name, cell)| (name.into(), cell.into()))
165 .collect(),
166 )
167 }
168}
169
170impl<T: TryInto<TimeInt>> FromIterator<(Timeline, T)> for TimePoint {
171 #[inline]
172 fn from_iter<I: IntoIterator<Item = (Timeline, T)>>(iter: I) -> Self {
173 Self(
174 iter.into_iter()
175 .map(|(timeline, time)| {
176 let time = TimeInt::saturated_temporal(time);
177 (
178 *timeline.name(),
179 TimeCell::new(timeline.typ(), time.as_i64()),
180 )
181 })
182 .collect(),
183 )
184 }
185}
186
187impl<T: TryInto<TimeInt>, const N: usize> From<[(Timeline, T); N]> for TimePoint {
188 #[inline]
189 fn from(timelines: [(Timeline, T); N]) -> Self {
190 Self(
191 timelines
192 .into_iter()
193 .map(|(timeline, time)| {
194 let time = TimeInt::saturated_temporal(time);
195 (
196 *timeline.name(),
197 TimeCell::new(timeline.typ(), time.as_i64()),
198 )
199 })
200 .collect(),
201 )
202 }
203}