diff --git a/examples/toml-stuff.rs b/examples/toml-stuff.rs
new file mode 100644
index 0000000..99d2bc0
--- /dev/null
+++ b/examples/toml-stuff.rs
@@ -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::
(s).unwrap();
+ println!("{:?}", v);
+}
diff --git a/src/tweak.rs b/src/tweak.rs
index 9c99436..2a21af1 100644
--- a/src/tweak.rs
+++ b/src/tweak.rs
@@ -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::().register_asset_loader(TweakfileLoader);
+ app.init_asset::()
+ .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);
+
+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(&self, key: &str) -> Option> {
+ self.0.get(key).map(|val| Handle::::from(val.clone()))
+ }
+
+ fn get_int(&self, key: &str) -> Option {
+ self.0.get(key).map(|val| i64::from(val.clone()))
+ }
+
+ fn get_float(&self, key: &str) -> Option {
+ 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),
+}
+
+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 From for Handle {
+ fn from(src: TweakValue) -> Handle {
+ match src {
+ TweakValue::Handle(h) => h.clone().typed::(),
+ _ => panic!("{:?} is not a handle", src),
+ }
+ }
+}
+
+impl From for String {
+ fn from(src: TweakValue) -> String {
+ match src {
+ TweakValue::Str(s) => s,
+ _ => panic!("{:?} is not a bool", src),
+ }
+ }
+}
+
+impl From for i64 {
+ fn from(src: TweakValue) -> i64 {
+ match src {
+ TweakValue::Int(i) => i,
+ _ => panic!("{:?} is not an integer", src),
+ }
+ }
+}
+
+impl From for f64 {
+ fn from(src: TweakValue) -> f64 {
+ match src {
+ TweakValue::Float(f) => f,
+ _ => panic!("{:?} is not a float", src),
+ }
+ }
+}
+
+impl From 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::(s)?;
- result.display3d.load_dependencies(load_context);
- Ok(result)
+ let parsed = toml::from_str::(s)?;
+ let list = Tweaks::from_table(&parsed, load_context, String::new());
+ let result: HashMap = list.into_iter().collect();
+ // Ok(Tweaks(result))
+ Ok(Tweakfile::default())
})
}