Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_core/src/time.rs

3.1 KiB, 26 runs

created by r1870400018:126, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1use crate::{
2 prelude::*,
3};
4
5use std::time::Duration;
6#[cfg(not(target_arch = "wasm32"))]
7use std::{
8 time::Instant,
9 thread,
10};
11
12/// Waits for the given boolean function to become true, or for the maximum duration to be reached.
13/// Returns the starting `Instant` and whether the operation timed out. Returns an error if the
14/// given `Duration`s are inconsistent.
15#[cfg(not(target_arch = "wasm32"))]
16pub fn wait_for_true(
17 check_interval: Duration,
18 max_wait: Duration,
19 fn_true: impl Fn() -> bool,
20)
21 -> Outcome<(Instant, bool)>
22{
23 if check_interval > max_wait {
24 return Err(err!(
25 "The given check interval, {:?}, should not be larger than the \
26 given max wait, {:?}.", check_interval, max_wait;
27 Invalid, Input));
28 }
29 let start = Instant::now();
30 loop {
31 if fn_true() {
32 return Ok((start, false));
33 } else {
34 thread::sleep(check_interval);
35 }
36 if start.elapsed() > max_wait {
37 return Ok((start, true));
38 }
39 }
40}
41
42#[cfg(target_arch = "wasm32")]
43pub fn wait_for_true(
44 _check_interval: Duration,
45 _max_wait: Duration,
46 _fn_true: impl Fn() -> bool,
47)
48 -> Outcome<(std::time::Instant, bool)>
49{
50 Err(err!(
51 "wait_for_true blocks the calling thread and is unavailable on the \
52 wasm32 target; use an asynchronous wait instead.";
53 Unimplemented))
54}
55
56/// A simple system clock stopwatch.
57#[derive(Debug, PartialEq, Copy, Clone)]
58pub struct Timer {
59 #[cfg(not(target_arch = "wasm32"))]
60 t0: Instant,
61 #[cfg(target_arch = "wasm32")]
62 t0: f64,
63 last: usize,
64}
65
66impl Timer {
67 #[cfg(not(target_arch = "wasm32"))]
68 pub fn new() -> Self {
69 Self {
70 t0: Instant::now(),
71 last: 0,
72 }
73 }
74
75 #[cfg(target_arch = "wasm32")]
76 pub fn new() -> Self {
77 Self {
78 t0: crate::wasm::now_ms(),
79 last: 0,
80 }
81 }
82
83 #[cfg(not(target_arch = "wasm32"))]
84 pub fn reset(&mut self) {
85 self.t0 = Instant::now();
86 self.last = 0;
87 }
88
89 #[cfg(target_arch = "wasm32")]
90 pub fn reset(&mut self) {
91 self.t0 = crate::wasm::now_ms();
92 self.last = 0;
93 }
94
95 #[cfg(not(target_arch = "wasm32"))]
96 pub fn split_micros(&mut self) -> Outcome<usize> {
97 self.last = try_sub!(self.t0.elapsed().as_micros() as usize, self.last);
98 Ok(self.last)
99 }
100
101 #[cfg(target_arch = "wasm32")]
102 pub fn split_micros(&mut self) -> Outcome<usize> {
103 let elapsed = ((crate::wasm::now_ms() - self.t0) * 1_000.0) as usize;
104 self.last = try_sub!(elapsed, self.last);
105 Ok(self.last)
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112 use std::thread::sleep;
113
114 #[test]
115 fn test_timer() -> Outcome<()> {
116 let mut t0 = Timer::new();
117 sleep(Duration::from_micros(1000));
118 let mut t = res!(t0.split_micros());
119 msg!("timer split: {}", t);
120 sleep(Duration::from_micros(2000));
121 t = res!(t0.split_micros());
122 msg!("timer split: {}", t);
123 Ok(())
124 }
125}