devela/phys/time/source/
impl_source.rs1use crate::{TimePoint, TimeScale, TimeSource, TimeSourceCfg};
16
17#[rustfmt::skip]
20impl<T, P> TimeSourceCfg<P> for T
21where
22 T: TimeSource<P>,
23 P: TimePoint,
24{
25 type Config = ();
26
27 fn time_is_monotonic((): ()) -> bool { T::time_is_monotonic() }
28 fn time_is_absolute((): ()) -> bool { T::time_is_absolute() }
29 fn time_scale((): ()) -> TimeScale { T::time_scale() }
30
31 fn time_now((): ()) -> P { T::time_now() }
32 fn time_point_value((): (), point: P) -> u64 { T::time_point_value(point) }
33 fn time_elapsed_value((): (), elapsed: P::Elapsed) -> u64 { T::time_elapsed_value(elapsed) }
34
35 fn time_now_millis((): ()) -> u64 { T::time_now_millis() }
36 fn time_now_micros((): ()) -> u64 { T::time_now_micros() }
37 fn time_now_nanos((): ()) -> u64 { T::time_now_nanos() }
38 fn time_now_millis_f64((): ()) -> f64 { T::time_now_millis_f64() }
39}
40
41#[rustfmt::skip]
42#[cfg(feature = "std")]
43#[cfg_attr(nightly_doc, doc(cfg(feature = "std")))]
44mod impl_std {
45 use crate::{Duration, UNIX_EPOCH, OnceLock, SystemInstant, SystemTime};
46 use super::*;
47 impl TimeSource<SystemTime> for SystemTime { fn time_is_monotonic() -> bool { false }
48 fn time_is_absolute() -> bool { true }
49 fn time_scale() -> TimeScale { TimeScale::Nanos }
50 fn time_now() -> SystemTime { SystemTime::now() }
51 fn time_point_value(point: SystemTime) -> u64 {
52 point.duration_since(UNIX_EPOCH).expect("backwards system time").as_nanos() as u64
53 }
54 fn time_elapsed_value(elapsed: Duration) -> u64 { elapsed.as_nanos() as u64 }
55 }
56 impl TimeSource<u64> for SystemTime {
61 fn time_is_monotonic() -> bool { false }
62 fn time_is_absolute() -> bool { true }
63 fn time_scale() -> TimeScale { TimeScale::Nanos }
64 fn time_now() -> u64 { SystemTime::now()
65 .duration_since(UNIX_EPOCH).expect("backwards system time").as_nanos() as u64
66 }
67 fn time_point_value(point: u64) -> u64 { point }
68 fn time_elapsed_value(elapsed: u64) -> u64 { elapsed }
69 }
70 impl TimeSource<u32> for SystemTime {
75 fn time_is_monotonic() -> bool { false }
76 fn time_is_absolute() -> bool { true }
77 fn time_scale() -> TimeScale { TimeScale::Seconds }
78 fn time_now() -> u32 {
79 u32::try_from(
80 SystemTime::now()
81 .duration_since(UNIX_EPOCH)
82 .expect("backwards system time")
83 .as_secs()
84 ).expect("SystemTime u32 second projection overflow")
85 }
86 fn time_point_value(point: u32) -> u64 { point.into() }
87 fn time_elapsed_value(elapsed: u32) -> u64 { elapsed.into() }
88 }
89
90 static SYSTEM_INSTANT_BASE: OnceLock<SystemInstant> = OnceLock::new();
102
103 impl TimeSource<SystemInstant> for SystemInstant {
104 fn time_is_monotonic() -> bool { true }
105 fn time_is_absolute() -> bool { false }
106 fn time_scale() -> TimeScale { TimeScale::Nanos }
107 fn time_now() -> SystemInstant { SystemInstant::now() }
108 fn time_point_value(point: SystemInstant) -> u64 {
109 let base = SYSTEM_INSTANT_BASE.get_or_init(SystemInstant::now);
110 point.duration_since(*base).as_nanos() as u64
111 }
112 fn time_elapsed_value(elapsed: Duration) -> u64 { elapsed.as_nanos() as u64 }
113 }
114 impl TimeSource<u64> for SystemInstant {
119 fn time_is_monotonic() -> bool { true }
120 fn time_is_absolute() -> bool { false }
121 fn time_scale() -> TimeScale { TimeScale::Nanos }
122 fn time_now() -> u64 {
123 let base = SYSTEM_INSTANT_BASE.get_or_init(SystemInstant::now);
124 base.elapsed().as_nanos() as u64
125 }
126 fn time_point_value(point: u64) -> u64 { point }
127 fn time_elapsed_value(elapsed: u64) -> u64 { elapsed }
128 }
129 impl TimeSource<u32> for SystemInstant {
136 fn time_is_monotonic() -> bool { true }
137 fn time_is_absolute() -> bool { false }
138 fn time_scale() -> TimeScale { TimeScale::Micros }
139 fn time_now() -> u32 {
140 let base = SYSTEM_INSTANT_BASE.get_or_init(SystemInstant::now);
141 u32::try_from(base.elapsed().as_micros())
142 .expect("SystemInstant u32 projection overflow")
143 }
144 fn time_point_value(point: u32) -> u64 { point.into() }
145 fn time_elapsed_value(elapsed: u32) -> u64 { elapsed.into() }
146 }
147}
148
149#[rustfmt::skip]
150#[cfg(all(feature = "web", not(windows)))]
151mod impl_js {
152 use crate::JsInstant;
153 use super::*;
154
155 impl TimeSource<u64> for JsInstant {
162 fn time_is_monotonic() -> bool { true }
163 fn time_is_absolute() -> bool { false }
164 fn time_scale() -> TimeScale { TimeScale::Millis }
165 fn time_now() -> u64 { JsInstant::now().as_millis_f64() as u64 }
166 fn time_point_value(point: u64) -> u64 { point }
167 fn time_elapsed_value(elapsed: u64) -> u64 { elapsed }
168 fn time_now_millis_f64() -> f64 { JsInstant::now().as_millis_f64() }
169 }
170 impl TimeSource<u32> for JsInstant {
177 fn time_is_monotonic() -> bool { true }
178 fn time_is_absolute() -> bool { false }
179 fn time_scale() -> TimeScale { TimeScale::Millis }
180 fn time_now() -> u32 {
181 u32::try_from(JsInstant::now().as_millis_f64() as u64)
182 .expect("JsInstant u32 millisecond projection overflow")
183 }
184 fn time_point_value(point: u32) -> u64 { point.into() }
185 fn time_elapsed_value(elapsed: u32) -> u64 { elapsed.into() }
186 fn time_now_millis_f64() -> f64 { JsInstant::now().as_millis_f64() }
187 }
188}