aboutsummaryrefslogtreecommitdiff
path: root/clock
diff options
context:
space:
mode:
authorAndreas Grois <andi@grois.info>2021-04-20 23:49:47 +0200
committerAndreas Grois <andi@grois.info>2021-04-20 23:49:47 +0200
commita162325484a90d7531b7142f0fc790b1abf30c79 (patch)
treec57656bca34d23fb41defd55e85aa4ec49693730 /clock
parente1a78dd03e4e60d667254fcaaeb4f7f1f7459ae6 (diff)
Simple synchronized clock (limited to full seconds or 1/x seconds)
Diffstat (limited to 'clock')
-rw-r--r--clock/src/lib.rs49
1 files changed, 35 insertions, 14 deletions
diff --git a/clock/src/lib.rs b/clock/src/lib.rs
index 21f2079..4ee0b7a 100644
--- a/clock/src/lib.rs
+++ b/clock/src/lib.rs
@@ -14,19 +14,36 @@ impl<'c> ClockRunnable<'c> {
let now = chrono::offset::Local::now();
now.format(&self.config.format).to_string()
}
- fn simple_loop(&self) {
+ fn simple_loop(&self, timeout : std::time::Duration) {
loop {
self.to_main.send_update(Ok(self.print_current_time_with_format())).expect("Clock plugin tried to send the current time to the main program, but the main program doesn't listen any more.");
- match self.from_main.recv_timeout(std::time::Duration::from_secs_f32(self.config.refresh_rate)) {
+ match self.from_main.recv_timeout(timeout) {
Ok(MessagesFromMain::Refresh) | Err(RecvTimeoutError::Timeout) => {},
Ok(MessagesFromMain::Quit) | Err(RecvTimeoutError::Disconnected) => { break; },
}
}
}
- fn synchronized_loop(&self, second_fraction : u32) {
- //TODO: implement...
- self.simple_loop();
+
+ fn synchronized_loop(&self, full_seconds : u64, second_fraction : u32) {
+ let interval_duration = std::time::Duration::from_secs(full_seconds) / (second_fraction);
+ loop {
+ self.to_main.send_update(Ok(self.print_current_time_with_format())).expect("Clock plugin tried to send the current time to the main program, but the main program doesn't listen any more.");
+ let now = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).expect("System time before beginning of UNIX epoch?!?");
+ let target_time = now + interval_duration;
+
+ let target_millis = target_time.as_millis();
+ let target_millis_times_fraction = target_millis * (second_fraction as u128);
+ let now_millis = now.as_millis();
+ let target_rounded_millis_times_fraction = ((target_millis_times_fraction + 500)/1000)*1000;
+ let target_rounded_millis = target_rounded_millis_times_fraction / (second_fraction as u128);
+ assert!(target_rounded_millis >= now_millis);
+ let timeout = std::time::Duration::from_millis((target_rounded_millis - now_millis) as u64);
+ match self.from_main.recv_timeout(timeout) {
+ Ok(MessagesFromMain::Refresh) | Err(RecvTimeoutError::Timeout) => {},
+ Ok(MessagesFromMain::Quit) | Err(RecvTimeoutError::Disconnected) => { break; },
+ }
+ }
}
}
@@ -34,20 +51,24 @@ impl<'c> SwayStatusModuleRunnable for ClockRunnable<'c> {
fn run(&self) {
//there are two modes of operation for this module.
//Which one is used depends entirely on the interval
- //If the interval or its inverse is a full multiple of
- //a second, we use the "synchronized" variant, which
+ //If the interval is a full multiple of a second,
+ //we use the "synchronized" variant, which
//aims at ticking approximately at the full second.
+ //
+ //Similarly if the interval can be written as 1/x seconds.
+ //
//Otherwise we just loop.
- let frac_part = self.config.refresh_rate.fract();
- let inverse_frac_part = self.config.refresh_rate.recip().fract();
- if frac_part.abs() > 1e-3 && inverse_frac_part.abs() > 1e-3 {
- self.simple_loop();
+ let abs_frac_part = (self.config.refresh_rate.round() - self.config.refresh_rate).abs();
+ let inverse = self.config.refresh_rate.recip();
+ let abs_inverse_frac_part = (inverse.round() - inverse).abs();
+ if self.config.refresh_rate < 1e-3_f32 || ((abs_frac_part >= 1e-3_f32) && abs_inverse_frac_part >= 1e-3_f32) {
+ self.simple_loop(std::time::Duration::from_secs_f32(self.config.refresh_rate.abs()));
}
- else if frac_part.abs() <= 1e-3 {
- self.synchronized_loop(1);
+ else if abs_frac_part <= 1e-3 {
+ self.synchronized_loop(self.config.refresh_rate.round() as u64, 1);
}
else {
- self.synchronized_loop(self.config.refresh_rate.recip().trunc().abs() as u32);
+ self.synchronized_loop(1, inverse.round() as u32);
}
}
}