use bevy::{
prelude::*,
reflect::{
serde::{ReflectDeserializer, ReflectSerializer},
DynamicStruct, PartialReflect,
},
};
use serde::de::DeserializeSeed;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.run();
}
#[derive(Reflect)]
#[reflect(from_reflect = false)]
pub struct Foo {
a: usize,
nested: Bar,
#[reflect(ignore)]
_ignored: NonReflectedValue,
}
#[derive(Reflect)]
pub struct Bar {
b: usize,
}
#[derive(Default)]
struct NonReflectedValue {
_a: usize,
}
fn setup(type_registry: Res<AppTypeRegistry>) {
let mut value = Foo {
a: 1,
_ignored: NonReflectedValue { _a: 10 },
nested: Bar { b: 8 },
};
*value.get_field_mut("a").unwrap() = 2usize;
assert_eq!(value.a, 2);
assert_eq!(*value.get_field::<usize>("a").unwrap(), 2);
let field = value.field("a").unwrap();
let fully_reflected_field = field.try_as_reflect().unwrap();
assert_eq!(*fully_reflected_field.downcast_ref::<usize>().unwrap(), 2);
assert_eq!(*field.try_downcast_ref::<usize>().unwrap(), 2);
let mut patch = DynamicStruct::default();
patch.insert("a", 4usize);
value.apply(&patch);
assert_eq!(value.a, 4);
let type_registry = type_registry.read();
let serializer = ReflectSerializer::new(&value, &type_registry);
let ron_string =
ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap();
info!("{}\n", ron_string);
let reflect_deserializer = ReflectDeserializer::new(&type_registry);
let mut deserializer = ron::de::Deserializer::from_str(&ron_string).unwrap();
let reflect_value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
assert_eq!(
reflect_value.reflect_type_path(),
DynamicStruct::type_path(),
);
assert!(reflect_value.reflect_partial_eq(&value).unwrap());
value.apply(&*reflect_value);
}