73 lines
2.4 KiB
Diff
73 lines
2.4 KiB
Diff
diff --git a/src/timer.rs b/src/timer.rs
|
|
index ae60b07..2e7d544 100644
|
|
--- a/src/timer.rs
|
|
+++ b/src/timer.rs
|
|
@@ -178,7 +178,7 @@ impl<'a> Timer<'a> {
|
|
}
|
|
}
|
|
|
|
-#[derive(Copy, Clone, Debug)]
|
|
+#[derive(Copy, Clone, Debug, PartialEq)]
|
|
pub struct ClockFrequency {
|
|
hz: usize,
|
|
}
|
|
@@ -196,21 +196,53 @@ pub struct ClockValue {
|
|
}
|
|
|
|
impl ClockValue {
|
|
+ pub const fn new(num_ticks: isize, clock_hz: usize) -> ClockValue {
|
|
+ ClockValue {
|
|
+ num_ticks,
|
|
+ clock_frequency: ClockFrequency { hz: clock_hz },
|
|
+ }
|
|
+ }
|
|
+
|
|
pub fn num_ticks(&self) -> isize {
|
|
self.num_ticks
|
|
}
|
|
|
|
+ // Computes (value * factor) / divisor, even when value * factor >= isize::MAX.
|
|
+ fn scale_int(value: isize, factor: isize, divisor: isize) -> isize {
|
|
+ // As long as isize is not i64, this should be fine. If not, this is an alternative:
|
|
+ // factor * (value / divisor) + ((value % divisor) * factor) / divisor
|
|
+ ((value as i64 * factor as i64) / divisor as i64) as isize
|
|
+ }
|
|
+
|
|
pub fn ms(&self) -> isize {
|
|
- if self.num_ticks.abs() < isize::MAX / 1000 {
|
|
- (1000 * self.num_ticks) / self.clock_frequency.hz() as isize
|
|
- } else {
|
|
- 1000 * (self.num_ticks / self.clock_frequency.hz() as isize)
|
|
- }
|
|
+ ClockValue::scale_int(self.num_ticks, 1000, self.clock_frequency.hz() as isize)
|
|
}
|
|
|
|
pub fn ms_f64(&self) -> f64 {
|
|
1000.0 * (self.num_ticks as f64) / (self.clock_frequency.hz() as f64)
|
|
}
|
|
+
|
|
+ pub fn wrapping_add(self, duration: Duration<isize>) -> ClockValue {
|
|
+ // This is a precision preserving formula for scaling an isize.
|
|
+ let duration_ticks =
|
|
+ ClockValue::scale_int(duration.ms, self.clock_frequency.hz() as isize, 1000);
|
|
+ ClockValue {
|
|
+ num_ticks: self.num_ticks.wrapping_add(duration_ticks),
|
|
+ clock_frequency: self.clock_frequency,
|
|
+ }
|
|
+ }
|
|
+
|
|
+ pub fn wrapping_sub(self, other: ClockValue) -> Option<Duration<isize>> {
|
|
+ if self.clock_frequency == other.clock_frequency {
|
|
+ let clock_duration = ClockValue {
|
|
+ num_ticks: self.num_ticks - other.num_ticks,
|
|
+ clock_frequency: self.clock_frequency,
|
|
+ };
|
|
+ Some(Duration::from_ms(clock_duration.ms()))
|
|
+ } else {
|
|
+ None
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
pub struct Alarm {
|