Toml generalization

Trying to make the tweakfile code more general purpose.
I'd like to just throw stuff in there and reference it in code without
having to modify structs and stuff.

So far it's tedious, but mostly because I'll have to go back and rewrite
a bunch of code... sadge.
main
Elijah Voigt 2 years ago
parent 837c345ffe
commit cef69b81cc

@ -0,0 +1,19 @@
use bevy::utils::HashMap;
use serde::Deserialize;
use toml::Table;
#[derive(Deserialize, Debug)]
enum Val {
A(String),
B(usize),
C(bool),
}
fn main() {
let s = r#"val = "asdf"
other = 123
final = false
"#;
let v = toml::from_str::<Table>(s).unwrap();
println!("{:?}", v);
}

@ -1,5 +1,6 @@
use crate::prelude::*;
use bevy::asset::AsyncReadExt;
use bevy::utils::HashMap;
use bevy::{
asset::{io::Reader, AssetLoader, LoadContext},
reflect::TypePath,
@ -17,7 +18,8 @@ impl Plugin for TweakPlugin {
fn build(&self, app: &mut App) {
app.add_systems(OnEnter(GameState::Loading), load_tweakfile);
app.init_asset::<Tweakfile>().register_asset_loader(TweakfileLoader);
app.init_asset::<Tweakfile>()
.register_asset_loader(TweakfileLoader);
}
}
@ -32,7 +34,7 @@ pub(crate) struct GameTweakfile {
}
/// Tweakfile contains tweaks made to other parts of the game
#[derive(Debug, Deserialize, TypePath, Asset)]
#[derive(Debug, Deserialize, TypePath, Asset, Default)]
pub struct Tweakfile {
#[serde(default)]
pub audio: audio::AudioTweaks,
@ -42,6 +44,125 @@ pub struct Tweakfile {
pub display2d: display2d::tweaks::Display2dTweaks,
}
#[derive(Debug, Asset, TypePath)]
pub struct Tweaks(HashMap<String, TweakValue>);
impl Tweaks {
fn from_table(
table: &toml::Table,
load_context: &mut LoadContext,
base: String,
) -> Vec<(String, TweakValue)> {
table
.iter()
.flat_map(|(k, v)| {
let key = if base.len() > 0 {
format!("{}_{}", base, k)
} else {
k.clone()
};
match v {
toml::Value::Table(t) => Tweaks::from_table(t, load_context, key),
toml::Value::Datetime(_) => panic!("This type is not supported!"),
_ => vec![(key, TweakValue::from_toml(v, load_context))],
}
})
.collect()
}
fn get_handle<T: Asset>(&self, key: &str) -> Option<Handle<T>> {
self.0.get(key).map(|val| Handle::<T>::from(val.clone()))
}
fn get_int(&self, key: &str) -> Option<i64> {
self.0.get(key).map(|val| i64::from(val.clone()))
}
fn get_float(&self, key: &str) -> Option<f64> {
self.0.get(key).map(|val| f64::from(val.clone()))
}
}
#[derive(Debug, Clone)]
pub enum TweakValue {
Handle(UntypedHandle),
Int(i64),
Float(f64),
Bool(bool),
Str(String),
List(Vec<TweakValue>),
}
impl TweakValue {
fn from_toml(val: &toml::Value, load_context: &mut LoadContext) -> TweakValue {
match val {
toml::Value::String(s) => {
if std::path::Path::new(&format!("assets/{}", s)).exists() {
TweakValue::Handle(load_context.load_untyped(s).untyped())
} else {
TweakValue::Str(s.clone())
}
}
toml::Value::Integer(i) => TweakValue::Int(*i),
toml::Value::Float(f) => TweakValue::Float(*f),
toml::Value::Boolean(b) => TweakValue::Bool(*b),
toml::Value::Array(a) => TweakValue::List(
a.iter()
.map(|v| TweakValue::from_toml(v, load_context))
.collect(),
),
toml::Value::Table(_) | toml::Value::Datetime(_) => {
panic!("This type is not supported!")
}
}
}
}
impl<T: Asset> From<TweakValue> for Handle<T> {
fn from(src: TweakValue) -> Handle<T> {
match src {
TweakValue::Handle(h) => h.clone().typed::<T>(),
_ => panic!("{:?} is not a handle", src),
}
}
}
impl From<TweakValue> for String {
fn from(src: TweakValue) -> String {
match src {
TweakValue::Str(s) => s,
_ => panic!("{:?} is not a bool", src),
}
}
}
impl From<TweakValue> for i64 {
fn from(src: TweakValue) -> i64 {
match src {
TweakValue::Int(i) => i,
_ => panic!("{:?} is not an integer", src),
}
}
}
impl From<TweakValue> for f64 {
fn from(src: TweakValue) -> f64 {
match src {
TweakValue::Float(f) => f,
_ => panic!("{:?} is not a float", src),
}
}
}
impl From<TweakValue> for bool {
fn from(src: TweakValue) -> bool {
match src {
TweakValue::Bool(b) => b,
_ => panic!("{:?} is not a bool", src),
}
}
}
#[derive(Default)]
pub struct TweakfileLoader;
@ -70,9 +191,11 @@ impl AssetLoader for TweakfileLoader {
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;
let s = std::str::from_utf8(bytes.as_slice())?;
let mut result = toml::from_str::<Tweakfile>(s)?;
result.display3d.load_dependencies(load_context);
Ok(result)
let parsed = toml::from_str::<toml::Table>(s)?;
let list = Tweaks::from_table(&parsed, load_context, String::new());
let result: HashMap<String, TweakValue> = list.into_iter().collect();
// Ok(Tweaks(result))
Ok(Tweakfile::default())
})
}

Loading…
Cancel
Save