mirror of
https://github.com/an-anime-team/an-anime-game-launcher.git
synced 2025-02-16 15:22:01 +03:00
Added hot config system, fixed gamemode option
This commit is contained in:
parent
a6667f73d4
commit
737aa7e8bc
6 changed files with 69 additions and 16 deletions
|
@ -14,7 +14,7 @@ gtk4 = "0.4"
|
|||
gtk4 = "0.4"
|
||||
libadwaita = "0.1"
|
||||
|
||||
anime-game-core = { path = "anime-game-core", features = ["all"] }
|
||||
anime-game-core = { path = "anime-game-core", features = ["all", "static"] }
|
||||
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
|
|
@ -19,7 +19,26 @@ pub use hud::HUD;
|
|||
pub use wine_sync::WineSync;
|
||||
pub use wine_lang::WineLang;
|
||||
|
||||
static mut CONFIG: Option<Config> = None;
|
||||
|
||||
/// Get config data
|
||||
///
|
||||
/// This method will load config from file once and store it into the memory.
|
||||
/// If you know that the config file was updated - you should run `get_raw` method
|
||||
/// that always loads config directly from the file. This will also update in-memory config
|
||||
pub fn get() -> Result<Config, Error> {
|
||||
unsafe {
|
||||
match &CONFIG {
|
||||
Some(config) => Ok(config.clone()),
|
||||
None => get_raw()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get config data
|
||||
///
|
||||
/// This method will always load data directly from the file and update in-memory config
|
||||
pub fn get_raw() -> Result<Config, Error> {
|
||||
match config_file() {
|
||||
Some(path) => {
|
||||
// Try to read config if the file exists
|
||||
|
@ -30,14 +49,20 @@ pub fn get() -> Result<Config, Error> {
|
|||
file.read_to_string(&mut json)?;
|
||||
|
||||
match serde_json::from_str::<Config>(&json) {
|
||||
Ok(json) => Ok(json),
|
||||
Ok(config) => {
|
||||
unsafe {
|
||||
CONFIG = Some(config.clone());
|
||||
}
|
||||
|
||||
Ok(config)
|
||||
},
|
||||
Err(err) => Err(Error::new(ErrorKind::InvalidData, format!("Failed to decode data from json format: {}", err.to_string())))
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise create default config file
|
||||
else {
|
||||
update(Config::default())?;
|
||||
update_raw(Config::default())?;
|
||||
|
||||
Ok(Config::default())
|
||||
}
|
||||
|
@ -46,7 +71,21 @@ pub fn get() -> Result<Config, Error> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update(config: Config) -> Result<(), Error> {
|
||||
/// Update in-memory config data
|
||||
///
|
||||
/// Use `update_raw` if you want to update config file itself
|
||||
pub fn update(config: Config) {
|
||||
unsafe {
|
||||
CONFIG = Some(config);
|
||||
}
|
||||
}
|
||||
|
||||
/// Update config file
|
||||
///
|
||||
/// This method will also update in-memory config data
|
||||
pub fn update_raw(config: Config) -> Result<(), Error> {
|
||||
update(config.clone());
|
||||
|
||||
match config_file() {
|
||||
Some(path) => {
|
||||
let mut file = File::create(&path)?;
|
||||
|
@ -64,6 +103,16 @@ pub fn update(config: Config) -> Result<(), Error> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Update config file from the in-memory saved config
|
||||
pub fn flush() -> Result<(), Error> {
|
||||
unsafe {
|
||||
match &CONFIG {
|
||||
Some(config) => update_raw(config.clone()),
|
||||
None => Err(Error::new(ErrorKind::Other, "Config wasn't loaded into the memory"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct Config {
|
||||
pub launcher: Launcher,
|
||||
|
|
|
@ -42,6 +42,11 @@ async fn main() {
|
|||
main.show();
|
||||
});
|
||||
|
||||
// Flush config from the memory to the file before closing the app
|
||||
application.connect_shutdown(|_| {
|
||||
lib::config::flush().expect("Failed to save config data");
|
||||
});
|
||||
|
||||
// Run app
|
||||
application.run();
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ pub enum Actions {
|
|||
|
||||
impl Actions {
|
||||
pub fn into_fn<T: gtk::glib::IsA<gtk::Widget>>(&self, app: &App) -> Box<dyn Fn(&T)> {
|
||||
Box::new(clone!(@strong self as action, @strong app => move |_| {
|
||||
Box::new(clone!(@strong self as action, @weak app => move |_| {
|
||||
app.update(action.clone()).expect(&format!("Failed to execute action {:?}", &action));
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -154,8 +154,7 @@ impl App {
|
|||
match action {
|
||||
Actions::OptionSelection(update, value) => {
|
||||
if let Ok(config) = config::get() {
|
||||
// TODO: show toast
|
||||
config::update((update)(config, value)).unwrap();
|
||||
config::update((update)(config, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -193,7 +192,7 @@ impl App {
|
|||
self.widgets.fsr_switcher.set_state(config.game.enhancements.fsr.enabled);
|
||||
|
||||
// Gamemode switching
|
||||
self.widgets.fsr_switcher.set_state(config.game.enhancements.gamemode);
|
||||
self.widgets.gamemode_switcher.set_state(config.game.enhancements.gamemode);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ pub enum Actions {
|
|||
|
||||
impl Actions {
|
||||
pub fn into_fn<T: gtk::glib::IsA<gtk::Widget>>(&self, app: &App) -> Box<dyn Fn(&T)> {
|
||||
Box::new(clone!(@strong self as action, @strong app => move |_| {
|
||||
Box::new(clone!(@strong self as action, @weak app => move |_| {
|
||||
app.update(action.clone()).expect(&format!("Failed to execute action {:?}", &action));
|
||||
}))
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ impl App {
|
|||
|
||||
/// Add default events and values to the widgets
|
||||
fn init_events(self) -> Self {
|
||||
self.widgets.wine_selected.connect_selected_notify(clone!(@strong self as this => move |combo_row| {
|
||||
self.widgets.wine_selected.connect_selected_notify(clone!(@weak self as this => move |combo_row| {
|
||||
if let Some(model) = combo_row.model() {
|
||||
if model.n_items() > 0 {
|
||||
this.update(Actions::SelectWineVersion(Rc::new(combo_row.selected() as usize))).unwrap();
|
||||
|
@ -207,7 +207,7 @@ impl App {
|
|||
}
|
||||
}));
|
||||
|
||||
self.widgets.dxvk_selected.connect_selected_notify(clone!(@strong self as this => move |combo_row| {
|
||||
self.widgets.dxvk_selected.connect_selected_notify(clone!(@weak self as this => move |combo_row| {
|
||||
if let Some(model) = combo_row.model() {
|
||||
if model.n_items() > 0 {
|
||||
this.update(Actions::SelectDxvkVersion(Rc::new(combo_row.selected() as usize))).unwrap();
|
||||
|
@ -216,7 +216,7 @@ impl App {
|
|||
}));
|
||||
|
||||
// Set wine recommended only switcher event
|
||||
self.widgets.wine_recommended_only.connect_state_notify(clone!(@strong self as this => move |switcher| {
|
||||
self.widgets.wine_recommended_only.connect_state_notify(clone!(@weak self as this => move |switcher| {
|
||||
for group in &*this.widgets.wine_components {
|
||||
for component in &group.version_components {
|
||||
component.row.set_visible(if switcher.state() {
|
||||
|
@ -238,7 +238,7 @@ impl App {
|
|||
}
|
||||
|
||||
// Set DXVK recommended only switcher event
|
||||
self.widgets.dxvk_recommended_only.connect_state_notify(clone!(@strong self as this => move |switcher| {
|
||||
self.widgets.dxvk_recommended_only.connect_state_notify(clone!(@weak self as this => move |switcher| {
|
||||
for component in &*this.widgets.dxvk_components {
|
||||
component.row.set_visible(if switcher.state() {
|
||||
component.version.recommended
|
||||
|
@ -254,7 +254,7 @@ impl App {
|
|||
for (i, component) in components.into_iter().enumerate() {
|
||||
component.button.connect_clicked(Actions::DxvkPerformAction(Rc::new(i)).into_fn(&self));
|
||||
|
||||
component.apply_button.connect_clicked(clone!(@strong component, @strong self as this => move |_| {
|
||||
component.apply_button.connect_clicked(clone!(@strong component, @weak self as this => move |_| {
|
||||
std::thread::spawn(clone!(@strong component, @strong this => move || {
|
||||
let config = config::get().expect("Failed to load config");
|
||||
|
||||
|
@ -400,7 +400,7 @@ impl App {
|
|||
|
||||
this.values.set(values);
|
||||
|
||||
config::update(config).expect("Failed to update config");
|
||||
config::update(config);
|
||||
}
|
||||
|
||||
Actions::UpdateWineComboRow => {
|
||||
|
@ -446,7 +446,7 @@ impl App {
|
|||
|
||||
this.values.set(values);
|
||||
|
||||
config::update(config).expect("Failed to update config");
|
||||
config::update(config);
|
||||
}
|
||||
|
||||
Actions::ToastError(toast) => {
|
||||
|
|
Loading…
Add table
Reference in a new issue