1use core::time::Duration;
2
3pub(crate) trait Clamp {
4 fn clamp(self, lower: Self, upper: Self) -> Self;
5}
6
7impl<C: PartialOrd> Clamp for C {
8 fn clamp(self, lower: Self, upper: Self) -> Self {
9 if self < lower {
10 lower
11 } else if upper < self {
12 upper
13 } else {
14 self
15 }
16 }
17}
18
19pub(crate) trait DurationHelpers {
22 fn from_secs_f32_2(secs: f32) -> Self;
23
24 fn as_secs_f32_2(&self) -> f32;
25}
26
27const NANOS_PER_SEC: u32 = 1_000_000_000;
28
29impl DurationHelpers for Duration {
30 fn from_secs_f32_2(secs: f32) -> Self {
31 let nanos = secs * (NANOS_PER_SEC as f32);
34 assert!(nanos.is_finite());
35
36 let nanos = nanos as u128;
37 Duration::new(
38 (nanos / u128::from(NANOS_PER_SEC)) as u64,
39 (nanos % u128::from(NANOS_PER_SEC)) as u32,
40 )
41 }
42
43 fn as_secs_f32_2(&self) -> f32 {
44 (self.as_secs() as f32)
45 + (self.subsec_nanos() as f32) / (NANOS_PER_SEC as f32)
46 }
47}
48
49#[derive(Debug, Clone, PartialEq)]
52pub struct CummulativeSteps {
53 steps_per_unit: f32,
54 steps: f32,
55}
56
57impl CummulativeSteps {
58 pub const fn new(steps_per_unit: f32) -> CummulativeSteps {
61 CummulativeSteps {
62 steps: 0.0,
63 steps_per_unit,
64 }
65 }
66
67 pub const fn real_location(&self) -> f32 { self.steps }
69
70 pub const fn steps_per_unit(&self) -> f32 { self.steps_per_unit }
72
73 pub const fn with_steps_per_unit(
74 &self,
75 steps_per_unit: f32,
76 ) -> CummulativeSteps {
77 CummulativeSteps {
78 steps_per_unit,
79 steps: self.steps,
80 }
81 }
82
83 pub fn move_by(&mut self, delta: f32) -> i64 {
85 let previous_steps = self.steps.round();
86
87 self.steps += delta * self.steps_per_unit;
88 let rounded_steps = (self.steps - previous_steps).round();
89
90 rounded_steps as i64
91 }
92}