Skip to content

Commit

Permalink
Merge pull request #55 from Berrysoft/dev/dcp-settings
Browse files Browse the repository at this point in the history
Decouple settings manager from runtime.
  • Loading branch information
Berrysoft authored Dec 10, 2022
2 parents 5263868 + fcba640 commit c79c3cd
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 95 deletions.
2 changes: 1 addition & 1 deletion bins/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions bins/ayaka-gui/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ actix-web = "4"
actix-files = "0.6"
actix-cors = "0.6"
trylog = "0.3"
tryiterator = { git = "https://github.com/Pernosco/tryiterator.git" }

[features]
default = [ "custom-protocol" ]
Expand Down
44 changes: 24 additions & 20 deletions bins/ayaka-gui/src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,28 @@
windows_subsystem = "windows"
)]
#![feature(once_cell)]
#![feature(type_alias_impl_trait)]

mod asset_resolver;
mod settings;

use ayaka_runtime::{
anyhow::{self, Result},
log::{debug, info},
settings::*,
*,
};
use flexi_logger::{FileSpec, LogSpecification, Logger};
use serde::{Deserialize, Serialize};
use settings::*;
use std::{
collections::{HashMap, HashSet},
fmt::Display,
net::TcpListener,
};
use tauri::{
async_runtime::Mutex, command, utils::config::AppUrl, AppHandle, Manager, State, WindowUrl,
async_runtime::Mutex, command, utils::config::AppUrl, AppHandle, Manager, PathResolver, State,
WindowUrl,
};
use trylog::macros::*;

