mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
props: properties no longer directly implement the Serialize trait
This commit is contained in:
parent
bb56b07973
commit
da52b1b034
8 changed files with 117 additions and 32 deletions
|
@ -147,17 +147,6 @@ pub fn derive_properties(input: TokenStream) -> TokenStream {
|
|||
}
|
||||
}
|
||||
|
||||
impl #impl_generics #bevy_property_path::serde::ser::Serialize for #struct_name#ty_generics {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: #bevy_property_path::serde::ser::Serializer,
|
||||
{
|
||||
use #bevy_property_path::serde::ser::SerializeMap;
|
||||
use #bevy_property_path::serde::Serialize;
|
||||
#bevy_property_path::MapSerializer::new(self).serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl #impl_generics #bevy_property_path::Property for #struct_name#ty_generics {
|
||||
#[inline]
|
||||
fn type_name(&self) -> &str {
|
||||
|
@ -205,6 +194,10 @@ pub fn derive_properties(input: TokenStream) -> TokenStream {
|
|||
fn as_properties(&self) -> Option<&dyn #bevy_property_path::Properties> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
fn serializable(&self) -> #bevy_property_path::Serializable {
|
||||
#bevy_property_path::Serializable::Owned(Box::new(#bevy_property_path::MapSerializer::new(self)))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -256,6 +249,11 @@ pub fn derive_property(input: TokenStream) -> TokenStream {
|
|||
panic!("prop value is not {}", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn serializable(&self) -> #bevy_property_path::Serializable {
|
||||
#bevy_property_path::Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
Properties, PropertiesType, Property, PropertyIter, PropertyTypeRegistration,
|
||||
PropertyTypeRegistry,
|
||||
PropertyTypeRegistry, Serializable,
|
||||
};
|
||||
use de::SeqAccess;
|
||||
use serde::{
|
||||
|
@ -183,6 +183,10 @@ impl Property for DynamicProperties {
|
|||
fn is_sequence(&self) -> bool {
|
||||
self.properties_type == PropertiesType::Seq
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for DynamicProperties {
|
||||
|
@ -219,14 +223,13 @@ impl<'a> Serialize for MapSerializer<'a> {
|
|||
if property.is_sequence() {
|
||||
state.serialize_entry(name, &SeqSerializer { property })?;
|
||||
} else {
|
||||
state.serialize_entry(name, property)?;
|
||||
state.serialize_entry(name, property.serializable().borrow())?;
|
||||
}
|
||||
}
|
||||
state.end()
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: maybe you can return this as a type erased serializer as Prop::get_serializer()? This would remove the need for explicit Serialize impls
|
||||
pub struct SeqSerializer<'a> {
|
||||
pub property: &'a dyn Property,
|
||||
}
|
||||
|
@ -248,7 +251,7 @@ impl<'a> Serialize for SeqSerializer<'a> {
|
|||
state.serialize_entry("data", &PropertiesSeqSerializer { properties })?;
|
||||
} else {
|
||||
state.serialize_entry("seq_value_type", self.property.type_name())?;
|
||||
state.serialize_entry("data", self.property)?;
|
||||
state.serialize_entry("data", self.property.serializable().borrow())?;
|
||||
}
|
||||
state.end()
|
||||
}
|
||||
|
@ -265,7 +268,7 @@ impl<'a> Serialize for PropertiesSeqSerializer<'a> {
|
|||
{
|
||||
let mut state = serializer.serialize_seq(Some(self.properties.prop_len()))?;
|
||||
for prop in self.properties.iter_props() {
|
||||
state.serialize_element(prop)?;
|
||||
state.serialize_element(prop.serializable().borrow())?;
|
||||
}
|
||||
state.end()
|
||||
}
|
||||
|
@ -537,7 +540,7 @@ where
|
|||
));
|
||||
}
|
||||
dynamic_properties = map.next_value_seed(PropSeqDeserializer {
|
||||
property_type_registry: property_type_registry,
|
||||
property_type_registry,
|
||||
current_type_name: current_type_name.clone(),
|
||||
})?;
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{impl_property, Property};
|
||||
use crate::{impl_property, Property, Serializable};
|
||||
use glam::{Mat3, Mat4, Quat, Vec2, Vec3};
|
||||
|
||||
impl_property!(Vec2);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{impl_property, Property};
|
||||
use crate::{impl_property, Property, Serializable};
|
||||
use legion::prelude::Entity;
|
||||
|
||||
impl_property!(Entity);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::Property;
|
||||
use crate::{Serializable, Property};
|
||||
use serde::Serialize;
|
||||
use smallvec::{Array, SmallVec};
|
||||
use std::any::Any;
|
||||
|
@ -39,4 +39,8 @@ where
|
|||
*self = prop.clone();
|
||||
}
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{impl_property, Properties, PropertiesType, Property, PropertyIter};
|
||||
use crate::{impl_property, Properties, PropertiesType, Property, PropertyIter, SeqSerializer, Serializable};
|
||||
use serde::Serialize;
|
||||
use std::{
|
||||
any::Any,
|
||||
|
@ -9,7 +9,7 @@ use std::{
|
|||
|
||||
impl<T> Properties for Vec<T>
|
||||
where
|
||||
T: Property + Clone + Serialize,
|
||||
T: Property + Clone,
|
||||
{
|
||||
fn prop(&self, _name: &str) -> Option<&dyn Property> {
|
||||
None
|
||||
|
@ -39,7 +39,7 @@ where
|
|||
|
||||
impl<T> Property for Vec<T>
|
||||
where
|
||||
T: Property + Clone + Serialize,
|
||||
T: Property + Clone,
|
||||
{
|
||||
fn type_name(&self) -> &str {
|
||||
std::any::type_name::<Self>()
|
||||
|
@ -81,6 +81,10 @@ where
|
|||
fn is_sequence(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Owned(Box::new(SeqSerializer::new(self)))
|
||||
}
|
||||
}
|
||||
|
||||
impl_property!(String);
|
||||
|
@ -150,6 +154,10 @@ impl Property for usize {
|
|||
panic!("prop value is not {}", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Property for u64 {
|
||||
|
@ -204,6 +212,10 @@ impl Property for u64 {
|
|||
panic!("prop value is not {}", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Property for u32 {
|
||||
|
@ -258,6 +270,10 @@ impl Property for u32 {
|
|||
panic!("prop value is not {}", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Property for u16 {
|
||||
|
@ -312,6 +328,10 @@ impl Property for u16 {
|
|||
panic!("prop value is not {}", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Property for u8 {
|
||||
|
@ -366,6 +386,10 @@ impl Property for u8 {
|
|||
panic!("prop value is not {}", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Property for isize {
|
||||
|
@ -420,6 +444,10 @@ impl Property for isize {
|
|||
panic!("prop value is not {}", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Property for i64 {
|
||||
|
@ -474,6 +502,10 @@ impl Property for i64 {
|
|||
panic!("prop value is not {}", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Property for i32 {
|
||||
|
@ -528,6 +560,10 @@ impl Property for i32 {
|
|||
panic!("prop value is not {}", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Property for i16 {
|
||||
|
@ -582,6 +618,10 @@ impl Property for i16 {
|
|||
panic!("prop value is not {}", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Property for i8 {
|
||||
|
@ -636,6 +676,10 @@ impl Property for i8 {
|
|||
panic!("prop value is not {}", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Property for f32 {
|
||||
|
@ -674,6 +718,10 @@ impl Property for f32 {
|
|||
panic!("prop value is not {}", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Property for f64 {
|
||||
|
@ -712,4 +760,8 @@ impl Property for f64 {
|
|||
panic!("prop value is not {}", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,23 @@
|
|||
use crate::Properties;
|
||||
use std::any::Any;
|
||||
use erased_serde::Serialize;
|
||||
|
||||
pub trait Property: erased_serde::Serialize + Send + Sync + Any + 'static {
|
||||
|
||||
pub enum Serializable<'a> {
|
||||
Owned(Box<dyn Serialize + 'a>),
|
||||
Borrowed(&'a dyn Serialize),
|
||||
}
|
||||
|
||||
impl<'a> Serializable<'a> {
|
||||
pub fn borrow(&self) -> &dyn Serialize {
|
||||
match self {
|
||||
Serializable::Borrowed(serialize) => serialize,
|
||||
Serializable::Owned(serialize) => serialize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Property: Send + Sync + Any + 'static {
|
||||
fn type_name(&self) -> &str;
|
||||
fn any(&self) -> &dyn Any;
|
||||
fn any_mut(&mut self) -> &mut dyn Any;
|
||||
|
@ -14,9 +30,9 @@ pub trait Property: erased_serde::Serialize + Send + Sync + Any + 'static {
|
|||
fn is_sequence(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
erased_serde::serialize_trait_object!(Property);
|
||||
fn serializable(&self) -> Serializable;
|
||||
}
|
||||
|
||||
pub trait PropertyVal {
|
||||
fn val<T: 'static>(&self) -> Option<&T>;
|
||||
|
@ -84,6 +100,10 @@ macro_rules! impl_property {
|
|||
panic!("prop value is not {}", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
};
|
||||
(SEQUENCE, @$trait_:ident [$($args:ident,)*] where [$($preds:tt)+]) => {
|
||||
|
@ -128,6 +148,10 @@ macro_rules! impl_property {
|
|||
fn is_sequence(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -169,6 +193,10 @@ macro_rules! impl_property {
|
|||
panic!("prop value is not {}", std::any::type_name::<Self>());
|
||||
}
|
||||
}
|
||||
|
||||
fn serializable(&self) -> Serializable {
|
||||
Serializable::Borrowed(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -4,7 +4,6 @@ use bevy::{
|
|||
property::{ron::deserialize_dynamic_properties},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use bevy_property::{PropertiesSeqSerializer, SeqSerializer};
|
||||
|
||||
fn main() {
|
||||
App::build()
|
||||
|
@ -57,8 +56,9 @@ fn setup(property_type_registry: Res<PropertyTypeRegistryContext>) {
|
|||
test.apply(&patch);
|
||||
assert_eq!(test.a, 4);
|
||||
|
||||
// Properties implement the serde Serialize trait. You don't need to derive it yourself!
|
||||
let ron_string = serialize_ron(&test).unwrap();
|
||||
// All properties can be serialized.
|
||||
// If you #[derive(Properties)] your type doesn't even need to directly implement the Serde trait!
|
||||
let ron_string = serialize_ron(&test.serializable().borrow()).unwrap();
|
||||
println!("{}\n", ron_string);
|
||||
|
||||
// Dynamic properties can be deserialized
|
||||
|
@ -73,20 +73,20 @@ fn setup(property_type_registry: Res<PropertyTypeRegistryContext>) {
|
|||
// This means you can patch Properties with dynamic properties deserialized from a string
|
||||
test.apply(&dynamic_properties);
|
||||
|
||||
// Properties can also be sequences. Std sequences (Vec, VecDeque) already implement the Properties trait
|
||||
// Properties can also be sequences.
|
||||
// Sequences from std::collections (Vec, VecDeque) already implement the Properties trait
|
||||
let mut seq = vec![1u32, 2u32];
|
||||
let mut patch = DynamicProperties::seq();
|
||||
patch.push(Box::new(3u32), None);
|
||||
seq.apply(&patch);
|
||||
assert_eq!(seq[0], 3);
|
||||
|
||||
let ron_string = serialize_ron(&SeqSerializer { property: &patch} ).unwrap();
|
||||
let ron_string = serialize_ron(&patch.serializable().borrow()).unwrap();
|
||||
println!("{}\n", ron_string);
|
||||
let dynamic_properties =
|
||||
deserialize_dynamic_properties(&ron_string, &property_type_registry.value.read().unwrap())
|
||||
.unwrap();
|
||||
let round_tripped = serialize_ron(&dynamic_properties).unwrap();
|
||||
println!("{}", round_tripped);
|
||||
assert_eq!(ron_string, round_tripped);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue