From 68989ee0ca34e5f28e1a1bc22e4c091fb8ee6789 Mon Sep 17 00:00:00 2001 From: Marko19907 Date: Sun, 9 Jun 2024 15:26:46 +0200 Subject: [PATCH] Refactored time unit handling to use Rust's std::time::Duration --- src/controller.rs | 28 ++++++++++++++++----- src/delay_dialog.rs | 17 +++++++------ src/settings.rs | 61 +++++++++++++++------------------------------ src/view.rs | 14 +++++++---- 4 files changed, 60 insertions(+), 60 deletions(-) diff --git a/src/controller.rs b/src/controller.rs index de634d8..696864e 100644 --- a/src/controller.rs +++ b/src/controller.rs @@ -26,6 +26,22 @@ impl Delays { _ => Delays::Custom, } } + + /// Returns the delay in milliseconds + fn as_millis(&self) -> u64 { + match self { + Delays::ThirtySeconds => 30000, + Delays::OneMinute => 60000, + Delays::TwoMinutes => 120000, + Delays::FiveMinutes => 300000, + Delays::Custom => 0, + } + } + + /// Converts a delay to Rust's Duration + pub fn as_duration(&self) -> Duration { + Duration::from_millis(self.as_millis()) + } } pub enum Distances { @@ -84,29 +100,29 @@ impl Controller { pub fn run(controller: Arc>) { thread::Builder::new().name("mover_thread".to_string()).spawn(move || { - let interval = controller.lock().unwrap().get_interval() as u64; - sleep(Duration::from_millis(interval)); // Wait for the first interval, don't move windows immediately + let interval = controller.lock().unwrap().get_interval(); + sleep(interval); // Wait for the first interval, don't move windows immediately loop { let controller = controller.lock().unwrap(); let running = controller.is_running(); - let interval = controller.get_interval() as u64; + let interval = controller.get_interval(); drop(controller); if running { mover::run(); } - sleep(Duration::from_millis(interval)); + sleep(interval); } }).expect("Thread failed to start"); } - pub fn get_interval(&self) -> i32 { + pub fn get_interval(&self) -> Duration { return self.settings_manager.get_delay(); } - pub fn set_interval(&mut self, interval: i32) { + pub fn set_interval(&mut self, interval: Duration) { self.settings_manager.set_delay(interval); } diff --git a/src/delay_dialog.rs b/src/delay_dialog.rs index 33fc731..37b5c7d 100644 --- a/src/delay_dialog.rs +++ b/src/delay_dialog.rs @@ -1,10 +1,11 @@ use std::{thread, cell::RefCell}; +use std::time::Duration; use nwg::{ControlHandle, NativeUi, NumberSelectData}; use crate::settings::{LOWEST_DELAY, MAX_DELAY}; pub enum DelayDialogData { Cancel, - Value(i32), + Value(Duration), } #[derive(Default)] @@ -22,16 +23,16 @@ impl DelayDialog { /// Create the dialog UI on a new thread. The dialog result will be returned by the thread handle. /// To alert the main GUI that the dialog completed, this function takes a notice sender object. - pub(crate) fn popup(sender: nwg::NoticeSender, current_value: i32) -> thread::JoinHandle { + pub(crate) fn popup(sender: nwg::NoticeSender, current: Duration) -> thread::JoinHandle { return thread::spawn(move || { // Create the UI just like in the main function let app = DelayDialog::build_ui(Default::default()).expect("Failed to build UI"); let number_select_data = NumberSelectData::Int { - value: (current_value / 1000) as i64, - step: 1, // 1 second steps - max: MAX_DELAY as i64 / 1000, // 30 minutes - min: LOWEST_DELAY as i64 / 1000, // 1 second + value: current.as_secs() as i64, + step: 1, // 1 second steps + max: MAX_DELAY.as_secs() as i64, + min: LOWEST_DELAY.as_secs() as i64, }; app.number_select.set_data(number_select_data); @@ -49,8 +50,8 @@ impl DelayDialog { let mut data = self.data.borrow_mut(); if btn == &self.ok_button { let value = self.number_select.data(); - if let Ok(parsed_value) = value.formatted_value().parse::() { - *data = Some(DelayDialogData::Value(parsed_value.abs() * 1000)); + if let Ok(parsed_value) = value.formatted_value().parse::() { + *data = Some(DelayDialogData::Value(Duration::from_secs(parsed_value))); } else { // TODO: Handle the error, if any println!("Failed to parse value!"); diff --git a/src/settings.rs b/src/settings.rs index 556b647..2a6707f 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -1,6 +1,7 @@ use std::fs::{File, write}; use std::io::Read; use std::sync::{Arc, Mutex}; +use std::time::Duration; use serde::{Deserialize, Serialize}; use crate::controller::Delays; @@ -13,10 +14,10 @@ pub struct Settings { } /// Lowest delay allowed, in milliseconds (1 second) -pub const LOWEST_DELAY: i32 = 1000; +pub const LOWEST_DELAY: Duration = Duration::from_secs(1); /// Highest delay allowed, in milliseconds (30 minutes) -pub const MAX_DELAY: i32 = 1800000; +pub const MAX_DELAY: Duration = Duration::from_secs(30 * 60); /// Lowest max distance allowed, in pixels pub const LOWEST_MAX_DISTANCE: i32 = 1; @@ -40,24 +41,14 @@ impl Settings { self.running = running; } - /// Returns the delay in milliseconds - pub fn get_delay(&self) -> i32 { - return self.delay_milliseconds; + /// Returns the delay + pub fn get_delay(&self) -> Duration { + return Duration::from_millis(self.delay_milliseconds as u64); } /// Sets the delay, in milliseconds - pub fn set_delay(&mut self, delay: i32) { - self.delay_milliseconds = delay; - } - - /// Returns the delay in seconds - pub fn get_delay_seconds(&self) -> i32 { - return self.delay_milliseconds / 1000; - } - - /// Sets the delay, in seconds - pub fn set_delay_seconds(&mut self, delay: i32) { - self.delay_milliseconds = delay * 1000; + pub fn set_delay(&mut self, delay: Duration) { + self.delay_milliseconds = delay.as_millis() as i32; } pub fn get_max_distance(&self) -> (i32, i32) { @@ -111,16 +102,16 @@ impl SettingsManager { let mut errors: Vec = Vec::new(); // Validate the settings and update them if necessary since the user could have edited the settings file - if settings.delay_milliseconds < LOWEST_DELAY { - settings.delay_milliseconds = LOWEST_DELAY; + if settings.delay_milliseconds < LOWEST_DELAY.as_millis() as i32 { + settings.delay_milliseconds = LOWEST_DELAY.as_millis() as i32; errors.push( - format!("The delay was too low, it has been set to the lowest possible value of {} second.", LOWEST_DELAY / 1000) + format!("The delay was too low, it has been set to the lowest possible value of {} second.", LOWEST_DELAY.as_millis() as i32 / 1000) ); } - if settings.delay_milliseconds > MAX_DELAY { - settings.delay_milliseconds = MAX_DELAY; + if settings.delay_milliseconds > MAX_DELAY.as_millis() as i32 { + settings.delay_milliseconds = MAX_DELAY.as_millis() as i32; errors.push( - format!("The delay was too high, it has been set to the highest possible value of {} seconds.", MAX_DELAY / 1000) + format!("The delay was too high, it has been set to the highest possible value of {} seconds.", MAX_DELAY.as_millis() as i32 / 1000) ); } @@ -179,13 +170,13 @@ impl SettingsManager { pub fn is_running(&self) -> bool { let settings = self.settings.lock().unwrap(); - return settings.running; + return settings.get_running(); } /// Sets the running state, and saves the settings to the settings file pub fn set_running(&self, running: bool) { let mut settings = self.settings.lock().unwrap(); - settings.running = running; + settings.set_running(running); SettingsManager::save_settings(&*settings); } @@ -196,27 +187,15 @@ impl SettingsManager { SettingsManager::save_settings(&*settings); } - pub fn get_delay(&self) -> i32 { + pub fn get_delay(&self) -> Duration { let settings = self.settings.lock().unwrap(); - return settings.delay_milliseconds; + return settings.get_delay(); } /// Sets the delay, in milliseconds, and saves the settings to the settings file - pub fn set_delay(&self, delay: i32) { - let mut settings = self.settings.lock().unwrap(); - settings.delay_milliseconds = delay; - SettingsManager::save_settings(&*settings); - } - - pub fn get_delay_seconds(&self) -> i32 { - let settings = self.settings.lock().unwrap(); - return settings.get_delay_seconds(); - } - - /// Sets the delay, in seconds, and saves the settings to the settings file - pub fn set_delay_seconds(&self, delay: i32) { + pub fn set_delay(&self, duration: Duration) { let mut settings = self.settings.lock().unwrap(); - settings.set_delay_seconds(delay); + settings.set_delay(duration); SettingsManager::save_settings(&*settings); } diff --git a/src/view.rs b/src/view.rs index b809773..6e08aa6 100644 --- a/src/view.rs +++ b/src/view.rs @@ -1,5 +1,6 @@ use std::{thread, cell::RefCell}; use std::sync::{Arc, Mutex}; +use std::time::Duration; use crate::controller::{Controller, Delays, Distances}; use crate::delay_dialog::{DelayDialogData, DelayDialog}; use crate::distance_dialog::{DistanceDialog, DistanceDialogData}; @@ -64,10 +65,10 @@ impl SystemTray { fn do_delay(&self, delay: Delays) { match delay { - Delays::ThirtySeconds => self.controller.lock().unwrap().set_interval(Delays::ThirtySeconds as i32), - Delays::OneMinute => self.controller.lock().unwrap().set_interval(Delays::OneMinute as i32), - Delays::TwoMinutes => self.controller.lock().unwrap().set_interval(Delays::TwoMinutes as i32), - Delays::FiveMinutes => self.controller.lock().unwrap().set_interval(Delays::FiveMinutes as i32), + Delays::ThirtySeconds => self.controller.lock().unwrap().set_interval(Delays::ThirtySeconds.as_duration()), + Delays::OneMinute => self.controller.lock().unwrap().set_interval(Delays::OneMinute.as_duration()), + Delays::TwoMinutes => self.controller.lock().unwrap().set_interval(Delays::TwoMinutes.as_duration()), + Delays::FiveMinutes => self.controller.lock().unwrap().set_interval(Delays::FiveMinutes.as_duration()), Delays::Custom => { self.delay_custom(); return; // Don't update the menu or tooltip, will be done when the dialog closes in the callback @@ -121,6 +122,7 @@ impl SystemTray { .for_each(|x| x.set_checked(false)); let interval = self.controller.lock().unwrap().get_interval(); + let interval = interval.as_millis() as i32; match Delays::from_millis(interval) { Delays::ThirtySeconds => self.delay_30_menu.set_checked(true), Delays::OneMinute => self.delay_1_menu.set_checked(true), @@ -162,7 +164,9 @@ impl SystemTray { } /// Formats an interval in milliseconds into a human readable string - fn format_interval(&self, interval: i32) -> String { + fn format_interval(&self, duration: Duration) -> String { + let interval = duration.as_millis() as i32; + match Delays::from_millis(interval) { Delays::ThirtySeconds => return "30 seconds".to_string(), Delays::OneMinute => return "1 minute".to_string(),