1#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
3pub struct Timescale(u64);
4
5impl Timescale {
6 pub const NANOSECOND: Self = Self(1_000_000_000);
7
8 pub const fn new(v: u64) -> Self {
9 Self(v)
10 }
11}
12
13#[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub struct Time(pub i64);
16
17impl re_byte_size::SizeBytes for Time {
18 fn heap_size_bytes(&self) -> u64 {
19 0
20 }
21
22 fn is_pod() -> bool {
23 true
24 }
25}
26
27const fn const_round_f64(v: f64) -> i64 {
32 if v > 0.0 {
33 (v + 0.5) as i64
34 } else {
35 (v - 0.5) as i64
36 }
37}
38
39impl Time {
40 pub const ZERO: Self = Self(0);
41 pub const MAX: Self = Self(i64::MAX);
42 pub const MIN: Self = Self(i64::MIN);
43
44 #[inline]
51 pub fn new(v: i64) -> Self {
52 Self(v)
53 }
54
55 #[inline]
56 pub const fn from_secs(secs_since_start: f64, timescale: Timescale) -> Self {
57 Self(const_round_f64(secs_since_start * timescale.0 as f64))
58 }
59
60 #[inline]
61 pub const fn from_millis(millis_since_start: f64, timescale: Timescale) -> Self {
62 Self::from_secs(millis_since_start / 1e3, timescale)
63 }
64
65 #[inline]
66 pub const fn from_micros(micros_since_start: f64, timescale: Timescale) -> Self {
67 Self::from_secs(micros_since_start / 1e6, timescale)
68 }
69
70 #[inline]
71 pub const fn from_nanos(nanos_since_start: i64, timescale: Timescale) -> Self {
72 Self::from_secs(nanos_since_start as f64 / 1e9, timescale)
73 }
74
75 #[inline]
77 pub fn duration(self, timescale: Timescale) -> std::time::Duration {
78 std::time::Duration::from_nanos(self.into_nanos(timescale) as _)
79 }
80
81 #[inline]
82 pub fn into_secs(self, timescale: Timescale) -> f64 {
83 self.0 as f64 / timescale.0 as f64
84 }
85
86 #[inline]
87 pub fn into_millis(self, timescale: Timescale) -> f64 {
88 self.into_secs(timescale) * 1e3
89 }
90
91 #[inline]
92 pub fn into_micros(self, timescale: Timescale) -> f64 {
93 self.into_secs(timescale) * 1e6
94 }
95
96 #[inline]
97 pub fn into_nanos(self, timescale: Timescale) -> i64 {
98 (self.into_secs(timescale) * 1e9).round() as i64
99 }
100}
101
102impl std::fmt::Debug for Time {
103 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104 self.0.fmt(f)
105 }
106}
107
108impl std::ops::Add for Time {
109 type Output = Self;
110
111 #[inline]
112 fn add(self, rhs: Self) -> Self::Output {
113 Self(self.0.saturating_add(rhs.0))
114 }
115}
116
117impl std::ops::Sub for Time {
118 type Output = Self;
119
120 #[inline]
121 fn sub(self, rhs: Self) -> Self::Output {
122 Self(self.0.saturating_sub(rhs.0))
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129
130 #[test]
131 fn test_const_round_f64() {
132 assert_eq!(const_round_f64(1.5), 2);
133 assert_eq!(const_round_f64(2.5), 3);
134 assert_eq!(const_round_f64(1.499999999), 1);
135 assert_eq!(const_round_f64(2.499999999), 2);
136 assert_eq!(const_round_f64(-1.5), -2);
137 assert_eq!(const_round_f64(-2.5), -3);
138 assert_eq!(const_round_f64(-1.499999999), -1);
139 assert_eq!(const_round_f64(-2.499999999), -2);
140 }
141}