From 0eb3f31260232aa233c60ba58e7cd33734aa87cb Mon Sep 17 00:00:00 2001 From: Guillaume Binet Date: Sun, 26 May 2024 15:03:33 -0400 Subject: [PATCH] Adds a rudimentary clock --- Cargo.toml | 2 +- copper_clock/Cargo.toml | 12 ++++++ copper_clock/src/lib.rs | 82 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 copper_clock/Cargo.toml create mode 100644 copper_clock/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index dda192bd8..95f3afa77 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,3 @@ [workspace] -members = ["copper", "copper_log_test", "copper_derive", "copper_derive_test", "copper_log", "examples/config_gen", "examples/pluginload", "examples/simplelogger", "examples/v4lsrc", "copper_log_runtime"] +members = ["copper", "copper_log_test", "copper_derive", "copper_derive_test", "copper_log", "examples/config_gen", "examples/pluginload", "examples/simplelogger", "examples/v4lsrc", "copper_log_runtime", "copper_datalogger", "copper_clock"] resolver = "2" diff --git a/copper_clock/Cargo.toml b/copper_clock/Cargo.toml new file mode 100644 index 000000000..379806473 --- /dev/null +++ b/copper_clock/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "copper_clock" +version = "0.1.0" +edition = "2021" + +[dependencies] +quanta = "0.12.3" +bincode = "2.0.0-rc.3" +bincode_derive = "2.0.0-rc.3" + +[dev-dependencies] +approx = "0.5.1" diff --git a/copper_clock/src/lib.rs b/copper_clock/src/lib.rs new file mode 100644 index 000000000..96fd7e6c0 --- /dev/null +++ b/copper_clock/src/lib.rs @@ -0,0 +1,82 @@ +pub use quanta::Instant; +use quanta::{Clock, Mock}; +use std::sync::Arc; +use std::time::Duration; + +#[cfg(test)] +#[macro_use] +extern crate approx; + +pub struct RobotClock { + inner: Clock, + ref_time: Instant, +} + +impl RobotClock { + pub fn new() -> Self { + let clock = Clock::new(); + let ref_time = clock.now(); + RobotClock { + inner: clock, + ref_time, + } + } + + // Builds a monotonic clock starting at the given reference time. + pub fn from_ref_time(ref_time_ns: u64) -> Self { + let clock = Clock::new(); + let ref_time = clock.now() - Duration::from_nanos(ref_time_ns); + RobotClock { + inner: Clock::new(), + ref_time, + } + } + + // Build a fake clock with a reference time of 0. + // The Mock interface enables you to increment and decrement the time. + pub fn mock() -> (Self, Arc) { + let (clock, mock) = Clock::mock(); + let ref_time = clock.now(); + ( + RobotClock { + inner: clock, + ref_time, + }, + mock, + ) + } + + pub fn elapsed(&self) -> Duration { + self.inner.now() - self.ref_time + } +} + +impl Default for RobotClock { + fn default() -> Self { + Self::new() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_mock() { + let (clock, mock) = RobotClock::mock(); + assert_eq!(clock.elapsed(), Duration::from_secs(0)); + mock.increment(Duration::from_secs(1)); + assert_eq!(clock.elapsed(), Duration::from_secs(1)); + } + + #[test] + fn test_from_ref_time() { + let tolerance_ms = 10; + let clock = RobotClock::from_ref_time(1_000_000_000); + assert_relative_eq!( + clock.elapsed().as_millis() as f64, + Duration::from_secs(1).as_millis() as f64, + epsilon = tolerance_ms as f64 + ); + } +}