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

View file

@ -4,7 +4,7 @@
use camera::Webcam;
use debug::Debugger;
use gb_emu_lib::{
config::ConfigManager,
config::{ConfigManager, NamedConfig},
connect::{
CgbRomType, EmulatorCoreTrait, EmulatorMessage, EmulatorOptions, NoCamera, RomFile,
SerialTarget, SramType,
@ -39,6 +39,12 @@ pub struct StandaloneConfig {
output_buffer_size: u32,
}
impl NamedConfig for StandaloneConfig {
fn name() -> String {
String::from("standalone")
}
}
impl Default for StandaloneConfig {
fn default() -> Self {
Self {
@ -59,7 +65,6 @@ struct Configs {
}
static CONFIGS: OnceLock<Configs> = OnceLock::new();
pub const CONFIG_NAME: &str = "standalone";
fn access_config<'a>() -> &'a Configs {
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 = 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);

View file

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

View file

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