Add multi-profile per-game functionality for #82, change to JSON to RON format

This commit is contained in:
NGnius (Graham) 2023-11-18 15:17:56 -05:00
parent a90932d813
commit 3aa9680bae
18 changed files with 253 additions and 159 deletions

26
backend/Cargo.lock generated
View file

@ -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"

View file

@ -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

View file

@ -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()]

View file

@ -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) => {

View file

@ -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";

View file

@ -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(),
)
});

View file

@ -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)
}
}

View 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)
}
}

View file

@ -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>,

View file

@ -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};

View file

@ -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();

View file

@ -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 `{}`: {}",

View 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)
}
}

View file

@ -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()),
}
}
}

View file

@ -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 {

View file

@ -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())

View file

@ -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> {

View file

@ -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)}
);
});