Expand Down Expand Up @@ -72,9 +77,9 @@ impl OpenGameStatus {

#[derive(Default)]
struct Storage {
ident: String,
config: String,
dist_port: u16,
manager: FileSettingsManager,
records: Mutex<Vec<ActionRecord>>,
context: Mutex<Option<Context>>,
current: Mutex<Option<RawContext>>,
Expand All @@ -83,11 +88,11 @@ struct Storage {
}

impl Storage {
pub fn new(ident: impl Into<String>, config: impl Into<String>, dist_port: u16) -> Self {
pub fn new(resolver: &PathResolver, config: impl Into<String>, dist_port: u16) -> Self {
Self {
ident: ident.into(),
config: config.into(),
dist_port,
manager: FileSettingsManager::new(resolver),
..Default::default()
}
}
Expand Down Expand Up @@ -140,20 +145,20 @@ async fn open_game(handle: AppHandle, storage: State<'_, Storage>) -> CommandRes
window.set_title(&ctx.game.config.title)?;
let settings = {
OpenGameStatus::LoadSettings.emit(&handle)?;
unwrap_or_default_log!(load_settings(&storage.ident), "Load settings failed")
unwrap_or_default_log!(storage.manager.load_settings(), "Load settings failed")
};
*storage.settings.lock().await = Some(settings);

OpenGameStatus::LoadGlobalRecords.emit(&handle)?;
let global_record = unwrap_or_default_log!(
load_global_record(&storage.ident, &ctx.game.config.title),
storage.manager.load_global_record(&ctx.game.config.title),
"Load global records failed"
);
*storage.global_record.lock().await = Some(global_record);

OpenGameStatus::LoadRecords.emit(&handle)?;
*storage.records.lock().await = unwrap_or_default_log!(
load_records(&storage.ident, &ctx.game.config.title),
storage.manager.load_records(&ctx.game.config.title),
"Load records failed"
);
*storage.context.lock().await = Some(ctx);
Expand Down Expand Up @@ -215,16 +220,15 @@ async fn save_record_to(index: usize, storage: State<'_, Storage>) -> CommandRes
async fn save_all(storage: State<'_, Storage>) -> CommandResult<()> {
let context = storage.context.lock().await;
let game = &context.as_ref().unwrap().game.config.title;
save_settings(
&storage.ident,
storage.settings.lock().await.as_ref().unwrap(),
)?;
save_global_record(
&storage.ident,
game,
storage.global_record.lock().await.as_ref().unwrap(),
)?;
save_records(&storage.ident, game, &storage.records.lock().await)?;
storage
.manager
.save_settings(storage.settings.lock().await.as_ref().unwrap())?;
storage
.manager
.save_global_record(game, storage.global_record.lock().await.as_ref().unwrap())?;
storage
.manager
.save_records(game, &storage.records.lock().await)?;
Ok(())
}

Expand Down Expand Up @@ -433,7 +437,7 @@ fn main() -> Result<()> {
.plugin(asset_resolver::init(listener))
.plugin(tauri_plugin_window_state::Builder::default().build())
.setup(move |app| {
let ident = app.config().tauri.bundle.identifier.clone();
let resolver = app.path_resolver();
let spec = LogSpecification::parse("warn,ayaka=debug")?;
let log_handle = if cfg!(debug_assertions) {
Logger::with(spec)
Expand All @@ -445,7 +449,7 @@ fn main() -> Result<()> {
Logger::with(spec)
.log_to_file(
FileSpec::default()
.directory(app.path_resolver().app_log_dir().unwrap())
.directory(resolver.app_log_dir().unwrap())
.basename("ayaka-gui"),
)
.use_utc()
Expand Down Expand Up @@ -477,7 +481,7 @@ fn main() -> Result<()> {
.unwrap()
.to_path_buf();
asset_resolver::ROOT_PATH.set(root_path).unwrap();
app.manage(Storage::new(ident, config, port));
app.manage(Storage::new(&resolver, config, port));
Ok(())
})
.invoke_handler(tauri::generate_handler![
Expand Down
84 changes: 84 additions & 0 deletions bins/ayaka-gui/src-tauri/src/settings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use ayaka_runtime::{
anyhow::{self, Result},
settings::*,
};
use serde::{de::DeserializeOwned, Serialize};
use std::path::{Path, PathBuf};
use tauri::PathResolver;
use tryiterator::TryIteratorExt;

#[derive(Default)]
pub struct FileSettingsManager {
local_data_dir: PathBuf,
config_dir: PathBuf,
}

impl FileSettingsManager {
pub fn new(resolver: &PathResolver) -> Self {
Self {
local_data_dir: resolver.app_local_data_dir().unwrap(),
config_dir: resolver.app_config_dir().unwrap(),
}
}

fn records_path_root(&self, game: &str) -> PathBuf {
self.local_data_dir.join("save").join(game)
}
}

impl SettingsManager for FileSettingsManager {
fn load_file<T: DeserializeOwned>(&self, path: impl AsRef<Path>) -> Result<T> {
let buffer = std::fs::read(path)?;
Ok(serde_json::from_slice(&buffer)?)
}

fn save_file<T: Serialize>(
&self,
path: impl AsRef<Path>,
data: &T,
pretty: bool,
) -> Result<()> {
let path = path.as_ref();
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
let buffer = if pretty {
serde_json::to_vec_pretty(data)
} else {
serde_json::to_vec(data)
}?;
std::fs::write(path, buffer)?;
Ok(())
}

fn settings_path(&self) -> Result<PathBuf> {
Ok(self.config_dir.join("settings.json"))
}

fn global_record_path(&self, game: &str) -> Result<PathBuf> {
Ok(self.records_path_root(game).join("global.json"))
}

type RecordsPathIter = impl Iterator<Item = Result<PathBuf>>;

fn records_path(&self, game: &str) -> Result<Self::RecordsPathIter> {
let ctx_path = self.records_path_root(game);
Ok(std::fs::read_dir(ctx_path)?
.map_err(anyhow::Error::from)
.try_filter_map(|entry| {
let p = entry.path();
if p.is_file() && p.file_name().unwrap_or_default() != "global.json" {
Ok(Some(p))
} else {
Ok(None)
}
}))
}

fn record_path(&self, game: &str, i: usize) -> Result<PathBuf> {
Ok(self
.records_path_root(game)
.join(i.to_string())
.with_extension("json"))
}
}
1 change: 0 additions & 1 deletion utils/ayaka-runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ anyhow = { workspace = true }
stream-future = "0.3"
futures-util = "0.3"
tryiterator = { git = "https://github.com/Pernosco/tryiterator.git" }
dirs = "4.0"
log = { workspace = true }
trylog = { workspace = true }
cfg-if = "1.0"
Expand Down
1 change: 1 addition & 0 deletions utils/ayaka-runtime/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
plugin::{LoadStatus, Runtime},
settings::*,
*,
};
use anyhow::{anyhow, bail, Result};
Expand Down
3 changes: 1 addition & 2 deletions utils/ayaka-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ mod config;
mod context;
mod locale;
pub mod plugin;
mod settings;
pub mod settings;

#[doc(no_inline)]
pub use anyhow;
Expand All @@ -29,7 +29,6 @@ pub use futures_util::{pin_mut, StreamExt, TryStreamExt};
pub use locale::*;
#[doc(no_inline)]
pub use log;
pub use settings::*;

/// Get the version of Ayaka runtime.
/// This version string is exacted from `CARGO_PKG_VERSION`.
Expand Down
Loading

0 comments on commit c79c3cd

Please sign in to comment.