Add multi-profile per-game functionality for #82, change to JSON to RON format
This commit is contained in:
parent
a90932d813
commit
3aa9680bae
18 changed files with 253 additions and 159 deletions
26
backend/Cargo.lock
generated
26
backend/Cargo.lock
generated
|
@ -153,7 +153,7 @@ version = "0.64.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"lazy_static",
|
||||
|
@ -175,6 +175,15 @@ version = "1.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
|
@ -599,7 +608,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"bytes",
|
||||
"headers-core",
|
||||
"http",
|
||||
|
@ -1059,6 +1068,7 @@ dependencies = [
|
|||
"limits_core",
|
||||
"log",
|
||||
"regex",
|
||||
"ron",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"simplelog",
|
||||
|
@ -1161,6 +1171,18 @@ version = "0.7.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
|
||||
|
||||
[[package]]
|
||||
name = "ron"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94"
|
||||
dependencies = [
|
||||
"base64 0.21.2",
|
||||
"bitflags 2.4.1",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
|
|
|
@ -15,6 +15,7 @@ readme = "../README.md"
|
|||
usdpl-back = { version = "0.10.1", features = ["blocking"] }#, path = "../../usdpl-rs/usdpl-back"}
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
ron = "0.8"
|
||||
sysfuss = { version = "0.2", features = ["derive"] }#,path = "../../sysfs-nav"}
|
||||
|
||||
# async
|
||||
|
|
|
@ -55,18 +55,34 @@ pub fn load_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 |path: u64, name: String| {
|
||||
let setter = move |id: u64, name: String, variant: u64, variant_name: Option<String>| {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::LoadSettings(path, name))
|
||||
.send(ApiMessage::LoadSettings(id, name, variant, variant_name.unwrap_or_else(|| crate::consts::DEFAULT_SETTINGS_VARIANT_NAME.to_owned())))
|
||||
.expect("load_settings send failed")
|
||||
};
|
||||
move |params_in: super::ApiParameterType| {
|
||||
if let Some(Primitive::String(id)) = params_in.get(0) {
|
||||
if let Some(Primitive::String(name)) = params_in.get(1) {
|
||||
setter(id.parse().unwrap_or_default(), name.to_owned());
|
||||
if let Some(Primitive::F64(variant_id)) = params_in.get(2) {
|
||||
if let Some(Primitive::String(variant_name)) = params_in.get(3) {
|
||||
setter(id.parse().unwrap_or_default(),
|
||||
name.to_owned(),
|
||||
*variant_id as _,
|
||||
Some(variant_name.to_owned()));
|
||||
vec![true.into()]
|
||||
} else {
|
||||
setter(id.parse().unwrap_or_default(),
|
||||
name.to_owned(),
|
||||
*variant_id as _,
|
||||
None);
|
||||
vec![true.into()]
|
||||
}
|
||||
} else {
|
||||
log::warn!("load_settings missing variant id parameter");
|
||||
vec!["load_settings missing variant id parameter".into()]
|
||||
}
|
||||
} else {
|
||||
log::warn!("load_settings missing name parameter");
|
||||
vec!["load_settings missing name parameter".into()]
|
||||
|
|
|
@ -5,7 +5,6 @@ use crate::persist::SettingsJson;
|
|||
use crate::settings::{
|
||||
MinMax, OnPowerEvent, OnResume, OnSet, PowerMode, Settings, TBattery, TCpus, TGeneral, TGpu,
|
||||
};
|
||||
use crate::utility::unwrap_maybe_fatal;
|
||||
|
||||
type Callback<T> = Box<dyn FnOnce(T) + Send>;
|
||||
|
||||
|
@ -23,7 +22,7 @@ pub enum ApiMessage {
|
|||
OnChargeChange(f64), // battery fill amount: 0 = empty, 1 = full
|
||||
PowerVibeCheck,
|
||||
WaitForEmptyQueue(Callback<()>),
|
||||
LoadSettings(u64, String), // (path, name)
|
||||
LoadSettings(u64, String, u64, String), // (path, name, variant, variant name)
|
||||
LoadMainSettings,
|
||||
LoadSystemSettings,
|
||||
GetLimits(Callback<super::SettingsLimits>),
|
||||
|
@ -287,21 +286,14 @@ impl ApiMessageHandler {
|
|||
log::debug!("api_worker is saving...");
|
||||
let is_persistent = *settings.general.persistent();
|
||||
let save_path =
|
||||
crate::utility::settings_dir().join(settings.general.get_path().clone());
|
||||
crate::utility::settings_dir().join(settings.general.get_path());
|
||||
if is_persistent {
|
||||
let settings_clone = settings.json();
|
||||
let save_json: SettingsJson = settings_clone.into();
|
||||
unwrap_maybe_fatal(save_json.save(&save_path), "Failed to save settings");
|
||||
if let Some(event) = &settings.general.on_event().on_save {
|
||||
if !event.is_empty() {
|
||||
unwrap_maybe_fatal(
|
||||
std::process::Command::new("/bin/bash")
|
||||
.args(&["-c", event])
|
||||
.spawn(),
|
||||
"Failed to start on_save event command",
|
||||
);
|
||||
}
|
||||
if let Err(e) = crate::persist::FileJson::update_variant_or_create(&save_path, save_json, settings.general.get_name().to_owned()) {
|
||||
log::error!("Failed to create/update settings file {}: {}", save_path.display(), e);
|
||||
}
|
||||
//unwrap_maybe_fatal(save_json.save(&save_path), "Failed to save settings");
|
||||
log::debug!("Saved settings to {}", save_path.display());
|
||||
if let Err(e) = crate::utility::chown_settings_dir() {
|
||||
log::error!("Failed to change config dir permissions: {}", e);
|
||||
|
@ -375,9 +367,9 @@ impl ApiMessageHandler {
|
|||
self.on_empty.push(callback);
|
||||
false
|
||||
}
|
||||
ApiMessage::LoadSettings(id, name) => {
|
||||
ApiMessage::LoadSettings(id, name, variant_id, variant_name) => {
|
||||
let path = format!("{}.json", id);
|
||||
match settings.load_file(path.into(), name, false) {
|
||||
match settings.load_file(path.into(), name, variant_id, variant_name, false) {
|
||||
Ok(success) => log::info!("Loaded settings file? {}", success),
|
||||
Err(e) => log::warn!("Load file err: {}", e),
|
||||
}
|
||||
|
@ -387,6 +379,8 @@ impl ApiMessageHandler {
|
|||
match settings.load_file(
|
||||
crate::consts::DEFAULT_SETTINGS_FILE.into(),
|
||||
crate::consts::DEFAULT_SETTINGS_NAME.to_owned(),
|
||||
0,
|
||||
crate::consts::DEFAULT_SETTINGS_VARIANT_NAME.to_owned(),
|
||||
true,
|
||||
) {
|
||||
Ok(success) => log::info!("Loaded main settings file? {}", success),
|
||||
|
@ -395,7 +389,7 @@ impl ApiMessageHandler {
|
|||
true
|
||||
}
|
||||
ApiMessage::LoadSystemSettings => {
|
||||
settings.load_system_default(settings.general.get_name().to_owned());
|
||||
settings.load_system_default(settings.general.get_name().to_owned(), settings.general.get_variant_id(), settings.general.get_variant_name().to_owned());
|
||||
true
|
||||
}
|
||||
ApiMessage::GetLimits(cb) => {
|
||||
|
|
|
@ -5,6 +5,7 @@ pub const PACKAGE_VERSION: &'static str = env!("CARGO_PKG_VERSION");
|
|||
|
||||
pub const DEFAULT_SETTINGS_FILE: &str = "default_settings.json";
|
||||
pub const DEFAULT_SETTINGS_NAME: &str = "Main";
|
||||
pub const DEFAULT_SETTINGS_VARIANT_NAME: &str = "Primary";
|
||||
|
||||
pub const LIMITS_FILE: &str = "limits_cache.json";
|
||||
pub const LIMITS_OVERRIDE_FILE: &str = "limits_override.json";
|
||||
|
|
|
@ -75,12 +75,20 @@ fn main() -> Result<(), ()> {
|
|||
let _limits_handle = crate::settings::limits_worker_spawn();
|
||||
|
||||
let mut loaded_settings =
|
||||
persist::SettingsJson::open(utility::settings_dir().join(DEFAULT_SETTINGS_FILE))
|
||||
.map(|settings| settings::Settings::from_json(settings, DEFAULT_SETTINGS_FILE.into()))
|
||||
persist::FileJson::open(utility::settings_dir().join(DEFAULT_SETTINGS_FILE))
|
||||
.map(|mut file| file.variants.remove("0")
|
||||
.map(|settings| settings::Settings::from_json(DEFAULT_SETTINGS_NAME.into(), settings, DEFAULT_SETTINGS_FILE.into()))
|
||||
.unwrap_or_else(|| settings::Settings::system_default(
|
||||
DEFAULT_SETTINGS_FILE.into(),
|
||||
DEFAULT_SETTINGS_NAME.into(),
|
||||
0,
|
||||
DEFAULT_SETTINGS_VARIANT_NAME.into())))
|
||||
.unwrap_or_else(|_| {
|
||||
settings::Settings::system_default(
|
||||
DEFAULT_SETTINGS_FILE.into(),
|
||||
DEFAULT_SETTINGS_NAME.into(),
|
||||
0,
|
||||
DEFAULT_SETTINGS_VARIANT_NAME.into(),
|
||||
)
|
||||
});
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#[derive(Debug)]
|
||||
pub enum JsonError {
|
||||
Serde(serde_json::Error),
|
||||
pub enum SerdeError {
|
||||
Serde(RonError),
|
||||
Io(std::io::Error),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for JsonError {
|
||||
impl std::fmt::Display for SerdeError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Serde(e) => (e as &dyn std::fmt::Display).fmt(f),
|
||||
|
@ -12,3 +12,32 @@ impl std::fmt::Display for JsonError {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for SerdeError {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RonError {
|
||||
General(ron::error::Error),
|
||||
Spanned(ron::error::SpannedError),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for RonError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::General(e) => (e as &dyn std::fmt::Display).fmt(f),
|
||||
Self::Spanned(e) => (e as &dyn std::fmt::Display).fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ron::error::Error> for RonError {
|
||||
fn from(value: ron::error::Error) -> Self {
|
||||
Self::General(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ron::error::SpannedError> for RonError {
|
||||
fn from(value: ron::error::SpannedError) -> Self {
|
||||
Self::Spanned(value)
|
||||
}
|
||||
}
|
||||
|
|
62
backend/src/persist/file.rs
Normal file
62
backend/src/persist/file.rs
Normal file
|
@ -0,0 +1,62 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::SerdeError;
|
||||
use super::SettingsJson;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct FileJson {
|
||||
pub version: u64,
|
||||
pub name: String,
|
||||
pub variants: HashMap<String, SettingsJson>,
|
||||
}
|
||||
|
||||
impl FileJson {
|
||||
pub fn save<P: AsRef<std::path::Path>>(&self, path: P) -> Result<(), SerdeError> {
|
||||
let path = path.as_ref();
|
||||
|
||||
if !self.variants.is_empty() {
|
||||
if let Some(parent) = path.parent() {
|
||||
std::fs::create_dir_all(parent).map_err(SerdeError::Io)?;
|
||||
}
|
||||
let mut file = std::fs::File::create(path).map_err(SerdeError::Io)?;
|
||||
ron::ser::to_writer_pretty(&mut file, &self, crate::utility::ron_pretty_config()).map_err(|e| SerdeError::Serde(e.into()))
|
||||
} else {
|
||||
if path.exists() {
|
||||
// remove settings file when persistence is turned off, to prevent it from be loaded next time.
|
||||
std::fs::remove_file(path).map_err(SerdeError::Io)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open<P: AsRef<std::path::Path>>(path: P) -> Result<Self, SerdeError> {
|
||||
let mut file = std::fs::File::open(path).map_err(SerdeError::Io)?;
|
||||
ron::de::from_reader(&mut file).map_err(|e| SerdeError::Serde(e.into()))
|
||||
}
|
||||
|
||||
pub fn update_variant_or_create<P: AsRef<std::path::Path>>(path: P, setting: SettingsJson, given_name: String) -> Result<(), SerdeError> {
|
||||
if !setting.persistent {
|
||||
return Ok(())
|
||||
}
|
||||
let path = path.as_ref();
|
||||
|
||||
let file = if path.exists() {
|
||||
let mut file = Self::open(path)?;
|
||||
file.variants.insert(setting.variant.to_string(), setting);
|
||||
file
|
||||
} else {
|
||||
let mut setting_variants = HashMap::with_capacity(1);
|
||||
setting_variants.insert(setting.variant.to_string(), setting);
|
||||
Self {
|
||||
version: 0,
|
||||
name: given_name,
|
||||
variants: setting_variants,
|
||||
}
|
||||
};
|
||||
|
||||
file.save(path)
|
||||
}
|
||||
}
|
|
@ -2,38 +2,18 @@ use std::default::Default;
|
|||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::JsonError;
|
||||
use super::{BatteryJson, CpuJson, DriverJson, GpuJson};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct OnEventJson {
|
||||
pub on_save: Option<String>,
|
||||
pub on_load: Option<String>,
|
||||
pub on_set: Option<String>,
|
||||
pub on_resume: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for OnEventJson {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
on_save: None,
|
||||
on_load: None,
|
||||
on_set: None,
|
||||
on_resume: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct SettingsJson {
|
||||
pub version: u64,
|
||||
pub name: String,
|
||||
pub variant: u64,
|
||||
pub persistent: bool,
|
||||
pub cpus: Vec<CpuJson>,
|
||||
pub gpu: GpuJson,
|
||||
pub battery: BatteryJson,
|
||||
pub provider: Option<DriverJson>,
|
||||
pub events: Option<OnEventJson>,
|
||||
}
|
||||
|
||||
impl Default for SettingsJson {
|
||||
|
@ -41,42 +21,16 @@ impl Default for SettingsJson {
|
|||
Self {
|
||||
version: 0,
|
||||
name: crate::consts::DEFAULT_SETTINGS_NAME.to_owned(),
|
||||
variant: 0,
|
||||
persistent: false,
|
||||
cpus: Vec::with_capacity(8),
|
||||
gpu: GpuJson::default(),
|
||||
battery: BatteryJson::default(),
|
||||
provider: None,
|
||||
events: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SettingsJson {
|
||||
pub fn save<P: AsRef<std::path::Path>>(&self, path: P) -> Result<(), JsonError> {
|
||||
let path = path.as_ref();
|
||||
|
||||
if self.persistent {
|
||||
if let Some(parent) = path.parent() {
|
||||
std::fs::create_dir_all(parent).map_err(JsonError::Io)?;
|
||||
}
|
||||
let mut file = std::fs::File::create(path).map_err(JsonError::Io)?;
|
||||
serde_json::to_writer_pretty(&mut file, &self).map_err(JsonError::Serde)
|
||||
} else {
|
||||
if path.exists() {
|
||||
// remove settings file when persistence is turned off, to prevent it from be loaded next time.
|
||||
std::fs::remove_file(path).map_err(JsonError::Io)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open<P: AsRef<std::path::Path>>(path: P) -> Result<Self, JsonError> {
|
||||
let mut file = std::fs::File::open(path).map_err(JsonError::Io)?;
|
||||
serde_json::from_reader(&mut file).map_err(JsonError::Serde)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct MinMaxJson<T> {
|
||||
pub max: Option<T>,
|
||||
|
|
|
@ -2,13 +2,15 @@ mod battery;
|
|||
mod cpu;
|
||||
mod driver;
|
||||
mod error;
|
||||
mod file;
|
||||
mod general;
|
||||
mod gpu;
|
||||
|
||||
pub use battery::{BatteryEventJson, BatteryJson};
|
||||
pub use cpu::CpuJson;
|
||||
pub use driver::DriverJson;
|
||||
pub use general::{MinMaxJson, OnEventJson, SettingsJson};
|
||||
pub use file::FileJson;
|
||||
pub use general::{MinMaxJson, SettingsJson};
|
||||
pub use gpu::GpuJson;
|
||||
|
||||
pub use error::JsonError;
|
||||
pub use error::{SerdeError, RonError};
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::settings::{Driver, General, TBattery, TCpus, TGeneral, TGpu, Provider
|
|||
fn get_limits() -> limits_core::json_v2::Base {
|
||||
let limits_path = super::utility::limits_path();
|
||||
match File::open(&limits_path) {
|
||||
Ok(f) => match serde_json::from_reader(f) {
|
||||
Ok(f) => match ron::de::from_reader(f) {
|
||||
Ok(lim) => lim,
|
||||
Err(e) => {
|
||||
log::warn!(
|
||||
|
@ -35,7 +35,7 @@ fn get_limits() -> limits_core::json_v2::Base {
|
|||
fn get_limits_overrides() -> Option<Limits> {
|
||||
let limits_override_path = super::utility::limits_override_path();
|
||||
match File::open(&limits_override_path) {
|
||||
Ok(f) => match serde_json::from_reader(f) {
|
||||
Ok(f) => match ron::de::from_reader(f) {
|
||||
Ok(lim) => Some(lim),
|
||||
Err(e) => {
|
||||
log::warn!(
|
||||
|
@ -63,6 +63,8 @@ pub fn auto_detect_provider() -> DriverJson {
|
|||
None,
|
||||
crate::utility::settings_dir().join("autodetect.json"),
|
||||
"".to_owned(),
|
||||
0,
|
||||
crate::consts::DEFAULT_SETTINGS_VARIANT_NAME.to_owned(),
|
||||
)
|
||||
.battery
|
||||
.provider();
|
||||
|
@ -72,16 +74,19 @@ pub fn auto_detect_provider() -> DriverJson {
|
|||
|
||||
/// Device detection logic
|
||||
pub fn auto_detect0(
|
||||
settings_opt: Option<SettingsJson>,
|
||||
settings_opt: Option<&SettingsJson>,
|
||||
json_path: std::path::PathBuf,
|
||||
name: String,
|
||||
variant_id: u64,
|
||||
variant_name: String,
|
||||
) -> Driver {
|
||||
let mut general_driver = Box::new(General {
|
||||
persistent: false,
|
||||
path: json_path,
|
||||
name,
|
||||
variant_id,
|
||||
variant_name,
|
||||
driver: DriverJson::AutoDetect,
|
||||
events: Default::default(),
|
||||
});
|
||||
|
||||
let cpu_info: String = usdpl_back::api::files::read_single("/proc/cpuinfo").unwrap_or_default();
|
||||
|
|
|
@ -15,7 +15,7 @@ pub fn spawn() -> JoinHandle<()> {
|
|||
// try to load limits from file, fallback to built-in default
|
||||
let base = if limits_path.exists() {
|
||||
match std::fs::File::open(&limits_path) {
|
||||
Ok(f) => match serde_json::from_reader(f) {
|
||||
Ok(f) => match ron::de::from_reader(f) {
|
||||
Ok(b) => b,
|
||||
Err(e) => {
|
||||
log::error!("Cannot parse {}: {}", limits_path.display(), e);
|
||||
|
@ -72,7 +72,7 @@ pub fn get_limits_cached() -> Base {
|
|||
let limits_path = super::utility::limits_path();
|
||||
if limits_path.is_file() {
|
||||
match std::fs::File::open(&limits_path) {
|
||||
Ok(f) => match serde_json::from_reader(f) {
|
||||
Ok(f) => match ron::de::from_reader(f) {
|
||||
Ok(b) => b,
|
||||
Err(e) => {
|
||||
log::error!("Cannot parse {}: {}", limits_path.display(), e);
|
||||
|
@ -93,7 +93,7 @@ pub fn get_limits_cached() -> Base {
|
|||
fn save_base(new_base: &Base, path: impl AsRef<std::path::Path>) {
|
||||
let limits_path = path.as_ref();
|
||||
match std::fs::File::create(&limits_path) {
|
||||
Ok(f) => match serde_json::to_writer_pretty(f, &new_base) {
|
||||
Ok(f) => match ron::ser::to_writer_pretty(f, &new_base, crate::utility::ron_pretty_config()) {
|
||||
Ok(_) => log::info!("Successfully saved new limits to {}", limits_path.display()),
|
||||
Err(e) => log::error!(
|
||||
"Failed to save limits json to file `{}`: {}",
|
||||
|
|
|
@ -10,15 +10,17 @@ pub struct Driver {
|
|||
|
||||
impl Driver {
|
||||
pub fn init(
|
||||
settings: SettingsJson,
|
||||
name: String,
|
||||
settings: &SettingsJson,
|
||||
json_path: std::path::PathBuf,
|
||||
) -> Self {
|
||||
let name_bup = settings.name.clone();
|
||||
auto_detect0(Some(settings), json_path, name_bup)
|
||||
let id_bup = settings.variant;
|
||||
auto_detect0(Some(settings), json_path, name, id_bup, name_bup)
|
||||
}
|
||||
|
||||
pub fn system_default(json_path: std::path::PathBuf, name: String) -> Self {
|
||||
auto_detect0(None, json_path, name)
|
||||
pub fn system_default(json_path: std::path::PathBuf, name: String, variant_id: u64, variant_name: String) -> Self {
|
||||
auto_detect0(None, json_path, name, variant_id, variant_name)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::path::PathBuf;
|
|||
//use super::{Battery, Cpus, Gpu};
|
||||
use super::{OnResume, OnSet, SettingError};
|
||||
use super::{TBattery, TCpus, TGeneral, TGpu};
|
||||
use crate::persist::SettingsJson;
|
||||
use crate::persist::{SettingsJson, FileJson};
|
||||
//use crate::utility::unwrap_lock;
|
||||
|
||||
const LATEST_VERSION: u64 = 0;
|
||||
|
@ -33,44 +33,19 @@ pub struct General {
|
|||
pub persistent: bool,
|
||||
pub path: PathBuf,
|
||||
pub name: String,
|
||||
pub variant_id: u64,
|
||||
pub variant_name: String,
|
||||
pub driver: crate::persist::DriverJson,
|
||||
pub events: crate::persist::OnEventJson,
|
||||
}
|
||||
|
||||
impl OnSet for General {
|
||||
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
|
||||
if let Some(event) = &self.events.on_set {
|
||||
if !event.is_empty() {
|
||||
std::process::Command::new("/bin/bash")
|
||||
.args(&["-c", event])
|
||||
.spawn()
|
||||
.map_err(|e| {
|
||||
vec![SettingError {
|
||||
msg: format!("on_set event command error: {}", e),
|
||||
setting: SettingVariant::General,
|
||||
}]
|
||||
})?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl OnResume for General {
|
||||
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
|
||||
if let Some(event) = &self.events.on_resume {
|
||||
if !event.is_empty() {
|
||||
std::process::Command::new("/bin/bash")
|
||||
.args(&["-c", event])
|
||||
.spawn()
|
||||
.map_err(|e| {
|
||||
vec![SettingError {
|
||||
msg: format!("on_resume event command error: {}", e),
|
||||
setting: SettingVariant::General,
|
||||
}]
|
||||
})?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -106,12 +81,24 @@ impl TGeneral for General {
|
|||
self.name = name;
|
||||
}
|
||||
|
||||
fn provider(&self) -> crate::persist::DriverJson {
|
||||
self.driver.clone()
|
||||
fn get_variant_id(&self) -> u64 {
|
||||
self.variant_id
|
||||
}
|
||||
|
||||
fn on_event(&self) -> &crate::persist::OnEventJson {
|
||||
&self.events
|
||||
fn variant_id(&mut self, id: u64) {
|
||||
self.variant_id = id;
|
||||
}
|
||||
|
||||
fn get_variant_name(&self) -> &'_ str {
|
||||
&self.variant_name
|
||||
}
|
||||
|
||||
fn variant_name(&mut self, name: String) {
|
||||
self.variant_name = name;
|
||||
}
|
||||
|
||||
fn provider(&self) -> crate::persist::DriverJson {
|
||||
self.driver.clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,8 +142,8 @@ impl OnSet for Settings {
|
|||
|
||||
impl Settings {
|
||||
#[inline]
|
||||
pub fn from_json(other: SettingsJson, json_path: PathBuf) -> Self {
|
||||
let x = super::Driver::init(other, json_path.clone());
|
||||
pub fn from_json(name: String, other: SettingsJson, json_path: PathBuf) -> Self {
|
||||
let x = super::Driver::init(name, &other, json_path.clone());
|
||||
log::info!(
|
||||
"Loaded settings with drivers general:{:?},cpus:{:?},gpu:{:?},battery:{:?}",
|
||||
x.general.provider(),
|
||||
|
@ -172,8 +159,8 @@ impl Settings {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn system_default(json_path: PathBuf, name: String) -> Self {
|
||||
let driver = super::Driver::system_default(json_path, name);
|
||||
pub fn system_default(json_path: PathBuf, name: String, variant_id: u64, variant_name: String) -> Self {
|
||||
let driver = super::Driver::system_default(json_path, name, variant_id, variant_name);
|
||||
Self {
|
||||
general: driver.general,
|
||||
cpus: driver.cpus,
|
||||
|
@ -182,26 +169,40 @@ impl Settings {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn load_system_default(&mut self, name: String) {
|
||||
let driver = super::Driver::system_default(self.general.get_path().to_owned(), name);
|
||||
pub fn load_system_default(&mut self, name: String, variant_id: u64, variant_name: String) {
|
||||
let driver = super::Driver::system_default(self.general.get_path().to_owned(), name, variant_id, variant_name);
|
||||
self.cpus = driver.cpus;
|
||||
self.gpu = driver.gpu;
|
||||
self.battery = driver.battery;
|
||||
self.general = driver.general;
|
||||
}
|
||||
|
||||
pub fn get_variant<'a>(settings_file: &'a FileJson, variant_id: u64, variant_name: String) -> Result<&'a SettingsJson, SettingError> {
|
||||
if let Some(variant) = settings_file.variants.get(&variant_id.to_string()) {
|
||||
Ok(variant)
|
||||
} else {
|
||||
Err(SettingError {
|
||||
msg: format!("Cannot get non-existent variant `{}` (id:{})", variant_name, variant_id),
|
||||
setting: SettingVariant::General,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_file(
|
||||
&mut self,
|
||||
filename: PathBuf,
|
||||
name: String,
|
||||
variant: u64,
|
||||
variant_name: String,
|
||||
system_defaults: bool,
|
||||
) -> Result<bool, SettingError> {
|
||||
let json_path = crate::utility::settings_dir().join(&filename);
|
||||
if json_path.exists() {
|
||||
let settings_json = SettingsJson::open(&json_path).map_err(|e| SettingError {
|
||||
msg: e.to_string(),
|
||||
let file_json = FileJson::open(&json_path).map_err(|e| SettingError {
|
||||
msg: format!("Failed to open settings {}: {}", json_path.display(), e),
|
||||
setting: SettingVariant::General,
|
||||
})?;
|
||||
let settings_json = Self::get_variant(&file_json, variant, variant_name)?;
|
||||
if !settings_json.persistent {
|
||||
log::warn!(
|
||||
"Loaded persistent config `{}` ({}) with persistent=false",
|
||||
|
@ -211,7 +212,7 @@ impl Settings {
|
|||
*self.general.persistent() = false;
|
||||
self.general.name(name);
|
||||
} else {
|
||||
let x = super::Driver::init(settings_json, json_path.clone());
|
||||
let x = super::Driver::init(name, settings_json, json_path.clone());
|
||||
log::info!("Loaded settings with drivers general:{:?},cpus:{:?},gpu:{:?},battery:{:?}", x.general.provider(), x.cpus.provider(), x.gpu.provider(), x.battery.provider());
|
||||
self.general = x.general;
|
||||
self.cpus = x.cpus;
|
||||
|
@ -220,24 +221,15 @@ impl Settings {
|
|||
}
|
||||
} else {
|
||||
if system_defaults {
|
||||
self.load_system_default(name);
|
||||
self.load_system_default(name, variant, variant_name);
|
||||
} else {
|
||||
self.general.name(name);
|
||||
self.general.variant_name(variant_name);
|
||||
}
|
||||
*self.general.persistent() = false;
|
||||
}
|
||||
self.general.path(filename);
|
||||
if let Some(event) = &self.general.on_event().on_load {
|
||||
if !event.is_empty() {
|
||||
std::process::Command::new("/bin/bash")
|
||||
.args(&["-c", event])
|
||||
.spawn()
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("on_save event command error: {}", e),
|
||||
setting: SettingVariant::General,
|
||||
})?;
|
||||
}
|
||||
}
|
||||
self.general.variant_id(variant);
|
||||
Ok(*self.general.persistent())
|
||||
}
|
||||
|
||||
|
@ -275,13 +267,13 @@ impl Settings {
|
|||
pub fn json(&self) -> SettingsJson {
|
||||
SettingsJson {
|
||||
version: LATEST_VERSION,
|
||||
name: self.general.get_name().to_owned(),
|
||||
name: self.general.get_variant_name().to_owned(),
|
||||
variant: self.general.get_variant_id(),
|
||||
persistent: self.general.get_persistent(),
|
||||
cpus: self.cpus.json(),
|
||||
gpu: self.gpu.json(),
|
||||
battery: self.battery.json(),
|
||||
provider: Some(self.general.provider()),
|
||||
events: Some(self.general.on_event().clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,9 +109,15 @@ pub trait TGeneral: OnSet + OnResume + OnPowerEvent + Debug + Send {
|
|||
|
||||
fn name(&mut self, name: String);
|
||||
|
||||
fn provider(&self) -> crate::persist::DriverJson;
|
||||
fn get_variant_id(&self) -> u64;
|
||||
|
||||
fn on_event(&self) -> &'_ crate::persist::OnEventJson;
|
||||
fn variant_id(&mut self, id: u64);
|
||||
|
||||
fn get_variant_name(&self) -> &'_ str;
|
||||
|
||||
fn variant_name(&mut self, name: String);
|
||||
|
||||
fn provider(&self) -> crate::persist::DriverJson;
|
||||
}
|
||||
|
||||
pub trait TBattery: OnSet + OnResume + OnPowerEvent + Debug + Send {
|
||||
|
|
|
@ -1,19 +1,8 @@
|
|||
use std::fmt::Display;
|
||||
//use std::sync::{LockResult, MutexGuard};
|
||||
//use std::fs::{Permissions, metadata};
|
||||
use std::io::{Read, Write};
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
pub fn unwrap_maybe_fatal<T: Sized, E: Display>(result: Result<T, E>, message: &str) -> T {
|
||||
match result {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
log::error!("{}: {}", message, e);
|
||||
panic!("{}: {}", message, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*pub fn unwrap_lock<'a, T: Sized>(
|
||||
result: LockResult<MutexGuard<'a, T>>,
|
||||
lock_name: &str,
|
||||
|
@ -27,6 +16,12 @@ pub fn unwrap_maybe_fatal<T: Sized, E: Display>(result: Result<T, E>, message: &
|
|||
}
|
||||
}*/
|
||||
|
||||
pub fn ron_pretty_config() -> ron::ser::PrettyConfig {
|
||||
ron::ser::PrettyConfig::default()
|
||||
.struct_names(true)
|
||||
.compact_arrays(true)
|
||||
}
|
||||
|
||||
pub fn settings_dir() -> std::path::PathBuf {
|
||||
usdpl_back::api::dirs::home()
|
||||
.unwrap_or_else(|| "/tmp/".into())
|
||||
|
|
|
@ -247,8 +247,13 @@ export async function getGeneralPersistent(): Promise<boolean> {
|
|||
return (await call_backend("GENERAL_get_persistent", []))[0];
|
||||
}
|
||||
|
||||
export async function loadGeneralSettings(id: string, name: string): Promise<boolean> {
|
||||
return (await call_backend("GENERAL_load_settings", [id, name]))[0];
|
||||
export async function loadGeneralSettings(id: string, name: string, variant_id: number, variant_name: string | undefined): Promise<boolean> {
|
||||
if (variant_name) {
|
||||
return (await call_backend("GENERAL_load_settings", [id, name, variant_id, variant_name]))[0];
|
||||
} else {
|
||||
return (await call_backend("GENERAL_load_settings", [id, name, variant_id]))[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export async function loadGeneralDefaultSettings(): Promise<boolean> {
|
||||
|
|
|
@ -191,7 +191,7 @@ const reload = function() {
|
|||
backend.log(backend.LogLevel.Info, "RegisterForGameActionStart callback(" + actionType + ", " + id + ")");
|
||||
// don't use gameInfo.appid, haha
|
||||
backend.resolve(
|
||||
backend.loadGeneralSettings(id.toString(), gameInfo.display_name),
|
||||
backend.loadGeneralSettings(id.toString(), gameInfo.display_name, 0, undefined),
|
||||
(ok: boolean) => {backend.log(backend.LogLevel.Debug, "Loading settings ok? " + ok)}
|
||||
);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue