diff --git a/powertools-rs/src/api/general.rs b/powertools-rs/src/api/general.rs new file mode 100644 index 0000000..0345620 --- /dev/null +++ b/powertools-rs/src/api/general.rs @@ -0,0 +1,73 @@ +use std::sync::{mpsc::Sender, Arc, Mutex}; +use usdpl_back::core::serdes::Primitive; + +use crate::settings::{General, Settings, OnSet}; +use crate::utility::{unwrap_lock, unwrap_maybe_fatal}; + +/// Generate set persistent web method +pub fn set_persistent( + settings: Arc>, + saver: Sender<()>, +) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType { + let saver = Mutex::new(saver); // Sender is not Sync; this is required for safety + move |params_in: super::ApiParameterType| { + if let Some(Primitive::Bool(new_val)) = params_in.get(0) { + let mut settings_lock = unwrap_lock(settings.lock(), "general"); + settings_lock.persistent = *new_val; + unwrap_maybe_fatal( + unwrap_lock(saver.lock(), "save channel").send(()), + "Failed to send on save channel", + ); + super::utility::map_empty_result( + settings_lock.on_set(), + settings_lock.persistent, + ) + } else { + vec!["set_persistent missing parameter".into()] + } + } +} + +/// Generate get persistent save mode web method +pub fn get_persistent( + settings: Arc>, +) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType { + move |_: super::ApiParameterType| { + let settings_lock = unwrap_lock(settings.lock(), "general"); + vec![settings_lock + .persistent.into()] + } +} + +/// Generate load app settings from file web method +pub fn load_settings( + settings: Settings, +) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType { + move |params_in: super::ApiParameterType| { + if let Some(Primitive::String(path)) = params_in.get(0) { + if let Some(Primitive::String(name)) = params_in.get(1) { + super::utility::map_result( + settings.load_file(path.into(), name.to_owned()) + ) + } else { + vec!["load_settings missing name parameter".into()] + } + //let mut general_lock = unwrap_lock(settings.general.lock(), "general"); + } else { + vec!["load_settings missing path parameter".into()] + } + } +} + +/// Generate get current settings name +pub fn get_name( + settings: Arc>, +) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType { + move |_: super::ApiParameterType| { + let settings_lock = unwrap_lock(settings.lock(), "general"); + vec![settings_lock + .name + .clone() + .into()] + } +} diff --git a/powertools-rs/src/api/mod.rs b/powertools-rs/src/api/mod.rs index ed8f332..75e2a6d 100644 --- a/powertools-rs/src/api/mod.rs +++ b/powertools-rs/src/api/mod.rs @@ -1,5 +1,6 @@ pub mod battery; pub mod cpu; +pub mod general; pub mod gpu; mod utility; diff --git a/powertools-rs/src/consts.rs b/powertools-rs/src/consts.rs new file mode 100644 index 0000000..ef119ba --- /dev/null +++ b/powertools-rs/src/consts.rs @@ -0,0 +1,6 @@ +pub const PORT: u16 = 44443; + +pub const PACKAGE_NAME: &'static str = env!("CARGO_PKG_NAME"); +pub const PACKAGE_VERSION: &'static str = env!("CARGO_PKG_VERSION"); + +pub const DEFAULT_SETTINGS_FILE: &str = "default_settings.json"; diff --git a/powertools-rs/src/main.rs b/powertools-rs/src/main.rs index 09e30be..c22ef6f 100644 --- a/powertools-rs/src/main.rs +++ b/powertools-rs/src/main.rs @@ -3,6 +3,8 @@ mod persist; mod settings; mod state; +mod consts; +use consts::*; mod resume_worker; mod save_worker; mod utility; @@ -12,13 +14,6 @@ use simplelog::{LevelFilter, WriteLogger}; use usdpl_back::core::serdes::Primitive; use usdpl_back::Instance; -const PORT: u16 = 44443; - -const PACKAGE_NAME: &'static str = env!("CARGO_PKG_NAME"); -const PACKAGE_VERSION: &'static str = env!("CARGO_PKG_VERSION"); - -const DEFAULT_SETTINGS_FILE: &str = "default_settings.json"; - fn main() -> Result<(), ()> { let log_filepath = format!("/tmp/{}.log", PACKAGE_NAME); WriteLogger::init( @@ -127,6 +122,23 @@ fn main() -> Result<(), ()> { "GPU_get_slow_memory", api::gpu::get_slow_memory(default_settings.gpu.clone()) ) + // general API functions + .register( + "GENERAL_set_persistent", + api::general::set_persistent(default_settings.general.clone(), save_sender.clone()) + ) + .register( + "GENERAL_get_persistent", + api::general::get_persistent(default_settings.general.clone()) + ) + .register( + "GENERAL_load_settings", + api::general::load_settings(default_settings.clone()) + ) + .register( + "GENERAL_get_name", + api::general::get_name(default_settings.general.clone()) + ) .run_blocking() } diff --git a/powertools-rs/src/settings/general.rs b/powertools-rs/src/settings/general.rs index b7c6442..df994fc 100644 --- a/powertools-rs/src/settings/general.rs +++ b/powertools-rs/src/settings/general.rs @@ -35,6 +35,19 @@ pub struct General { pub name: String, } +impl OnSet for General { + fn on_set(&mut self) -> Result<(), SettingError> { + // remove settings file when persistence is turned off, to prevent it from be loaded next time. + if !self.persistent && self.path.exists() { + std::fs::remove_file(&self.path).map_err(|e| SettingError { + msg: e.to_string(), + setting: SettingVariant::General, + })?; + } + Ok(()) + } +} + #[derive(Debug, Clone)] pub struct Settings { pub general: Arc>, @@ -115,6 +128,38 @@ impl Settings { battery: Arc::new(Mutex::new(Battery::system_default())), } } + + pub fn load_file(&self, json_path: PathBuf, name: String) -> Result { + let mut general_lock = unwrap_lock(self.general.lock(), "general"); + if json_path.exists() { + let settings_json = SettingsJson::open(&json_path).map_err(|e| SettingError { + msg: e.to_string(), + setting: SettingVariant::General, + })?; + let new_cpus = Self::convert_cpus(settings_json.cpus, settings_json.version); + let new_gpu = Gpu::from_json(settings_json.gpu, settings_json.version); + let new_battery = Battery::from_json(settings_json.battery, settings_json.version); + { + let mut cpu_lock = unwrap_lock(self.cpus.lock(), "cpu"); + *cpu_lock = new_cpus; // TODO does this overwrite the contents of the lock as expected? + } + { + let mut gpu_lock = unwrap_lock(self.gpu.lock(), "gpu"); + *gpu_lock = new_gpu; + } + { + let mut battery_lock = unwrap_lock(self.battery.lock(), "battery"); + *battery_lock = new_battery; + } + general_lock.persistent = true; + general_lock.name = settings_json.name; + } else { + general_lock.persistent = false; + general_lock.name = name; + } + general_lock.path = json_path; + Ok(general_lock.persistent) + } } impl OnResume for Settings { diff --git a/powertools-rs/src/settings/mod.rs b/powertools-rs/src/settings/mod.rs index 2a70494..9f327af 100644 --- a/powertools-rs/src/settings/mod.rs +++ b/powertools-rs/src/settings/mod.rs @@ -8,7 +8,7 @@ mod traits; pub use battery::Battery; pub use cpu::Cpu; -pub use general::{SettingVariant, Settings}; +pub use general::{SettingVariant, Settings, General}; pub use gpu::Gpu; pub use min_max::MinMax; diff --git a/src/backend.ts b/src/backend.ts index cba1e11..d78bfb1 100644 --- a/src/backend.ts +++ b/src/backend.ts @@ -105,9 +105,27 @@ export async function unsetGpuClockLimits(): Promise { } export async function setGpuSlowMemory(val: boolean): Promise { - return (await call_backend("GPU_set_slow_memory", [min, max]))[0]; + return (await call_backend("GPU_set_slow_memory", [val]))[0]; } export async function getGpuSlowMemory(): Promise { return (await call_backend("GPU_get_slow_memory", []))[0]; } + +// general + +export async function setGeneralPersistent(val: boolean): Promise { + return (await call_backend("GENERAL_set_persistent", [val]))[0]; +} + +export async function getGeneralPersistent(): Promise { + return (await call_backend("GENERAL_get_persistent", []))[0]; +} + +export async function loadGeneralSettings(path: string, name: string): Promise { + return (await call_backend("GENERAL_load_settings", [path, name]))[0]; +} + +export async function getGeneralPersistent(): Promise { + return (await call_backend("GENERAL_get_name", []))[0]; +}