forked from NG-SD-Plugins/PowerTools
Refactor API processing to apply settings from single thread and queue API calls instead of locking
This commit is contained in:
parent
357a7cfe37
commit
1610f18278
17 changed files with 822 additions and 452 deletions
33
backend/Cargo.lock
generated
33
backend/Cargo.lock
generated
|
@ -38,6 +38,28 @@ dependencies = [
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-recursion"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2cda8f4bcc10624c4e85bc66b3f452cca98cfa5ca002dc83a16aad2367641bea"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-trait"
|
||||||
|
version = "0.1.58"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -567,12 +589,14 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "powertools-rs"
|
name = "powertools-rs"
|
||||||
version = "1.0.5"
|
version = "1.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
"log",
|
"log",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"simplelog",
|
"simplelog",
|
||||||
|
"tokio",
|
||||||
"usdpl-back",
|
"usdpl-back",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1053,12 +1077,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "usdpl-back"
|
name = "usdpl-back"
|
||||||
version = "0.6.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cbbc0781e83ba990f8239142e33173a2d2548701775f3db66702d1af4fd0319a"
|
checksum = "4ca96dac4ee471e9534940f99cb36f5212cbfaf4e7779eb3ba970d3c511d9583"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"async-recursion",
|
||||||
|
"async-trait",
|
||||||
"bytes",
|
"bytes",
|
||||||
"hex",
|
"hex",
|
||||||
|
"log",
|
||||||
"obfstr",
|
"obfstr",
|
||||||
"tokio",
|
"tokio",
|
||||||
"usdpl-core",
|
"usdpl-core",
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
[package]
|
[package]
|
||||||
name = "powertools-rs"
|
name = "powertools-rs"
|
||||||
version = "1.0.5"
|
version = "1.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
usdpl-back = { version = "0.6.0", features = ["blocking"]}
|
usdpl-back = { version = "0.7.0", features = ["blocking"]}
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
|
||||||
|
# async
|
||||||
|
tokio = { version = "*", features = ["time"] }
|
||||||
|
async-trait = { version = "0.1" }
|
||||||
|
|
||||||
# logging
|
# logging
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
simplelog = "0.12"
|
simplelog = "0.12"
|
||||||
|
|
65
backend/src/api/async_utils.rs
Normal file
65
backend/src/api/async_utils.rs
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
//use usdpl_back::core::serdes::Primitive;
|
||||||
|
use usdpl_back::AsyncCallable;
|
||||||
|
|
||||||
|
/*pub struct AsyncIsh<T: Send,
|
||||||
|
TS: (Fn(super::ApiParameterType) -> Result<T, String>) + Send + Sync,
|
||||||
|
SG: (Fn(T) -> T) + Send + Sync + 'static,
|
||||||
|
TG: (Fn(T) -> super::ApiParameterType) + Send + Sync> {
|
||||||
|
pub trans_setter: TS, // assumed to be pretty fast
|
||||||
|
pub set_get: SG, // probably has locks (i.e. slow)
|
||||||
|
pub trans_getter: TG, // assumed to be pretty fast
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl <T: Send,
|
||||||
|
TS: (Fn(super::ApiParameterType) -> Result<T, String>) + Send + Sync,
|
||||||
|
SG: (Fn(T) -> T) + Send + Sync + 'static,
|
||||||
|
TG: (Fn(T) -> super::ApiParameterType) + Send + Sync>
|
||||||
|
AsyncCallable for AsyncIsh<T, TS, SG, TG> {
|
||||||
|
async fn call(&self, params: super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
let t_to_set = match (self.trans_setter)(params) {
|
||||||
|
Ok(t) => t,
|
||||||
|
Err(e) => return vec![e.into()]
|
||||||
|
};
|
||||||
|
let t_got = match tokio::task::spawn_blocking(|| (self.set_get)(t_to_set)).await {
|
||||||
|
Ok(t) => t,
|
||||||
|
Err(e) => return vec![e.to_string().into()],
|
||||||
|
};
|
||||||
|
(self.trans_getter)(t_got)
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
pub struct AsyncIshGetter<T: Send + 'static,
|
||||||
|
Gen: (Fn() -> G) + Send + Sync,
|
||||||
|
G: (Fn() -> T) + Send + Sync + 'static,
|
||||||
|
TG: (Fn(T) -> super::ApiParameterType) + Send + Sync> {
|
||||||
|
pub set_get: Gen, // probably has locks (i.e. slow)
|
||||||
|
pub trans_getter: TG, // assumed to be pretty fast
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl <T: Send + 'static,
|
||||||
|
Gen: (Fn() -> G) + Send + Sync,
|
||||||
|
G: (Fn() -> T) + Send + Sync + 'static,
|
||||||
|
TG: (Fn(T) -> super::ApiParameterType) + Send + Sync>
|
||||||
|
AsyncCallable for AsyncIshGetter<T, Gen, G, TG> {
|
||||||
|
async fn call(&self, _params: super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
let getter = (self.set_get)();
|
||||||
|
let t_got = match tokio::task::spawn_blocking(move || getter()).await {
|
||||||
|
Ok(t) => t,
|
||||||
|
Err(e) => return vec![e.to_string().into()],
|
||||||
|
};
|
||||||
|
(self.trans_getter)(t_got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Blocking<F: (Fn(super::ApiParameterType) -> super::ApiParameterType) + Send + Sync> {
|
||||||
|
pub func: F,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl <F: (Fn(super::ApiParameterType) -> super::ApiParameterType) + Send + Sync> AsyncCallable for Blocking<F> {
|
||||||
|
async fn call(&self, params: super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
(self.func)(params)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
use std::sync::{mpsc::Sender, Arc, Mutex};
|
use std::sync::mpsc::{Sender, self};
|
||||||
|
use std::sync::Mutex;
|
||||||
use usdpl_back::core::serdes::Primitive;
|
use usdpl_back::core::serdes::Primitive;
|
||||||
|
|
||||||
use crate::settings::{Battery, OnSet};
|
use super::handler::{ApiMessage, BatteryMessage};
|
||||||
use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
|
|
||||||
|
|
||||||
/// Current current (ha!) web method
|
/// Current current (ha!) web method
|
||||||
pub fn current_now(_: super::ApiParameterType) -> super::ApiParameterType {
|
pub fn current_now(_: super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
@ -26,22 +26,18 @@ pub fn charge_design(_: super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
|
||||||
/// Generate set battery charge rate web method
|
/// Generate set battery charge rate web method
|
||||||
pub fn set_charge_rate(
|
pub fn set_charge_rate(
|
||||||
settings: Arc<Mutex<Battery>>,
|
sender: Sender<ApiMessage>,
|
||||||
saver: Sender<()>,
|
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let saver = Mutex::new(saver); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move |rate: f64|
|
||||||
|
sender.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Battery(BatteryMessage::SetChargeRate(Some(rate as u64))))
|
||||||
|
.expect("set_charge_rate send failed");
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(Primitive::F64(new_val)) = params_in.get(0) {
|
if let Some(&Primitive::F64(new_val)) = params_in.get(0) {
|
||||||
let mut settings_lock = unwrap_lock(settings.lock(), "battery");
|
setter(new_val);
|
||||||
settings_lock.charge_rate = Some(*new_val as _);
|
vec![(new_val).into()]
|
||||||
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.charge_rate.unwrap(),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
vec!["set_charge_rate missing parameter".into()]
|
vec!["set_charge_rate missing parameter".into()]
|
||||||
}
|
}
|
||||||
|
@ -50,30 +46,28 @@ pub fn set_charge_rate(
|
||||||
|
|
||||||
/// Generate get battery charge rate web method
|
/// Generate get battery charge rate web method
|
||||||
pub fn get_charge_rate(
|
pub fn get_charge_rate(
|
||||||
settings: Arc<Mutex<Battery>>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let getter = move || {
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
let callback = move |rate: Option<u64>| tx.send(rate).expect("get_charge_rate callback send failed");
|
||||||
|
sender.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::GetChargeRate(Box::new(callback)))).expect("get_charge_rate send failed");
|
||||||
|
rx.recv().expect("get_charge_rate callback recv failed")
|
||||||
|
};
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| {
|
||||||
let settings_lock = unwrap_lock(settings.lock(), "battery");
|
vec![getter().map(|x| x.into()).unwrap_or(Primitive::Empty)]
|
||||||
vec![settings_lock
|
|
||||||
.charge_rate
|
|
||||||
.map(|x| x.into())
|
|
||||||
.unwrap_or(Primitive::Empty)]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate unset battery charge rate web method
|
/// Generate unset battery charge rate web method
|
||||||
pub fn unset_charge_rate(
|
pub fn unset_charge_rate(
|
||||||
settings: Arc<Mutex<Battery>>,
|
sender: Sender<ApiMessage>,
|
||||||
saver: Sender<()>,
|
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let saver = Mutex::new(saver); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
move |_: super::ApiParameterType| {
|
let setter = move || sender.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::SetChargeRate(None))).expect("unset_charge_rate send failed");
|
||||||
let mut settings_lock = unwrap_lock(settings.lock(), "battery");
|
move |_params_in: super::ApiParameterType| {
|
||||||
settings_lock.charge_rate = None;
|
setter();
|
||||||
unwrap_maybe_fatal(
|
vec![true.into()]
|
||||||
unwrap_lock(saver.lock(), "save channel").send(()),
|
|
||||||
"Failed to send on save channel",
|
|
||||||
);
|
|
||||||
super::utility::map_empty_result(settings_lock.on_set(), true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
use std::sync::{mpsc::Sender, Arc, Mutex};
|
use std::sync::mpsc::{Sender, self};
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
use usdpl_back::core::serdes::Primitive;
|
use usdpl_back::core::serdes::Primitive;
|
||||||
|
use usdpl_back::AsyncCallable;
|
||||||
|
|
||||||
use crate::settings::{Cpu, OnSet, SettingError, SettingVariant, MinMax};
|
use crate::settings::{Cpu, SettingError, SettingVariant, MinMax};
|
||||||
use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
|
//use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
|
||||||
|
use super::handler::{ApiMessage, CpuMessage};
|
||||||
|
|
||||||
/// Available CPUs web method
|
/// Available CPUs web method
|
||||||
pub fn max_cpus(_: super::ApiParameterType) -> super::ApiParameterType {
|
pub fn max_cpus(_: super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
@ -20,29 +23,21 @@ pub fn max_cpus(_: super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
|
||||||
/// Generate set CPU online web method
|
/// Generate set CPU online web method
|
||||||
pub fn set_cpu_online(
|
pub fn set_cpu_online(
|
||||||
settings: Arc<Mutex<Vec<Cpu>>>,
|
sender: Sender<ApiMessage>,
|
||||||
saver: Sender<()>,
|
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let saver = Mutex::new(saver); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move |index: usize, value: bool|
|
||||||
|
sender.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Cpu(CpuMessage::SetCpuOnline(index, value))).expect("set_cpu_online send failed");
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(Primitive::F64(index)) = params_in.get(0) {
|
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
||||||
let mut settings_lock = unwrap_lock(settings.lock(), "cpu");
|
//let mut settings_lock = unwrap_lock(settings.lock(), "cpu");
|
||||||
if let Some(cpu) = settings_lock.get_mut(*index as usize) {
|
if let Some(&Primitive::Bool(online)) = params_in.get(1) {
|
||||||
if let Some(Primitive::Bool(online)) = params_in.get(1) {
|
setter(index as usize, online);
|
||||||
cpu.online = *online;
|
vec![online.into()]
|
||||||
unwrap_maybe_fatal(
|
|
||||||
unwrap_lock(saver.lock(), "save channel").send(()),
|
|
||||||
"Failed to send on save channel",
|
|
||||||
);
|
|
||||||
super::utility::map_empty_result(
|
|
||||||
cpu.on_set(),
|
|
||||||
cpu.online,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
vec!["set_cpu_online missing parameter 1".into()]
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
vec!["set_cpu_online cpu index out of bounds".into()]
|
vec!["set_cpu_online missing parameter 1".into()]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vec!["set_cpu_online missing parameter 0".into()]
|
vec!["set_cpu_online missing parameter 0".into()]
|
||||||
|
@ -51,81 +46,94 @@ pub fn set_cpu_online(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_cpus_online(
|
pub fn set_cpus_online(
|
||||||
settings: Arc<Mutex<Vec<Cpu>>>,
|
sender: Sender<ApiMessage>,
|
||||||
saver: Sender<()>,
|
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let saver = Mutex::new(saver); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move |values: Vec<bool>|
|
||||||
|
sender.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Cpu(CpuMessage::SetCpusOnline(values))).expect("set_cpus_online send failed");
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
let mut result = Vec::with_capacity(params_in.len());
|
let mut result = Vec::with_capacity(params_in.len());
|
||||||
let mut settings_lock = unwrap_lock(settings.lock(), "cpu");
|
let mut values = Vec::with_capacity(params_in.len());
|
||||||
for i in 0..params_in.len() {
|
for i in 0..params_in.len() {
|
||||||
if let Primitive::Bool(online) = params_in[i] {
|
if let Primitive::Bool(online) = params_in[i] {
|
||||||
if let Some(cpu) = settings_lock.get_mut(i) {
|
values.push(online);
|
||||||
cpu.online = online;
|
result.push(online.into());
|
||||||
match cpu.on_set() {
|
|
||||||
Ok(_) => result.push(cpu.online.into()),
|
|
||||||
Err(e) => result.push(e.msg.into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
values.push(true);
|
||||||
result.push(format!("Invalid parameter {}", i).into())
|
result.push(format!("Invalid parameter {}", i).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unwrap_maybe_fatal(
|
setter(values);
|
||||||
unwrap_lock(saver.lock(), "save channel").send(()),
|
|
||||||
"Failed to send on save channel",
|
|
||||||
);
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cpus_online(
|
/*pub fn get_cpus_online(
|
||||||
settings: Arc<Mutex<Vec<Cpu>>>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let getter = move || {
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
let callback = move |values: Vec<bool>| tx.send(values).expect("get_cpus_online callback send failed");
|
||||||
|
sender.lock().unwrap().send(ApiMessage::Cpu(CpuMessage::GetCpusOnline(Box::new(callback)))).expect("get_cpus_online send failed");
|
||||||
|
rx.recv().expect("get_cpus_online callback recv failed")
|
||||||
|
};
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| {
|
||||||
let settings_lock = unwrap_lock(settings.lock(), "cpu");
|
let result = getter();
|
||||||
let mut output = Vec::with_capacity(settings_lock.len());
|
let mut output = Vec::with_capacity(result.len());
|
||||||
for cpu in settings_lock.as_slice() {
|
for &status in result.as_slice() {
|
||||||
output.push(cpu.online.into());
|
output.push(status.into());
|
||||||
}
|
}
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
pub fn get_cpus_online(
|
||||||
|
sender: Sender<ApiMessage>,
|
||||||
|
) -> impl AsyncCallable {
|
||||||
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
|
let getter = move || {
|
||||||
|
let sender2 = sender.clone();
|
||||||
|
move || {
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
let callback = move |values: Vec<bool>| tx.send(values).expect("get_cpus_online callback send failed");
|
||||||
|
sender2.lock().unwrap().send(ApiMessage::Cpu(CpuMessage::GetCpusOnline(Box::new(callback)))).expect("get_cpus_online send failed");
|
||||||
|
rx.recv().expect("get_cpus_online callback recv failed")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
super::async_utils::AsyncIshGetter {
|
||||||
|
set_get: getter,
|
||||||
|
trans_getter: |result| {
|
||||||
|
let mut output = Vec::with_capacity(result.len());
|
||||||
|
for &status in result.as_slice() {
|
||||||
|
output.push(status.into());
|
||||||
|
}
|
||||||
|
output
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_clock_limits(
|
pub fn set_clock_limits(
|
||||||
settings: Arc<Mutex<Vec<Cpu>>>,
|
sender: Sender<ApiMessage>,
|
||||||
saver: Sender<()>,
|
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let saver = Mutex::new(saver); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move |index: usize, value: MinMax<u64>|
|
||||||
|
sender.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Cpu(CpuMessage::SetClockLimits(index, Some(value)))).expect("set_clock_limits send failed");
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(Primitive::F64(index)) = params_in.get(0) {
|
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
||||||
let mut settings_lock = unwrap_lock(settings.lock(), "cpu");
|
if let Some(&Primitive::F64(min)) = params_in.get(1) {
|
||||||
if let Some(cpu) = settings_lock.get_mut(*index as usize) {
|
if let Some(&Primitive::F64(max)) = params_in.get(2) {
|
||||||
if let Some(Primitive::F64(min)) = params_in.get(1) {
|
setter(index as usize, MinMax {min: min as u64, max: max as u64});
|
||||||
if let Some(Primitive::F64(max)) = params_in.get(2) {
|
vec![min.into(), max.into()]
|
||||||
cpu.clock_limits = Some(MinMax {
|
|
||||||
min: *min as _,
|
|
||||||
max: *max as _,
|
|
||||||
});
|
|
||||||
unwrap_maybe_fatal(
|
|
||||||
unwrap_lock(saver.lock(), "save channel").send(()),
|
|
||||||
"Failed to send on save channel",
|
|
||||||
);
|
|
||||||
match cpu.on_set() {
|
|
||||||
Ok(_) => vec![
|
|
||||||
cpu.clock_limits.as_ref().unwrap().min.into(),
|
|
||||||
cpu.clock_limits.as_ref().unwrap().max.into(),
|
|
||||||
],
|
|
||||||
Err(e) => vec![e.msg.into()]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
vec!["set_clock_limits missing parameter 2".into()]
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
vec!["set_clock_limits missing parameter 1".into()]
|
vec!["set_clock_limits missing parameter 2".into()]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vec!["set_clock_limits cpu index out of bounds".into()]
|
vec!["set_clock_limits missing parameter 1".into()]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vec!["set_clock_limits missing parameter 0".into()]
|
vec!["set_clock_limits missing parameter 0".into()]
|
||||||
|
@ -134,19 +142,21 @@ pub fn set_clock_limits(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_clock_limits(
|
pub fn get_clock_limits(
|
||||||
settings: Arc<Mutex<Vec<Cpu>>>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let getter = move |index: usize| {
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
let callback = move |values: Option<MinMax<u64>>| tx.send(values).expect("get_clock_limits callback send failed");
|
||||||
|
sender.lock().unwrap().send(ApiMessage::Cpu(CpuMessage::GetClockLimits(index, Box::new(callback)))).expect("get_clock_limits send failed");
|
||||||
|
rx.recv().expect("get_clock_limits callback recv failed")
|
||||||
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(Primitive::F64(index)) = params_in.get(0) {
|
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
||||||
let mut settings_lock = unwrap_lock(settings.lock(), "cpu");
|
if let Some(min_max) = getter(index as usize) {
|
||||||
if let Some(cpu) = settings_lock.get_mut(*index as usize) {
|
vec![min_max.min.into(), min_max.max.into()]
|
||||||
if let Some(min_max) = &cpu.clock_limits {
|
|
||||||
vec![min_max.min.into(), min_max.max.into()]
|
|
||||||
} else {
|
|
||||||
vec![Primitive::Empty, Primitive::Empty]
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
vec!["get_clock_limits cpu index out of bounds".into()]
|
vec![Primitive::Empty, Primitive::Empty]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vec!["get_clock_limits missing parameter 0".into()]
|
vec!["get_clock_limits missing parameter 0".into()]
|
||||||
|
@ -155,23 +165,17 @@ pub fn get_clock_limits(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unset_clock_limits(
|
pub fn unset_clock_limits(
|
||||||
settings: Arc<Mutex<Vec<Cpu>>>,
|
sender: Sender<ApiMessage>,
|
||||||
saver: Sender<()>,
|
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let saver = Mutex::new(saver); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move |index: usize|
|
||||||
|
sender.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Cpu(CpuMessage::SetClockLimits(index, None))).expect("unset_clock_limits send failed");
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(Primitive::F64(index)) = params_in.get(0) {
|
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
||||||
let mut settings_lock = unwrap_lock(settings.lock(), "cpu");
|
setter(index as usize);
|
||||||
if let Some(cpu) = settings_lock.get_mut(*index as usize) {
|
vec![true.into()]
|
||||||
cpu.clock_limits = None;
|
|
||||||
unwrap_maybe_fatal(
|
|
||||||
unwrap_lock(saver.lock(), "save channel").send(()),
|
|
||||||
"Failed to send on save channel",
|
|
||||||
);
|
|
||||||
super::utility::map_empty_result(cpu.on_set(), true)
|
|
||||||
} else {
|
|
||||||
vec!["get_clock_limits cpu index out of bounds".into()]
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
vec!["get_clock_limits missing parameter 0".into()]
|
vec!["get_clock_limits missing parameter 0".into()]
|
||||||
}
|
}
|
||||||
|
@ -179,29 +183,20 @@ pub fn unset_clock_limits(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_cpu_governor(
|
pub fn set_cpu_governor(
|
||||||
settings: Arc<Mutex<Vec<Cpu>>>,
|
sender: Sender<ApiMessage>,
|
||||||
saver: Sender<()>,
|
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let saver = Mutex::new(saver); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move |index: usize, governor: String|
|
||||||
|
sender.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Cpu(CpuMessage::SetCpuGovernor(index, governor))).expect("set_cpu_governor send failed");
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(Primitive::F64(index)) = params_in.get(0) {
|
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
||||||
let mut settings_lock = unwrap_lock(settings.lock(), "cpu");
|
if let Some(Primitive::String(governor)) = params_in.get(1) {
|
||||||
if let Some(cpu) = settings_lock.get_mut(*index as usize) {
|
setter(index as usize, governor.to_owned());
|
||||||
if let Some(Primitive::String(governor)) = params_in.get(1) {
|
vec![(governor as &str).into()]
|
||||||
cpu.governor = governor.to_owned();
|
|
||||||
unwrap_maybe_fatal(
|
|
||||||
unwrap_lock(saver.lock(), "save channel").send(()),
|
|
||||||
"Failed to send on save channel",
|
|
||||||
);
|
|
||||||
super::utility::map_empty_result(
|
|
||||||
cpu.on_set(),
|
|
||||||
&cpu.governor as &str,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
vec!["set_cpu_governor missing parameter 1".into()]
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
vec!["set_cpu_governor cpu index out of bounds".into()]
|
vec!["set_cpu_governor missing parameter 1".into()]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vec!["set_cpu_governor missing parameter 0".into()]
|
vec!["set_cpu_governor missing parameter 0".into()]
|
||||||
|
@ -209,14 +204,46 @@ pub fn set_cpu_governor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cpu_governors(
|
pub fn set_cpus_governors(
|
||||||
settings: Arc<Mutex<Vec<Cpu>>>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move |governors: Vec<String>|
|
||||||
|
sender.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Cpu(CpuMessage::SetCpusGovernor(governors))).expect("set_cpus_governor send failed");
|
||||||
|
move |params_in: super::ApiParameterType| {
|
||||||
|
let mut result = Vec::with_capacity(params_in.len());
|
||||||
|
let mut values = Vec::with_capacity(params_in.len());
|
||||||
|
for i in 0..params_in.len() {
|
||||||
|
if let Primitive::String(gov) = ¶ms_in[i] {
|
||||||
|
values.push(gov.to_owned());
|
||||||
|
result.push((gov as &str).into());
|
||||||
|
} else {
|
||||||
|
//values.push(true);
|
||||||
|
result.push(format!("Invalid parameter {}", i).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setter(values);
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_cpu_governors(
|
||||||
|
sender: Sender<ApiMessage>,
|
||||||
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let getter = move || {
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
let callback = move |values: Vec<String>| tx.send(values).expect("get_cpu_governors callback send failed");
|
||||||
|
sender.lock().unwrap().send(ApiMessage::Cpu(CpuMessage::GetCpusGovernor(Box::new(callback)))).expect("get_cpu_governors send failed");
|
||||||
|
rx.recv().expect("get_cpu_governors callback recv failed")
|
||||||
|
};
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| {
|
||||||
let settings_lock = unwrap_lock(settings.lock(), "cpu");
|
let result = getter();
|
||||||
let mut output = Vec::with_capacity(settings_lock.len());
|
let mut output = Vec::with_capacity(result.len());
|
||||||
for cpu in settings_lock.as_slice() {
|
for cpu in result.as_slice() {
|
||||||
output.push(cpu.governor.clone().into());
|
output.push(cpu.clone().into());
|
||||||
}
|
}
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,25 @@
|
||||||
use std::sync::{mpsc::Sender, Arc, Mutex};
|
use std::sync::mpsc::{Sender, self};
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
use usdpl_back::core::serdes::Primitive;
|
use usdpl_back::core::serdes::Primitive;
|
||||||
|
use usdpl_back::AsyncCallable;
|
||||||
|
|
||||||
use crate::settings::{General, Settings, OnSet};
|
//use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
|
||||||
use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
|
use super::handler::{ApiMessage, GeneralMessage};
|
||||||
|
|
||||||
/// Generate set persistent web method
|
/// Generate set persistent web method
|
||||||
pub fn set_persistent(
|
pub fn set_persistent(
|
||||||
settings: Arc<Mutex<General>>,
|
sender: Sender<ApiMessage>,
|
||||||
saver: Sender<()>,
|
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let saver = Mutex::new(saver); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move |pers: bool|
|
||||||
|
sender.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::General(GeneralMessage::SetPersistent(pers))).expect("set_persistent send failed");
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(Primitive::Bool(new_val)) = params_in.get(0) {
|
if let Some(&Primitive::Bool(new_val)) = params_in.get(0) {
|
||||||
let mut settings_lock = unwrap_lock(settings.lock(), "general");
|
setter(new_val);
|
||||||
settings_lock.persistent = *new_val;
|
//log::debug!("Persistent is now {}", settings_lock.persistent);
|
||||||
unwrap_maybe_fatal(
|
vec![new_val.into()]
|
||||||
unwrap_lock(saver.lock(), "save channel").send(()),
|
|
||||||
"Failed to send on save channel",
|
|
||||||
);
|
|
||||||
let result = super::utility::map_empty_result(
|
|
||||||
settings_lock.on_set(),
|
|
||||||
settings_lock.persistent,
|
|
||||||
);
|
|
||||||
log::debug!("Persistent is now {}", settings_lock.persistent);
|
|
||||||
result
|
|
||||||
} else {
|
} else {
|
||||||
vec!["set_persistent missing parameter".into()]
|
vec!["set_persistent missing parameter".into()]
|
||||||
}
|
}
|
||||||
|
@ -32,30 +28,34 @@ pub fn set_persistent(
|
||||||
|
|
||||||
/// Generate get persistent save mode web method
|
/// Generate get persistent save mode web method
|
||||||
pub fn get_persistent(
|
pub fn get_persistent(
|
||||||
settings: Arc<Mutex<General>>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let getter = move || {
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
let callback = move |value: bool| tx.send(value).expect("get_persistent callback send failed");
|
||||||
|
sender.lock().unwrap().send(ApiMessage::General(GeneralMessage::GetPersistent(Box::new(callback)))).expect("get_persistent send failed");
|
||||||
|
rx.recv().expect("get_persistent callback recv failed")
|
||||||
|
};
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| {
|
||||||
let settings_lock = unwrap_lock(settings.lock(), "general");
|
vec![getter().into()]
|
||||||
vec![settings_lock
|
|
||||||
.persistent.into()]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate load app settings from file web method
|
/// Generate load app settings from file web method
|
||||||
pub fn load_settings(
|
pub fn load_settings(
|
||||||
settings: Settings,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move |path: String, name: String|
|
||||||
|
sender.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::LoadSettings(path, name)).expect("load_settings send failed");
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(Primitive::String(path)) = params_in.get(0) {
|
if let Some(Primitive::String(path)) = params_in.get(0) {
|
||||||
if let Some(Primitive::String(name)) = params_in.get(1) {
|
if let Some(Primitive::String(name)) = params_in.get(1) {
|
||||||
match settings.load_file(path.into(), name.to_owned(), false) {
|
setter(path.to_owned(), name.to_owned());
|
||||||
Err(e) => vec![e.msg.into()],
|
vec![true.into()]
|
||||||
Ok(success) =>
|
|
||||||
super::utility::map_empty_result(
|
|
||||||
settings.clone().on_set(),
|
|
||||||
success
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
vec!["load_settings missing name parameter".into()]
|
vec!["load_settings missing name parameter".into()]
|
||||||
}
|
}
|
||||||
|
@ -68,10 +68,17 @@ pub fn load_settings(
|
||||||
|
|
||||||
/// Generate load default settings from file web method
|
/// Generate load default settings from file web method
|
||||||
pub fn load_default_settings(
|
pub fn load_default_settings(
|
||||||
settings: Settings,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move ||
|
||||||
|
sender.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::LoadMainSettings).expect("load_default_settings send failed");
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| {
|
||||||
match settings.load_file(
|
setter();
|
||||||
|
vec![true.into()]
|
||||||
|
/*match settings.load_file(
|
||||||
crate::consts::DEFAULT_SETTINGS_FILE.into(),
|
crate::consts::DEFAULT_SETTINGS_FILE.into(),
|
||||||
crate::consts::DEFAULT_SETTINGS_NAME.to_owned(),
|
crate::consts::DEFAULT_SETTINGS_NAME.to_owned(),
|
||||||
true
|
true
|
||||||
|
@ -81,32 +88,76 @@ pub fn load_default_settings(
|
||||||
settings.clone().on_set(),
|
settings.clone().on_set(),
|
||||||
success
|
success
|
||||||
)
|
)
|
||||||
}
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate load system default settings from file web method
|
||||||
|
pub fn load_system_settings(
|
||||||
|
sender: Sender<ApiMessage>,
|
||||||
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move ||
|
||||||
|
sender.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::LoadSystemSettings).expect("load_default_settings send failed");
|
||||||
|
move |_: super::ApiParameterType| {
|
||||||
|
setter();
|
||||||
|
vec![true.into()]
|
||||||
|
/*match settings.load_file(
|
||||||
|
crate::consts::DEFAULT_SETTINGS_FILE.into(),
|
||||||
|
crate::consts::DEFAULT_SETTINGS_NAME.to_owned(),
|
||||||
|
true
|
||||||
|
) {
|
||||||
|
Err(e) => vec![e.msg.into()],
|
||||||
|
Ok(success) => super::utility::map_empty_result(
|
||||||
|
settings.clone().on_set(),
|
||||||
|
success
|
||||||
|
)
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate get current settings name
|
/// Generate get current settings name
|
||||||
pub fn get_name(
|
pub fn get_name(
|
||||||
settings: Arc<Mutex<General>>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl AsyncCallable {
|
||||||
move |_: super::ApiParameterType| {
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let settings_lock = unwrap_lock(settings.lock(), "general");
|
let getter = move || {
|
||||||
vec![settings_lock
|
let sender2 = sender.clone();
|
||||||
.name
|
move || {
|
||||||
.clone()
|
let (tx, rx) = mpsc::channel();
|
||||||
.into()]
|
let callback = move |name: String| tx.send(name).expect("get_name callback send failed");
|
||||||
|
sender2.lock().unwrap().send(ApiMessage::General(GeneralMessage::GetCurrentProfileName(Box::new(callback)))).expect("get_name send failed");
|
||||||
|
rx.recv().expect("get_name callback recv failed")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
super::async_utils::AsyncIshGetter {
|
||||||
|
set_get: getter,
|
||||||
|
trans_getter: |result| {
|
||||||
|
vec![result.into()]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate wait for all locks to be available web method
|
/// Generate wait for all locks to be available web method
|
||||||
pub fn lock_unlock_all(
|
pub fn lock_unlock_all(
|
||||||
settings: Settings,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl AsyncCallable {
|
||||||
move |_: super::ApiParameterType| {
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let _lock = unwrap_lock(settings.general.lock(), "general");
|
let getter = move || {
|
||||||
let _lock = unwrap_lock(settings.cpus.lock(), "cpus");
|
let sender2 = sender.clone();
|
||||||
let _lock = unwrap_lock(settings.gpu.lock(), "gpu");
|
move || {
|
||||||
let _lock = unwrap_lock(settings.battery.lock(), "battery");
|
let (tx, rx) = mpsc::channel();
|
||||||
vec![true.into()]
|
let callback = move |x| tx.send(x).expect("lock_unlock_all callback send failed");
|
||||||
|
sender2.lock().unwrap().send(ApiMessage::WaitForEmptyQueue(Box::new(callback))).expect("lock_unlock_all send failed");
|
||||||
|
rx.recv().expect("lock_unlock_all callback recv failed")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
super::async_utils::AsyncIshGetter {
|
||||||
|
set_get: getter,
|
||||||
|
trans_getter: |_| {
|
||||||
|
vec![true.into()]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,25 @@
|
||||||
use std::sync::{mpsc::Sender, Arc, Mutex};
|
use std::sync::mpsc::{Sender, self};
|
||||||
|
use std::sync::{Mutex, Arc};
|
||||||
use usdpl_back::core::serdes::Primitive;
|
use usdpl_back::core::serdes::Primitive;
|
||||||
|
use usdpl_back::AsyncCallable;
|
||||||
|
|
||||||
use crate::settings::{Gpu, OnSet, MinMax};
|
use crate::settings::MinMax;
|
||||||
use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
|
//use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
|
||||||
|
use super::handler::{ApiMessage, GpuMessage};
|
||||||
|
|
||||||
pub fn set_ppt(
|
pub fn set_ppt(
|
||||||
settings: Arc<Mutex<Gpu>>,
|
sender: Sender<ApiMessage>,
|
||||||
saver: Sender<()>,
|
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let saver = Mutex::new(saver); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move |fast: u64, slow: u64|
|
||||||
|
sender.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Gpu(GpuMessage::SetPpt(Some(fast), Some(slow)))).expect("set_ppt send failed");
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(Primitive::F64(fast_ppt)) = params_in.get(0) {
|
if let Some(&Primitive::F64(fast_ppt)) = params_in.get(0) {
|
||||||
if let Some(Primitive::F64(slow_ppt)) = params_in.get(1) {
|
if let Some(&Primitive::F64(slow_ppt)) = params_in.get(1) {
|
||||||
let mut settings_lock = unwrap_lock(settings.lock(), "gpu");
|
setter(fast_ppt as u64, slow_ppt as u64);
|
||||||
settings_lock.fast_ppt = Some(*fast_ppt as u64);
|
vec![(fast_ppt as u64).into(), (slow_ppt as u64).into()]
|
||||||
settings_lock.slow_ppt = Some(*slow_ppt as u64);
|
|
||||||
unwrap_maybe_fatal(
|
|
||||||
unwrap_lock(saver.lock(), "save channel").send(()),
|
|
||||||
"Failed to send on save channel",
|
|
||||||
);
|
|
||||||
match settings_lock.on_set() {
|
|
||||||
Ok(_) => vec![
|
|
||||||
settings_lock.fast_ppt.unwrap().into(),
|
|
||||||
settings_lock.slow_ppt.unwrap().into()
|
|
||||||
],
|
|
||||||
Err(e) => vec![e.msg.into()],
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
vec!["set_ppt missing parameter 1".into()]
|
vec!["set_ppt missing parameter 1".into()]
|
||||||
}
|
}
|
||||||
|
@ -36,60 +30,59 @@ pub fn set_ppt(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ppt(
|
pub fn get_ppt(
|
||||||
settings: Arc<Mutex<Gpu>>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl AsyncCallable {
|
||||||
move |_: super::ApiParameterType| {
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let settings_lock = unwrap_lock(settings.lock(), "gpu");
|
let getter = move || {
|
||||||
let fast_ppt = settings_lock.fast_ppt.map(|x| x.into()).unwrap_or(Primitive::Empty);
|
let sender2 = sender.clone();
|
||||||
let slow_ppt = settings_lock.slow_ppt.map(|x| x.into()).unwrap_or(Primitive::Empty);
|
move || {
|
||||||
vec![fast_ppt, slow_ppt]
|
let (tx, rx) = mpsc::channel();
|
||||||
|
let callback = move |ppt: (Option<u64>, Option<u64>)| tx.send(ppt).expect("get_ppt callback send failed");
|
||||||
|
sender2.lock().unwrap().send(ApiMessage::Gpu(GpuMessage::GetPpt(Box::new(callback)))).expect("get_ppt send failed");
|
||||||
|
rx.recv().expect("get_ppt callback recv failed")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
super::async_utils::AsyncIshGetter {
|
||||||
|
set_get: getter,
|
||||||
|
trans_getter: |(fast, slow): (Option<u64>, Option<u64>)| {
|
||||||
|
vec![
|
||||||
|
fast.map(|x| x.into()).unwrap_or(Primitive::Empty),
|
||||||
|
slow.map(|x| x.into()).unwrap_or(Primitive::Empty),
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unset_ppt(
|
pub fn unset_ppt(
|
||||||
settings: Arc<Mutex<Gpu>>,
|
sender: Sender<ApiMessage>,
|
||||||
saver: Sender<()>,
|
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let saver = Mutex::new(saver); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move ||
|
||||||
|
sender.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Gpu(GpuMessage::SetPpt(None, None))).expect("set_ppt send failed");
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| {
|
||||||
let mut settings_lock = unwrap_lock(settings.lock(), "gpu");
|
setter();
|
||||||
settings_lock.fast_ppt = None;
|
vec![true.into()]
|
||||||
settings_lock.slow_ppt = None;
|
|
||||||
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(),
|
|
||||||
Primitive::Empty,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_clock_limits(
|
pub fn set_clock_limits(
|
||||||
settings: Arc<Mutex<Gpu>>,
|
sender: Sender<ApiMessage>,
|
||||||
saver: Sender<()>,
|
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let saver = Mutex::new(saver); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move |value: MinMax<u64>|
|
||||||
|
sender.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Gpu(GpuMessage::SetClockLimits(Some(value)))).expect("set_clock_limits send failed");
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(Primitive::F64(min)) = params_in.get(0) {
|
if let Some(&Primitive::F64(min)) = params_in.get(0) {
|
||||||
if let Some(Primitive::F64(max)) = params_in.get(1) {
|
if let Some(&Primitive::F64(max)) = params_in.get(1) {
|
||||||
let mut settings_lock = unwrap_lock(settings.lock(), "gpu");
|
setter(MinMax {
|
||||||
settings_lock.clock_limits = Some(MinMax {
|
min: min as _,
|
||||||
min: *min as _,
|
max: max as _,
|
||||||
max: *max as _,
|
|
||||||
});
|
});
|
||||||
unwrap_maybe_fatal(
|
vec![(min as u64).into(), (max as u64).into()]
|
||||||
unwrap_lock(saver.lock(), "save channel").send(()),
|
|
||||||
"Failed to send on save channel",
|
|
||||||
);
|
|
||||||
match settings_lock.on_set() {
|
|
||||||
Ok(_) => vec![
|
|
||||||
settings_lock.clock_limits.as_ref().unwrap().min.into(),
|
|
||||||
settings_lock.clock_limits.as_ref().unwrap().max.into(),
|
|
||||||
],
|
|
||||||
Err(e) => vec![e.msg.into()]
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
vec!["set_clock_limits missing parameter 1".into()]
|
vec!["set_clock_limits missing parameter 1".into()]
|
||||||
}
|
}
|
||||||
|
@ -100,51 +93,54 @@ pub fn set_clock_limits(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_clock_limits(
|
pub fn get_clock_limits(
|
||||||
settings: Arc<Mutex<Gpu>>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl AsyncCallable {
|
||||||
move |_: super::ApiParameterType| {
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let settings_lock = unwrap_lock(settings.lock(), "gpu");
|
let getter = move|| {
|
||||||
if let Some(min_max) = &settings_lock.clock_limits {
|
let sender2 = sender.clone();
|
||||||
vec![min_max.min.into(), min_max.max.into()]
|
move || {
|
||||||
} else {
|
let (tx, rx) = mpsc::channel();
|
||||||
vec![Primitive::Empty, Primitive::Empty]
|
let callback = move |clocks: Option<MinMax<u64>>| tx.send(clocks).expect("get_clock_limits callback send failed");
|
||||||
|
sender2.lock().unwrap().send(ApiMessage::Gpu(GpuMessage::GetClockLimits(Box::new(callback)))).expect("get_clock_limits send failed");
|
||||||
|
rx.recv().expect("get_clock_limits callback recv failed")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
super::async_utils::AsyncIshGetter {
|
||||||
|
set_get: getter,
|
||||||
|
trans_getter: |clocks: Option<MinMax<u64>>| {
|
||||||
|
clocks.map(|x| vec![
|
||||||
|
x.min.into(), x.max.into()
|
||||||
|
]).unwrap_or_else(|| vec![Primitive::Empty, Primitive::Empty])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unset_clock_limits(
|
pub fn unset_clock_limits(
|
||||||
settings: Arc<Mutex<Gpu>>,
|
sender: Sender<ApiMessage>,
|
||||||
saver: Sender<()>,
|
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let saver = Mutex::new(saver); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move ||
|
||||||
|
sender.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Gpu(GpuMessage::SetClockLimits(None))).expect("unset_clock_limits send failed");
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| {
|
||||||
let mut settings_lock = unwrap_lock(settings.lock(), "gpu");
|
setter();
|
||||||
settings_lock.clock_limits = None;
|
vec![true.into()]
|
||||||
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(), true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_slow_memory(
|
pub fn set_slow_memory(
|
||||||
settings: Arc<Mutex<Gpu>>,
|
sender: Sender<ApiMessage>,
|
||||||
saver: Sender<()>,
|
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let saver = Mutex::new(saver); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move |value: bool|
|
||||||
|
sender.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Gpu(GpuMessage::SetSlowMemory(value))).expect("unset_clock_limits send failed");
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(Primitive::Bool(memory_is_slow)) = params_in.get(0) {
|
if let Some(&Primitive::Bool(memory_is_slow)) = params_in.get(0) {
|
||||||
let mut settings_lock = unwrap_lock(settings.lock(), "gpu");
|
setter(memory_is_slow);
|
||||||
settings_lock.slow_memory = *memory_is_slow;
|
vec![memory_is_slow.into()]
|
||||||
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.slow_memory,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
vec!["set_slow_memory missing parameter 0".into()]
|
vec!["set_slow_memory missing parameter 0".into()]
|
||||||
}
|
}
|
||||||
|
@ -152,10 +148,22 @@ pub fn set_slow_memory(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_slow_memory(
|
pub fn get_slow_memory(
|
||||||
settings: Arc<Mutex<Gpu>>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl AsyncCallable {
|
||||||
move |_: super::ApiParameterType| {
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let settings_lock = unwrap_lock(settings.lock(), "cpu");
|
let getter = move || {
|
||||||
vec![settings_lock.slow_memory.into()]
|
let sender2 = sender.clone();
|
||||||
|
move || {
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
let callback = move |value: bool| tx.send(value).expect("get_slow_memory callback send failed");
|
||||||
|
sender2.lock().unwrap().send(ApiMessage::Gpu(GpuMessage::GetSlowMemory(Box::new(callback)))).expect("get_slow_memory send failed");
|
||||||
|
rx.recv().expect("get_slow_memory callback recv failed")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
super::async_utils::AsyncIshGetter {
|
||||||
|
set_get: getter,
|
||||||
|
trans_getter: |value: bool| {
|
||||||
|
vec![value.into()]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
199
backend/src/api/handler.rs
Normal file
199
backend/src/api/handler.rs
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
use std::sync::mpsc::{self, Receiver, Sender};
|
||||||
|
|
||||||
|
use crate::settings::{Settings, Cpu, Gpu, Battery, General, OnSet, OnResume, MinMax};
|
||||||
|
use crate::persist::SettingsJson;
|
||||||
|
use crate::utility::unwrap_maybe_fatal;
|
||||||
|
|
||||||
|
type Callback<T> = Box<dyn FnOnce(T) + Send>;
|
||||||
|
|
||||||
|
pub enum ApiMessage {
|
||||||
|
Battery(BatteryMessage),
|
||||||
|
Cpu(CpuMessage),
|
||||||
|
Gpu(GpuMessage),
|
||||||
|
General(GeneralMessage),
|
||||||
|
OnResume,
|
||||||
|
WaitForEmptyQueue(Callback<()>),
|
||||||
|
LoadSettings(String, String), // (path, name)
|
||||||
|
LoadMainSettings,
|
||||||
|
LoadSystemSettings,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum BatteryMessage {
|
||||||
|
SetChargeRate(Option<u64>),
|
||||||
|
GetChargeRate(Callback<Option<u64>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BatteryMessage {
|
||||||
|
fn process(self, settings: &mut Battery) {
|
||||||
|
match self {
|
||||||
|
Self::SetChargeRate(rate) => settings.charge_rate = rate,
|
||||||
|
Self::GetChargeRate(cb) => cb(settings.charge_rate),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum CpuMessage {
|
||||||
|
SetCpuOnline(usize, bool),
|
||||||
|
SetCpusOnline(Vec<bool>),
|
||||||
|
GetCpusOnline(Callback<Vec<bool>>),
|
||||||
|
SetClockLimits(usize, Option<MinMax<u64>>),
|
||||||
|
GetClockLimits(usize, Callback<Option<MinMax<u64>>>),
|
||||||
|
SetCpuGovernor(usize, String),
|
||||||
|
SetCpusGovernor(Vec<String>),
|
||||||
|
GetCpusGovernor(Callback<Vec<String>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CpuMessage {
|
||||||
|
fn process(self, settings: &mut Vec<Cpu>) {
|
||||||
|
match self {
|
||||||
|
Self::SetCpuOnline(index, status) => {settings.get_mut(index).map(|c| c.online = status);},
|
||||||
|
Self::SetCpusOnline(cpus) => {
|
||||||
|
for i in 0..cpus.len() {
|
||||||
|
settings.get_mut(i).map(|c| c.online = cpus[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Self::GetCpusOnline(cb) => {
|
||||||
|
let mut result = Vec::with_capacity(settings.len());
|
||||||
|
for cpu in settings {
|
||||||
|
result.push(cpu.online);
|
||||||
|
}
|
||||||
|
cb(result);
|
||||||
|
},
|
||||||
|
Self::SetClockLimits(index, clocks) => {settings.get_mut(index).map(|c| c.clock_limits = clocks);},
|
||||||
|
Self::GetClockLimits(index, cb) => {settings.get(index).map(|c| cb(c.clock_limits.clone()));},
|
||||||
|
Self::SetCpuGovernor(index, gov) => {settings.get_mut(index).map(|c| c.governor = gov);},
|
||||||
|
Self::SetCpusGovernor(govs) => {
|
||||||
|
for i in 0..govs.len() {
|
||||||
|
settings.get_mut(i).map(|c| c.governor = govs[i].clone());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Self::GetCpusGovernor(cb) => {
|
||||||
|
let mut result = Vec::with_capacity(settings.len());
|
||||||
|
for cpu in settings {
|
||||||
|
result.push(cpu.governor.clone());
|
||||||
|
}
|
||||||
|
cb(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum GpuMessage {
|
||||||
|
SetPpt(Option<u64>, Option<u64>), // (fast, slow)
|
||||||
|
GetPpt(Callback<(Option<u64>, Option<u64>)>),
|
||||||
|
SetClockLimits(Option<MinMax<u64>>),
|
||||||
|
GetClockLimits(Callback<Option<MinMax<u64>>>),
|
||||||
|
SetSlowMemory(bool),
|
||||||
|
GetSlowMemory(Callback<bool>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GpuMessage {
|
||||||
|
fn process(self, settings: &mut Gpu) {
|
||||||
|
match self {
|
||||||
|
Self::SetPpt(fast, slow) => {
|
||||||
|
settings.fast_ppt = fast;
|
||||||
|
settings.slow_ppt = slow;
|
||||||
|
},
|
||||||
|
Self::GetPpt(cb) => cb((settings.fast_ppt, settings.slow_ppt)),
|
||||||
|
Self::SetClockLimits(clocks) => settings.clock_limits = clocks,
|
||||||
|
Self::GetClockLimits(cb) => cb(settings.clock_limits.clone()),
|
||||||
|
Self::SetSlowMemory(val) => settings.slow_memory = val,
|
||||||
|
Self::GetSlowMemory(cb) => cb(settings.slow_memory),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum GeneralMessage {
|
||||||
|
SetPersistent(bool),
|
||||||
|
GetPersistent(Callback<bool>),
|
||||||
|
GetCurrentProfileName(Callback<String>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GeneralMessage {
|
||||||
|
fn process(self, settings: &mut General) {
|
||||||
|
match self {
|
||||||
|
Self::SetPersistent(val) => settings.persistent = val,
|
||||||
|
Self::GetPersistent(cb) => cb(settings.persistent),
|
||||||
|
Self::GetCurrentProfileName(cb) => cb(settings.name.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ApiMessageHandler {
|
||||||
|
intake: Receiver<ApiMessage>,
|
||||||
|
on_empty: Vec<Callback<()>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ApiMessageHandler {
|
||||||
|
pub fn process_forever(&mut self, settings: &mut Settings) {
|
||||||
|
while let Ok(msg) = self.intake.recv() {
|
||||||
|
self.process(settings, msg);
|
||||||
|
while let Ok(msg) = self.intake.try_recv() {
|
||||||
|
self.process(settings, msg);
|
||||||
|
}
|
||||||
|
// run on_set
|
||||||
|
if let Err(e) = settings.on_set() {
|
||||||
|
log::error!("Settings on_set() err: {}", e);
|
||||||
|
}
|
||||||
|
// do callbacks
|
||||||
|
for func in self.on_empty.drain(..) {
|
||||||
|
func(());
|
||||||
|
}
|
||||||
|
// save
|
||||||
|
log::debug!("api_worker is saving...");
|
||||||
|
let is_persistent = settings.general.persistent;
|
||||||
|
if is_persistent {
|
||||||
|
let save_path = crate::utility::settings_dir()
|
||||||
|
.join(settings.general.path.clone());
|
||||||
|
let settings_clone = settings.clone();
|
||||||
|
let save_json: SettingsJson = settings_clone.into();
|
||||||
|
unwrap_maybe_fatal(save_json.save(&save_path), "Failed to save settings");
|
||||||
|
log::debug!("Saved settings to {}", save_path.display());
|
||||||
|
} else {
|
||||||
|
log::debug!("Ignored save request for non-persistent settings");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process(&mut self, settings: &mut Settings, message: ApiMessage) {
|
||||||
|
match message {
|
||||||
|
ApiMessage::Battery(x) => x.process(&mut settings.battery),
|
||||||
|
ApiMessage::Cpu(x) => x.process(&mut settings.cpus),
|
||||||
|
ApiMessage::Gpu(x) => x.process(&mut settings.gpu),
|
||||||
|
ApiMessage::General(x) => x.process(&mut settings.general),
|
||||||
|
ApiMessage::OnResume => {
|
||||||
|
if let Err(e) = settings.on_resume() {
|
||||||
|
log::error!("Settings on_resume() err: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ApiMessage::WaitForEmptyQueue(callback) => self.on_empty.push(callback),
|
||||||
|
ApiMessage::LoadSettings(path, name) => {
|
||||||
|
match settings.load_file(path.into(), name, false) {
|
||||||
|
Ok(success) => log::info!("Loaded settings file? {}", success),
|
||||||
|
Err(e) => log::warn!("Load file err: {}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ApiMessage::LoadMainSettings => {
|
||||||
|
match settings.load_file(
|
||||||
|
crate::consts::DEFAULT_SETTINGS_FILE.into(),
|
||||||
|
crate::consts::DEFAULT_SETTINGS_NAME.to_owned(),
|
||||||
|
true
|
||||||
|
) {
|
||||||
|
Ok(success) => log::info!("Loaded main settings file? {}", success),
|
||||||
|
Err(e) => log::warn!("Load file err: {}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ApiMessage::LoadSystemSettings => {
|
||||||
|
settings.load_system_default();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new() -> (Self, Sender<ApiMessage>) {
|
||||||
|
let (tx, rx) = mpsc::channel();
|
||||||
|
(Self {
|
||||||
|
intake: rx,
|
||||||
|
on_empty: Vec::with_capacity(4),
|
||||||
|
}, tx)
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,8 @@ pub mod battery;
|
||||||
pub mod cpu;
|
pub mod cpu;
|
||||||
pub mod general;
|
pub mod general;
|
||||||
pub mod gpu;
|
pub mod gpu;
|
||||||
|
pub mod handler;
|
||||||
|
mod async_utils;
|
||||||
mod utility;
|
mod utility;
|
||||||
|
|
||||||
pub(super) type ApiParameterType = Vec<usdpl_back::core::serdes::Primitive>;
|
pub(super) type ApiParameterType = Vec<usdpl_back::core::serdes::Primitive>;
|
||||||
|
|
|
@ -14,7 +14,7 @@ pub fn map_result<T: Into<Primitive>>(result: Result<T, SettingError>) -> super:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
/*#[inline]
|
||||||
pub fn map_empty_result<T: Into<Primitive>>(
|
pub fn map_empty_result<T: Into<Primitive>>(
|
||||||
result: Result<(), SettingError>,
|
result: Result<(), SettingError>,
|
||||||
success: T,
|
success: T,
|
||||||
|
@ -26,4 +26,4 @@ pub fn map_empty_result<T: Into<Primitive>>(
|
||||||
vec![e.msg.into()]
|
vec![e.msg.into()]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
13
backend/src/api_worker.rs
Normal file
13
backend/src/api_worker.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
use std::thread::{self, JoinHandle};
|
||||||
|
|
||||||
|
use crate::settings::Settings;
|
||||||
|
//use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
|
||||||
|
use crate::api::handler::ApiMessageHandler;
|
||||||
|
|
||||||
|
pub fn spawn(mut settings: Settings, mut handler: ApiMessageHandler) -> JoinHandle<()> {
|
||||||
|
thread::spawn(move || {
|
||||||
|
log::info!("api_worker starting...");
|
||||||
|
handler.process_forever(&mut settings);
|
||||||
|
log::warn!("api_worker completed!");
|
||||||
|
})
|
||||||
|
}
|
|
@ -4,4 +4,4 @@ pub const PACKAGE_NAME: &'static str = env!("CARGO_PKG_NAME");
|
||||||
pub const PACKAGE_VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
pub const PACKAGE_VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
pub const DEFAULT_SETTINGS_FILE: &str = "default_settings.json";
|
pub const DEFAULT_SETTINGS_FILE: &str = "default_settings.json";
|
||||||
pub const DEFAULT_SETTINGS_NAME: &str = "Default";
|
pub const DEFAULT_SETTINGS_NAME: &str = "Main";
|
||||||
|
|
|
@ -6,7 +6,8 @@ mod state;
|
||||||
mod consts;
|
mod consts;
|
||||||
use consts::*;
|
use consts::*;
|
||||||
mod resume_worker;
|
mod resume_worker;
|
||||||
mod save_worker;
|
//mod save_worker;
|
||||||
|
mod api_worker;
|
||||||
mod utility;
|
mod utility;
|
||||||
|
|
||||||
use settings::OnSet;
|
use settings::OnSet;
|
||||||
|
@ -49,14 +50,16 @@ fn main() -> Result<(), ()> {
|
||||||
|
|
||||||
log::debug!("Settings: {:?}", loaded_settings);
|
log::debug!("Settings: {:?}", loaded_settings);
|
||||||
|
|
||||||
let (_save_handle, save_sender) = save_worker::spawn(loaded_settings.clone());
|
let (api_handler, api_sender) = crate::api::handler::ApiMessageHandler::new();
|
||||||
let _resume_handle = resume_worker::spawn(loaded_settings.clone());
|
|
||||||
|
//let (_save_handle, save_sender) = save_worker::spawn(loaded_settings.clone());
|
||||||
|
let _resume_handle = resume_worker::spawn(api_sender.clone());
|
||||||
|
|
||||||
if let Err(e) = loaded_settings.on_set() {
|
if let Err(e) = loaded_settings.on_set() {
|
||||||
log::error!("Startup Settings.on_set() error: {}", e);
|
log::error!("Startup Settings.on_set() error: {}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
Instance::new(PORT)
|
let instance = Instance::new(PORT)
|
||||||
.register("V_INFO", |_: Vec<Primitive>| {
|
.register("V_INFO", |_: Vec<Primitive>| {
|
||||||
vec![format!("{} v{}", PACKAGE_NAME, PACKAGE_VERSION).into()]
|
vec![format!("{} v{}", PACKAGE_NAME, PACKAGE_VERSION).into()]
|
||||||
})
|
})
|
||||||
|
@ -67,107 +70,119 @@ fn main() -> Result<(), ()> {
|
||||||
.register("BATTERY_charge_design", api::battery::charge_design)
|
.register("BATTERY_charge_design", api::battery::charge_design)
|
||||||
.register(
|
.register(
|
||||||
"BATTERY_set_charge_rate",
|
"BATTERY_set_charge_rate",
|
||||||
api::battery::set_charge_rate(loaded_settings.battery.clone(), save_sender.clone()),
|
api::battery::set_charge_rate(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"BATTERY_get_charge_rate",
|
"BATTERY_get_charge_rate",
|
||||||
api::battery::get_charge_rate(loaded_settings.battery.clone()),
|
api::battery::get_charge_rate(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"BATTERY_unset_charge_rate",
|
"BATTERY_unset_charge_rate",
|
||||||
api::battery::unset_charge_rate(loaded_settings.battery.clone(), save_sender.clone()),
|
api::battery::unset_charge_rate(api_sender.clone()),
|
||||||
)
|
)
|
||||||
// cpu API functions
|
// cpu API functions
|
||||||
.register("CPU_count", api::cpu::max_cpus)
|
.register("CPU_count", api::cpu::max_cpus)
|
||||||
.register(
|
.register(
|
||||||
"CPU_set_online",
|
"CPU_set_online",
|
||||||
api::cpu::set_cpu_online(loaded_settings.cpus.clone(), save_sender.clone())
|
api::cpu::set_cpu_online(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"CPU_set_onlines",
|
"CPU_set_onlines",
|
||||||
api::cpu::set_cpus_online(loaded_settings.cpus.clone(), save_sender.clone())
|
api::cpu::set_cpus_online(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register_async(
|
||||||
"CPU_get_onlines",
|
"CPU_get_onlines",
|
||||||
api::cpu::get_cpus_online(loaded_settings.cpus.clone())
|
api::cpu::get_cpus_online(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"CPU_set_clock_limits",
|
"CPU_set_clock_limits",
|
||||||
api::cpu::set_clock_limits(loaded_settings.cpus.clone(), save_sender.clone())
|
api::cpu::set_clock_limits(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"CPU_get_clock_limits",
|
"CPU_get_clock_limits",
|
||||||
api::cpu::get_clock_limits(loaded_settings.cpus.clone())
|
api::cpu::get_clock_limits(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"CPU_unset_clock_limits",
|
"CPU_unset_clock_limits",
|
||||||
api::cpu::unset_clock_limits(loaded_settings.cpus.clone(), save_sender.clone())
|
api::cpu::unset_clock_limits(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"CPU_set_governor",
|
"CPU_set_governor",
|
||||||
api::cpu::set_cpu_governor(loaded_settings.cpus.clone(), save_sender.clone())
|
api::cpu::set_cpu_governor(api_sender.clone())
|
||||||
|
)
|
||||||
|
.register(
|
||||||
|
"CPU_set_governors",
|
||||||
|
api::cpu::set_cpus_governors(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"CPU_get_governors",
|
"CPU_get_governors",
|
||||||
api::cpu::get_cpu_governors(loaded_settings.cpus.clone())
|
api::cpu::get_cpu_governors(api_sender.clone())
|
||||||
)
|
)
|
||||||
// gpu API functions
|
// gpu API functions
|
||||||
.register(
|
.register(
|
||||||
"GPU_set_ppt",
|
"GPU_set_ppt",
|
||||||
api::gpu::set_ppt(loaded_settings.gpu.clone(), save_sender.clone())
|
api::gpu::set_ppt(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register_async(
|
||||||
"GPU_get_ppt",
|
"GPU_get_ppt",
|
||||||
api::gpu::get_ppt(loaded_settings.gpu.clone())
|
api::gpu::get_ppt(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"GPU_unset_ppt",
|
"GPU_unset_ppt",
|
||||||
api::gpu::unset_ppt(loaded_settings.gpu.clone(), save_sender.clone())
|
api::gpu::unset_ppt(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"GPU_set_clock_limits",
|
"GPU_set_clock_limits",
|
||||||
api::gpu::set_clock_limits(loaded_settings.gpu.clone(), save_sender.clone())
|
api::gpu::set_clock_limits(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register_async(
|
||||||
"GPU_get_clock_limits",
|
"GPU_get_clock_limits",
|
||||||
api::gpu::get_clock_limits(loaded_settings.gpu.clone())
|
api::gpu::get_clock_limits(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"GPU_unset_clock_limits",
|
"GPU_unset_clock_limits",
|
||||||
api::gpu::unset_clock_limits(loaded_settings.gpu.clone(), save_sender.clone())
|
api::gpu::unset_clock_limits(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"GPU_set_slow_memory",
|
"GPU_set_slow_memory",
|
||||||
api::gpu::set_slow_memory(loaded_settings.gpu.clone(), save_sender.clone())
|
api::gpu::set_slow_memory(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register_async(
|
||||||
"GPU_get_slow_memory",
|
"GPU_get_slow_memory",
|
||||||
api::gpu::get_slow_memory(loaded_settings.gpu.clone())
|
api::gpu::get_slow_memory(api_sender.clone())
|
||||||
)
|
)
|
||||||
// general API functions
|
// general API functions
|
||||||
.register(
|
.register(
|
||||||
"GENERAL_set_persistent",
|
"GENERAL_set_persistent",
|
||||||
api::general::set_persistent(loaded_settings.general.clone(), save_sender.clone())
|
api::general::set_persistent(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"GENERAL_get_persistent",
|
"GENERAL_get_persistent",
|
||||||
api::general::get_persistent(loaded_settings.general.clone())
|
api::general::get_persistent(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"GENERAL_load_settings",
|
"GENERAL_load_settings",
|
||||||
api::general::load_settings(loaded_settings.clone())
|
api::general::load_settings(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"GENERAL_load_default_settings",
|
"GENERAL_load_default_settings",
|
||||||
api::general::load_default_settings(loaded_settings.clone())
|
api::general::load_default_settings(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
|
"GENERAL_load_system_settings",
|
||||||
|
api::general::load_system_settings(api_sender.clone())
|
||||||
|
)
|
||||||
|
.register_async(
|
||||||
"GENERAL_get_name",
|
"GENERAL_get_name",
|
||||||
api::general::get_name(loaded_settings.general.clone())
|
api::general::get_name(api_sender.clone())
|
||||||
)
|
)
|
||||||
.register(
|
.register_async(
|
||||||
"GENERAL_wait_for_unlocks",
|
"GENERAL_wait_for_unlocks",
|
||||||
api::general::lock_unlock_all(loaded_settings.clone())
|
api::general::lock_unlock_all(api_sender.clone())
|
||||||
)
|
);
|
||||||
|
|
||||||
|
api_worker::spawn(loaded_settings, api_handler);
|
||||||
|
|
||||||
|
instance
|
||||||
.run_blocking()
|
.run_blocking()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
use std::thread::{self, JoinHandle};
|
use std::thread::{self, JoinHandle};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
use std::sync::mpsc::Sender;
|
||||||
|
|
||||||
use crate::settings::{OnResume, Settings};
|
use crate::api::handler::ApiMessage;
|
||||||
use crate::utility::unwrap_maybe_fatal;
|
//use crate::utility::unwrap_maybe_fatal;
|
||||||
|
|
||||||
const ALLOWED_ERROR: f64 = 100.0; // period of 10ms with 100x means sleep has to be >= 1s to be detected
|
const ALLOWED_ERROR: f64 = 100.0; // period of 10ms with 100x means sleep has to be >= 1s to be detected
|
||||||
|
|
||||||
pub fn spawn(settings: Settings) -> JoinHandle<()> {
|
pub fn spawn(sender: Sender<ApiMessage>) -> JoinHandle<()> {
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
log::info!("resume_worker starting...");
|
log::info!("resume_worker starting...");
|
||||||
let duration = Duration::from_millis(10); // very low so it detects before Steam client does
|
let duration = Duration::from_millis(10); // very low so it detects before Steam client does
|
||||||
|
@ -18,7 +19,7 @@ pub fn spawn(settings: Settings) -> JoinHandle<()> {
|
||||||
if old_start.as_secs_f64() > duration.as_secs_f64() * (1.0 + ALLOWED_ERROR) {
|
if old_start.as_secs_f64() > duration.as_secs_f64() * (1.0 + ALLOWED_ERROR) {
|
||||||
// has just resumed from sleep
|
// has just resumed from sleep
|
||||||
log::info!("Resume detected");
|
log::info!("Resume detected");
|
||||||
unwrap_maybe_fatal(settings.on_resume(), "On resume failure");
|
sender.send(ApiMessage::OnResume).expect("resume_worker send failed");
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"OnResume completed after sleeping for {}s",
|
"OnResume completed after sleeping for {}s",
|
||||||
old_start.as_secs_f32()
|
old_start.as_secs_f32()
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use std::convert::Into;
|
use std::convert::Into;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::{Arc, Mutex};
|
//use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use super::{Battery, Cpu, Gpu};
|
use super::{Battery, Cpu, Gpu};
|
||||||
use super::{OnResume, OnSet, SettingError};
|
use super::{OnResume, OnSet, SettingError};
|
||||||
use crate::persist::{CpuJson, SettingsJson};
|
use crate::persist::{CpuJson, SettingsJson};
|
||||||
use crate::utility::unwrap_lock;
|
//use crate::utility::unwrap_lock;
|
||||||
|
|
||||||
const LATEST_VERSION: u64 = 0;
|
const LATEST_VERSION: u64 = 0;
|
||||||
|
|
||||||
|
@ -43,24 +43,20 @@ impl OnSet for General {
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
pub general: Arc<Mutex<General>>,
|
pub general: General,
|
||||||
pub cpus: Arc<Mutex<Vec<Cpu>>>,
|
pub cpus: Vec<Cpu>,
|
||||||
pub gpu: Arc<Mutex<Gpu>>,
|
pub gpu: Gpu,
|
||||||
pub battery: Arc<Mutex<Battery>>,
|
pub battery: Battery,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OnSet for Settings {
|
impl OnSet for Settings {
|
||||||
fn on_set(&mut self) -> Result<(), SettingError> {
|
fn on_set(&mut self) -> Result<(), SettingError> {
|
||||||
unwrap_lock(self.battery.lock(), "battery").on_set()?;
|
self.battery.on_set()?;
|
||||||
{
|
for cpu in self.cpus.iter_mut() {
|
||||||
// cpu lock scope
|
cpu.on_set()?;
|
||||||
let mut cpu_lock = unwrap_lock(self.cpus.lock(), "cpu");
|
|
||||||
for cpu in cpu_lock.iter_mut() {
|
|
||||||
cpu.on_set()?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
unwrap_lock(self.gpu.lock(), "gpu").on_set()?;
|
self.gpu.on_set()?;
|
||||||
unwrap_lock(self.general.lock(), "general").on_set()?;
|
self.general.on_set()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,24 +66,24 @@ impl Settings {
|
||||||
pub fn from_json(other: SettingsJson, json_path: PathBuf) -> Self {
|
pub fn from_json(other: SettingsJson, json_path: PathBuf) -> Self {
|
||||||
match other.version {
|
match other.version {
|
||||||
0 => Self {
|
0 => Self {
|
||||||
general: Arc::new(Mutex::new(General {
|
general: General {
|
||||||
persistent: other.persistent,
|
persistent: other.persistent,
|
||||||
path: json_path,
|
path: json_path,
|
||||||
name: other.name,
|
name: other.name,
|
||||||
})),
|
},
|
||||||
cpus: Arc::new(Mutex::new(Self::convert_cpus(other.cpus, other.version))),
|
cpus: Self::convert_cpus(other.cpus, other.version),
|
||||||
gpu: Arc::new(Mutex::new(Gpu::from_json(other.gpu, other.version))),
|
gpu: Gpu::from_json(other.gpu, other.version),
|
||||||
battery: Arc::new(Mutex::new(Battery::from_json(other.battery, other.version))),
|
battery: Battery::from_json(other.battery, other.version),
|
||||||
},
|
},
|
||||||
_ => Self {
|
_ => Self {
|
||||||
general: Arc::new(Mutex::new(General {
|
general: General {
|
||||||
persistent: other.persistent,
|
persistent: other.persistent,
|
||||||
path: json_path,
|
path: json_path,
|
||||||
name: other.name,
|
name: other.name,
|
||||||
})),
|
},
|
||||||
cpus: Arc::new(Mutex::new(Self::convert_cpus(other.cpus, other.version))),
|
cpus: Self::convert_cpus(other.cpus, other.version),
|
||||||
gpu: Arc::new(Mutex::new(Gpu::from_json(other.gpu, other.version))),
|
gpu: Gpu::from_json(other.gpu, other.version),
|
||||||
battery: Arc::new(Mutex::new(Battery::from_json(other.battery, other.version))),
|
battery: Battery::from_json(other.battery, other.version),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,35 +113,26 @@ impl Settings {
|
||||||
|
|
||||||
pub fn system_default(json_path: PathBuf) -> Self {
|
pub fn system_default(json_path: PathBuf) -> Self {
|
||||||
Self {
|
Self {
|
||||||
general: Arc::new(Mutex::new(General {
|
general: General {
|
||||||
persistent: false,
|
persistent: false,
|
||||||
path: json_path,
|
path: json_path,
|
||||||
name: crate::consts::DEFAULT_SETTINGS_NAME.to_owned(),
|
name: crate::consts::DEFAULT_SETTINGS_NAME.to_owned(),
|
||||||
})),
|
},
|
||||||
cpus: Arc::new(Mutex::new(Cpu::system_default())),
|
cpus: Cpu::system_default(),
|
||||||
gpu: Arc::new(Mutex::new(Gpu::system_default())),
|
gpu: Gpu::system_default(),
|
||||||
battery: Arc::new(Mutex::new(Battery::system_default())),
|
battery: Battery::system_default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_system_default(&self) {
|
pub fn load_system_default(&mut self) {
|
||||||
{
|
self.cpus = Cpu::system_default();
|
||||||
let mut cpu_lock = unwrap_lock(self.cpus.lock(), "cpu");
|
self.gpu = Gpu::system_default();
|
||||||
*cpu_lock = Cpu::system_default();
|
self.battery = Battery::system_default();
|
||||||
}
|
|
||||||
{
|
|
||||||
let mut gpu_lock = unwrap_lock(self.gpu.lock(), "gpu");
|
|
||||||
*gpu_lock = Gpu::system_default();
|
|
||||||
}
|
|
||||||
{
|
|
||||||
let mut battery_lock = unwrap_lock(self.battery.lock(), "battery");
|
|
||||||
*battery_lock = Battery::system_default();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_file(&self, filename: PathBuf, name: String, system_defaults: bool) -> Result<bool, SettingError> {
|
pub fn load_file(&mut self, filename: PathBuf, name: String, system_defaults: bool) -> Result<bool, SettingError> {
|
||||||
let json_path = crate::utility::settings_dir().join(filename);
|
let json_path = crate::utility::settings_dir().join(filename);
|
||||||
let mut general_lock = unwrap_lock(self.general.lock(), "general");
|
//let mut general_lock = unwrap_lock(self.general.lock(), "general");
|
||||||
if json_path.exists() {
|
if json_path.exists() {
|
||||||
let settings_json = SettingsJson::open(&json_path).map_err(|e| SettingError {
|
let settings_json = SettingsJson::open(&json_path).map_err(|e| SettingError {
|
||||||
msg: e.to_string(),
|
msg: e.to_string(),
|
||||||
|
@ -153,53 +140,38 @@ impl Settings {
|
||||||
})?;
|
})?;
|
||||||
if !settings_json.persistent {
|
if !settings_json.persistent {
|
||||||
log::warn!("Loaded persistent config `{}` ({}) with persistent=false", &settings_json.name, json_path.display());
|
log::warn!("Loaded persistent config `{}` ({}) with persistent=false", &settings_json.name, json_path.display());
|
||||||
general_lock.persistent = false;
|
self.general.persistent = false;
|
||||||
general_lock.name = name;
|
self.general.name = name;
|
||||||
} else {
|
} else {
|
||||||
let new_cpus = Self::convert_cpus(settings_json.cpus, settings_json.version);
|
self.cpus = Self::convert_cpus(settings_json.cpus, settings_json.version);
|
||||||
let new_gpu = Gpu::from_json(settings_json.gpu, settings_json.version);
|
self.gpu = Gpu::from_json(settings_json.gpu, settings_json.version);
|
||||||
let new_battery = Battery::from_json(settings_json.battery, settings_json.version);
|
self.battery = Battery::from_json(settings_json.battery, settings_json.version);
|
||||||
{
|
self.general.persistent = true;
|
||||||
let mut cpu_lock = unwrap_lock(self.cpus.lock(), "cpu");
|
self.general.name = settings_json.name;
|
||||||
*cpu_lock = new_cpus;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
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 {
|
} else {
|
||||||
if system_defaults {
|
if system_defaults {
|
||||||
self.load_system_default();
|
self.load_system_default();
|
||||||
}
|
}
|
||||||
general_lock.persistent = false;
|
self.general.persistent = false;
|
||||||
general_lock.name = name;
|
self.general.name = name;
|
||||||
}
|
}
|
||||||
general_lock.path = json_path;
|
self.general.path = json_path;
|
||||||
Ok(general_lock.persistent)
|
Ok(self.general.persistent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OnResume for Settings {
|
impl OnResume for Settings {
|
||||||
fn on_resume(&self) -> Result<(), SettingError> {
|
fn on_resume(&self) -> Result<(), SettingError> {
|
||||||
log::debug!("Locking settings for on_resume");
|
log::debug!("Applying settings for on_resume");
|
||||||
unwrap_lock(self.battery.lock(), "battery").on_resume()?;
|
self.battery.on_resume()?;
|
||||||
log::debug!("Got battery lock");
|
log::debug!("Resumed battery");
|
||||||
{
|
for cpu in self.cpus.iter() {
|
||||||
let cpu_lock = unwrap_lock(self.cpus.lock(), "cpu");
|
cpu.on_resume()?;
|
||||||
log::debug!("Got cpus lock");
|
|
||||||
for cpu in cpu_lock.iter() {
|
|
||||||
cpu.on_resume()?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
unwrap_lock(self.gpu.lock(), "gpu").on_resume()?;
|
log::debug!("Resumed CPUs");
|
||||||
log::debug!("Got gpu lock");
|
self.gpu.on_resume()?;
|
||||||
|
log::debug!("Resumed GPU");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,26 +179,18 @@ impl OnResume for Settings {
|
||||||
impl Into<SettingsJson> for Settings {
|
impl Into<SettingsJson> for Settings {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into(self) -> SettingsJson {
|
fn into(self) -> SettingsJson {
|
||||||
log::debug!("Locking settings to convert into json");
|
log::debug!("Converting into json");
|
||||||
let gen_lock = unwrap_lock(self.general.lock(), "general");
|
|
||||||
log::debug!("Got general lock");
|
|
||||||
let cpu_lock = unwrap_lock(self.cpus.lock(), "cpu");
|
|
||||||
log::debug!("Got cpus lock");
|
|
||||||
let gpu_lock = unwrap_lock(self.gpu.lock(), "gpu");
|
|
||||||
log::debug!("Got gpu lock");
|
|
||||||
let batt_lock = unwrap_lock(self.battery.lock(), "battery");
|
|
||||||
log::debug!("Got battery lock");
|
|
||||||
SettingsJson {
|
SettingsJson {
|
||||||
version: LATEST_VERSION,
|
version: LATEST_VERSION,
|
||||||
name: gen_lock.name.clone(),
|
name: self.general.name.clone(),
|
||||||
persistent: gen_lock.persistent,
|
persistent: self.general.persistent,
|
||||||
cpus: cpu_lock
|
cpus: self.cpus
|
||||||
.clone()
|
.clone()
|
||||||
.drain(..)
|
.drain(..)
|
||||||
.map(|cpu| cpu.into())
|
.map(|cpu| cpu.into())
|
||||||
.collect(),
|
.collect(),
|
||||||
gpu: gpu_lock.clone().into(),
|
gpu: self.gpu.clone().into(),
|
||||||
battery: batt_lock.clone().into(),
|
battery: self.battery.clone().into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::sync::{LockResult, MutexGuard};
|
//use std::sync::{LockResult, MutexGuard};
|
||||||
|
|
||||||
pub fn unwrap_maybe_fatal<T: Sized, E: Display>(result: Result<T, E>, message: &str) -> T {
|
pub fn unwrap_maybe_fatal<T: Sized, E: Display>(result: Result<T, E>, message: &str) -> T {
|
||||||
match result {
|
match result {
|
||||||
|
@ -11,7 +11,7 @@ pub fn unwrap_maybe_fatal<T: Sized, E: Display>(result: Result<T, E>, message: &
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unwrap_lock<'a, T: Sized>(
|
/*pub fn unwrap_lock<'a, T: Sized>(
|
||||||
result: LockResult<MutexGuard<'a, T>>,
|
result: LockResult<MutexGuard<'a, T>>,
|
||||||
lock_name: &str,
|
lock_name: &str,
|
||||||
) -> MutexGuard<'a, T> {
|
) -> MutexGuard<'a, T> {
|
||||||
|
@ -22,7 +22,7 @@ pub fn unwrap_lock<'a, T: Sized>(
|
||||||
panic!("Failed to acquire {} lock: {}", lock_name, e);
|
panic!("Failed to acquire {} lock: {}", lock_name, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
pub fn settings_dir() -> std::path::PathBuf {
|
pub fn settings_dir() -> std::path::PathBuf {
|
||||||
usdpl_back::api::dirs::home()
|
usdpl_back::api::dirs::home()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "PowerTools",
|
"name": "PowerTools",
|
||||||
"version": "1.0.5",
|
"version": "1.1.0",
|
||||||
"description": "Power tweaks for power users",
|
"description": "Power tweaks for power users",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "shx rm -rf dist && rollup -c",
|
"build": "shx rm -rf dist && rollup -c",
|
||||||
|
|
Loading…
Reference in a new issue