named config trait

This commit is contained in:
Alex Janka 2023-10-30 14:15:47 +11:00
parent 1c313530e9
commit 59ee750d26
4 changed files with 45 additions and 21 deletions

View file

@ -137,7 +137,7 @@ fn main() {
) )
.ok(), .ok(),
ConfigType::Standalone => config_manager ConfigType::Standalone => config_manager
.load_custom_config::<gb_emu::StandaloneConfig>(gb_emu::CONFIG_NAME) .load_custom_config::<gb_emu::StandaloneConfig>()
.and_then(|v| ConfigManager::get_custom_config_string(v).ok()), .and_then(|v| ConfigManager::get_custom_config_string(v).ok()),
} }
} else { } else {

View file

@ -4,7 +4,7 @@
use camera::Webcam; use camera::Webcam;
use debug::Debugger; use debug::Debugger;
use gb_emu_lib::{ use gb_emu_lib::{
config::ConfigManager, config::{ConfigManager, NamedConfig},
connect::{ connect::{
CgbRomType, EmulatorCoreTrait, EmulatorMessage, EmulatorOptions, NoCamera, RomFile, CgbRomType, EmulatorCoreTrait, EmulatorMessage, EmulatorOptions, NoCamera, RomFile,
SerialTarget, SramType, SerialTarget, SramType,
@ -39,6 +39,12 @@ pub struct StandaloneConfig {
output_buffer_size: u32, output_buffer_size: u32,
} }
impl NamedConfig for StandaloneConfig {
fn name() -> String {
String::from("standalone")
}
}
impl Default for StandaloneConfig { impl Default for StandaloneConfig {
fn default() -> Self { fn default() -> Self {
Self { Self {
@ -59,7 +65,6 @@ struct Configs {
} }
static CONFIGS: OnceLock<Configs> = OnceLock::new(); static CONFIGS: OnceLock<Configs> = OnceLock::new();
pub const CONFIG_NAME: &str = "standalone";
fn access_config<'a>() -> &'a Configs { fn access_config<'a>() -> &'a Configs {
CONFIGS.get().expect("accessed config before it was set!") CONFIGS.get().expect("accessed config before it was set!")
@ -89,7 +94,7 @@ pub fn run(options: RunOptions) -> ! {
let config_manager = ConfigManager::get().expect("Could not open config folder"); let config_manager = ConfigManager::get().expect("Could not open config folder");
let config = config_manager.load_or_create_base_config(); let config = config_manager.load_or_create_base_config();
let standalone_config: StandaloneConfig = config_manager.load_or_create_config(CONFIG_NAME); let standalone_config: StandaloneConfig = config_manager.load_or_create_config();
let rom_file = RomFile::Path(options.rom); let rom_file = RomFile::Path(options.rom);

View file

@ -2,7 +2,7 @@ use async_ringbuf::AsyncHeapConsumer;
use baseview::Size; use baseview::Size;
use futures::executor; use futures::executor;
use gb_emu_lib::{ use gb_emu_lib::{
config::ConfigManager, config::{ConfigManager, NamedConfig},
connect::{ connect::{
AudioOutput, CgbRomType, DownsampleType, EmulatorCoreTrait, EmulatorMessage, AudioOutput, CgbRomType, DownsampleType, EmulatorCoreTrait, EmulatorMessage,
EmulatorOptions, NoCamera, RendererMessage, RomFile, SerialTarget, EmulatorOptions, NoCamera, RendererMessage, RomFile, SerialTarget,
@ -69,6 +69,12 @@ pub struct VstConfig {
force_skip_bootrom: bool, force_skip_bootrom: bool,
} }
impl NamedConfig for VstConfig {
fn name() -> String {
String::from("vst")
}
}
impl Default for VstConfig { impl Default for VstConfig {
fn default() -> Self { fn default() -> Self {
Self { Self {
@ -92,7 +98,7 @@ fn access_config<'a>() -> &'a Configs {
CONFIGS.get_or_init(|| { CONFIGS.get_or_init(|| {
let config_manager = ConfigManager::get().expect("Could not open config folder"); let config_manager = ConfigManager::get().expect("Could not open config folder");
let emu_config = config_manager.load_or_create_base_config(); let emu_config = config_manager.load_or_create_base_config();
let vst_config = config_manager.load_or_create_config::<VstConfig>("vst"); let vst_config: VstConfig = config_manager.load_or_create_config();
Configs { Configs {
vst_config, vst_config,

View file

@ -6,6 +6,10 @@ use std::{
use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde::{de::DeserializeOwned, Deserialize, Serialize};
pub trait NamedConfig {
fn name() -> String;
}
pub struct ConfigManager { pub struct ConfigManager {
path: PathBuf, path: PathBuf,
} }
@ -27,26 +31,29 @@ impl ConfigManager {
} }
pub fn load_or_create_base_config(&self) -> Config { pub fn load_or_create_base_config(&self) -> Config {
self.load_or_create_config("base") self.load_or_create_config()
} }
pub fn load_or_create_config<C>(&self, name: &str) -> C pub fn load_or_create_config<C>(&self) -> C
where where
C: Serialize + DeserializeOwned + Default + Clone, C: NamedConfig + Serialize + DeserializeOwned + Default + Clone,
{ {
match self.load_custom_config::<C>(name) { match self.load_custom_config::<C>() {
Some(v) => { Some(v) => {
let _ = self.save_custom_config(name, v.clone()); let _ = self.save_custom_config(v.clone());
v v
} }
None => { None => {
let config = C::default(); let config = C::default();
if let Ok(true) = self.path.join(name).try_exists() { if let Ok(true) = self.path.join(C::name()).try_exists() {
eprintln!("Failed to load \"{name}\" config, but it exists on disk"); eprintln!(
"Failed to load \"{}\" config, but it exists on disk",
C::name()
);
} else { } else {
let result = self.save_custom_config(name, config.clone()); let result = self.save_custom_config(config.clone());
if let Err(e) = result { if let Err(e) = result {
eprintln!("Failed to save \"{name}\" config: {e:#?}"); eprintln!("Failed to save \"{}\" config: {e:#?}", C::name());
} }
} }
config config
@ -54,19 +61,19 @@ impl ConfigManager {
} }
} }
pub fn load_custom_config<C>(&self, name: &str) -> Option<C> pub fn load_custom_config<C>(&self) -> Option<C>
where where
C: DeserializeOwned + Default, C: NamedConfig + DeserializeOwned + Default,
{ {
let path = self.path.join(name); let path = self.path.join(C::name());
ron::de::from_reader(BufReader::new(fs::File::open(path).ok()?)).ok() ron::de::from_reader(BufReader::new(fs::File::open(path).ok()?)).ok()
} }
pub fn save_custom_config<C>(&self, name: &str, config: C) -> Result<(), ron::Error> pub fn save_custom_config<C>(&self, config: C) -> Result<(), ron::Error>
where where
C: Serialize, C: NamedConfig + Serialize,
{ {
let path = self.path.join(name); let path = self.path.join(C::name());
ron::ser::to_writer_pretty( ron::ser::to_writer_pretty(
BufWriter::new(fs::File::create(path)?), BufWriter::new(fs::File::create(path)?),
&config, &config,
@ -92,6 +99,12 @@ pub struct Config {
pub vulkan_config: VulkanRendererConfig, pub vulkan_config: VulkanRendererConfig,
} }
impl NamedConfig for Config {
fn name() -> String {
String::from("base")
}
}
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(default)] #[serde(default)]
pub struct VulkanRendererConfig { pub struct VulkanRendererConfig {