rust-rl/src/config/mod.rs
2024-06-15 17:24:37 +01:00

140 lines
4.3 KiB
Rust

use bracket_lib::prelude::*;
use toml::Value;
use serde::{ Serialize, Deserialize };
lazy_static! {
pub static ref CONFIG: Config = try_load_configuration();
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Config {
pub logging: LogConfig,
pub visuals: VisualConfig,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct LogConfig {
pub show_mapgen: bool,
pub log_combat: bool,
pub log_spawning: bool,
pub log_ticks: bool,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct VisualConfig {
pub with_scanlines: bool,
pub with_screen_burn: bool,
pub with_darken_by_distance: bool,
pub use_bitset_walls: bool,
pub use_coloured_tile_bg: bool,
pub add_colour_variance: bool,
}
impl Default for Config {
fn default() -> Self {
Config {
logging: LogConfig {
show_mapgen: false,
log_combat: false,
log_spawning: false,
log_ticks: false,
},
visuals: VisualConfig {
with_scanlines: false,
with_screen_burn: false,
with_darken_by_distance: true,
use_bitset_walls: true,
use_coloured_tile_bg: true,
add_colour_variance: true,
},
}
}
}
impl Config {
pub fn load_from_file(filename: &str) -> Config {
if let Ok(contents) = std::fs::read_to_string(filename) {
let parsed_config: Result<Value, _> = toml::from_str(&contents);
if let Ok(parsed_config) = parsed_config {
let mut config = Config::default();
let mut requires_write = false;
requires_write |= config.logging.apply_values(&parsed_config);
requires_write |= config.visuals.apply_values(&parsed_config);
if requires_write {
if let Err(write_err) = config.save_to_file(filename) {
console::log(format!("Error writing config: {:?}", write_err));
}
}
return config;
}
}
let config = Config::default();
if let Err(write_err) = config.save_to_file(filename) {
console::log(format!("Error writing config: {:?}", write_err));
}
return config;
}
pub fn save_to_file(&self, filename: &str) -> Result<(), Box<dyn std::error::Error>> {
let toml_string = toml::to_string(self)?;
std::fs::write(filename, toml_string)?;
Ok(())
}
}
macro_rules! apply_bool_value {
($config:expr, $parsed_config:expr, $changed:expr, $field:ident) => {
if let Some(value) = $parsed_config.get(stringify!($field)).and_then(|v| v.as_bool()) {
if $config.$field != value {
$config.$field = value;
$changed = true;
}
}
};
}
trait Section {
fn apply_values(&mut self, parsed_config: &Value) -> bool;
}
impl Section for LogConfig {
fn apply_values(&mut self, parsed_config: &Value) -> bool {
if let Some(section) = parsed_config.get("logging") {
let mut missing = false;
apply_bool_value!(self, section, missing, log_spawning);
apply_bool_value!(self, section, missing, log_ticks);
missing
} else {
true
}
}
}
impl Section for VisualConfig {
fn apply_values(&mut self, parsed_config: &Value) -> bool {
if let Some(section) = parsed_config.get("visuals") {
let mut missing = false;
apply_bool_value!(self, section, missing, with_scanlines);
apply_bool_value!(self, section, missing, with_screen_burn);
apply_bool_value!(self, section, missing, with_darken_by_distance);
apply_bool_value!(self, section, missing, use_bitset_walls);
apply_bool_value!(self, section, missing, use_coloured_tile_bg);
apply_bool_value!(self, section, missing, add_colour_variance);
missing
} else {
true
}
}
}
#[cfg(not(target_arch = "wasm32"))]
pub fn try_load_configuration() -> Config {
let config: Config = Config::load_from_file("config.toml");
return config;
}
#[cfg(target_arch = "wasm32")]
pub fn try_load_configuration() -> Config {
let config = Config::default();
return config;
}