From 59dbf22e39d24c5886be3a83aeefa71106bb39f3 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Wed, 27 May 2020 13:07:32 -0700 Subject: [PATCH] rework scene format. use property value serializer, removing the need for ron fork / enabling any serde target --- .../bevy_property_derive/src/lib.rs | 38 +- .../bevy_property/src/dynamic_properties.rs | 41 +- .../bevy_property/src/impl_property_legion.rs | 2 +- .../src/impl_property_smallvec.rs | 6 +- crates/bevy_property/src/impl_property_std.rs | 15 +- crates/bevy_property/src/properties.rs | 29 +- crates/bevy_property/src/property.rs | 36 +- crates/bevy_property/src/property_serde.rs | 351 ++++++++++-------- crates/bevy_property/src/ron.rs | 16 +- crates/bevy_scene/src/scene_loader.rs | 14 +- crates/bevy_scene/src/serde.rs | 29 +- 11 files changed, 295 insertions(+), 282 deletions(-) diff --git a/crates/bevy_property/bevy_property_derive/src/lib.rs b/crates/bevy_property/bevy_property_derive/src/lib.rs index 8e2f7f9e85..5fcac31c0f 100644 --- a/crates/bevy_property/bevy_property_derive/src/lib.rs +++ b/crates/bevy_property/bevy_property_derive/src/lib.rs @@ -148,10 +148,6 @@ pub fn derive_properties(input: TokenStream) -> TokenStream { fn iter_props(&self) -> #bevy_property_path::PropertyIter { #bevy_property_path::PropertyIter::new(self) } - - fn properties_type(&self) -> #bevy_property_path::PropertiesType { - #bevy_property_path::PropertiesType::Map - } } impl #impl_generics #bevy_property_path::Property for #struct_name#ty_generics { @@ -181,11 +177,11 @@ pub fn derive_properties(input: TokenStream) -> TokenStream { #[inline] fn apply(&mut self, value: &dyn #bevy_property_path::Property) { if let Some(properties) = value.as_properties() { - if properties.properties_type() != self.properties_type() { + if properties.property_type() != self.property_type() { panic!( "Properties type mismatch. This type is {:?} but the applied type is {:?}", - self.properties_type(), - properties.properties_type() + self.property_type(), + properties.property_type() ); } for (i, prop) in properties.iter_props().enumerate() { @@ -202,8 +198,12 @@ pub fn derive_properties(input: TokenStream) -> TokenStream { Some(self) } - fn serializable(&self) -> #bevy_property_path::Serializable { - #bevy_property_path::Serializable::Owned(Box::new(#bevy_property_path::property_serde::MapSerializer::new(self))) + fn serializable(&self) -> #bevy_property_path::property_serde::Serializable { + #bevy_property_path::property_serde::Serializable::Owned(Box::new(#bevy_property_path::property_serde::MapSerializer::new(self))) + } + + fn property_type(&self) -> #bevy_property_path::PropertyType { + #bevy_property_path::PropertyType::Map } } }) @@ -258,8 +258,14 @@ pub fn derive_property(input: TokenStream) -> TokenStream { } #[inline] - fn serializable(&self) -> #bevy_property_path::Serializable { - #bevy_property_path::Serializable::Borrowed(self) + fn serializable(&self) -> #bevy_property_path::property_serde::Serializable { + #bevy_property_path::property_serde::Serializable::Owned(Box::new(#bevy_property_path::property_serde::PropertyValueSerializer { + property: self, + })) + } + + fn property_type(&self) -> #bevy_property_path::PropertyType { + #bevy_property_path::PropertyType::Value } } @@ -337,7 +343,9 @@ pub fn impl_property(input: TokenStream) -> TokenStream { quote! { #serialize_fn(self) } } else { quote! { - #bevy_property_path::Serializable::Borrowed(self) + #bevy_property_path::property_serde::Serializable::Owned(Box::new(#bevy_property_path::property_serde::PropertyValueSerializer { + property: self, + })) } }; let deserialize_fn = if let Some(deserialize_fn) = property_def.deserialize_fn { @@ -387,9 +395,13 @@ pub fn impl_property(input: TokenStream) -> TokenStream { } #[inline] - fn serializable(&self) -> #bevy_property_path::Serializable { + fn serializable(&self) -> #bevy_property_path::property_serde::Serializable { #serialize_fn } + + fn property_type(&self) -> #bevy_property_path::PropertyType { + #bevy_property_path::PropertyType::Value + } } impl #impl_generics #bevy_property_path::DeserializeProperty for #ty#ty_generics #where_clause { diff --git a/crates/bevy_property/src/dynamic_properties.rs b/crates/bevy_property/src/dynamic_properties.rs index b635eb7a29..948f40f2f6 100644 --- a/crates/bevy_property/src/dynamic_properties.rs +++ b/crates/bevy_property/src/dynamic_properties.rs @@ -1,4 +1,4 @@ -use crate::{Properties, PropertiesType, Property, PropertyIter, Serializable}; +use crate::{property_serde::Serializable, Properties, Property, PropertyIter, PropertyType}; use std::{any::Any, borrow::Cow, collections::HashMap}; pub struct DynamicProperties { @@ -6,7 +6,7 @@ pub struct DynamicProperties { pub props: Vec>, pub prop_names: Vec>, pub prop_indices: HashMap, usize>, - pub properties_type: PropertiesType, + pub property_type: PropertyType, } impl DynamicProperties { @@ -16,7 +16,7 @@ impl DynamicProperties { props: Default::default(), prop_names: Default::default(), prop_indices: Default::default(), - properties_type: PropertiesType::Map, + property_type: PropertyType::Map, } } @@ -26,7 +26,7 @@ impl DynamicProperties { props: Default::default(), prop_names: Default::default(), prop_indices: Default::default(), - properties_type: PropertiesType::Seq, + property_type: PropertyType::Seq, } } @@ -88,9 +88,10 @@ impl Properties for DynamicProperties { #[inline] fn prop_name(&self, index: usize) -> Option<&str> { - match self.properties_type { - PropertiesType::Seq => None, - PropertiesType::Map => self.prop_names.get(index).map(|name| name.as_ref()), + match self.property_type { + PropertyType::Seq => None, + PropertyType::Map => self.prop_names.get(index).map(|name| name.as_ref()), + _ => panic!("DynamicProperties cannot be Value types"), } } @@ -105,11 +106,6 @@ impl Properties for DynamicProperties { index: 0, } } - - #[inline] - fn properties_type(&self) -> PropertiesType { - self.properties_type - } } impl Property for DynamicProperties { @@ -142,25 +138,26 @@ impl Property for DynamicProperties { #[inline] fn apply(&mut self, value: &dyn Property) { if let Some(properties) = value.as_properties() { - if properties.properties_type() != self.properties_type { + if properties.property_type() != self.property_type { panic!( "Properties type mismatch. This type is {:?} but the applied type is {:?}", - self.properties_type, - properties.properties_type() + self.property_type, + properties.property_type() ); } - match self.properties_type { - PropertiesType::Map => { + match self.property_type { + PropertyType::Map => { for (i, prop) in properties.iter_props().enumerate() { let name = properties.prop_name(i).unwrap(); self.prop_mut(name).map(|p| p.apply(prop)); } } - PropertiesType::Seq => { + PropertyType::Seq => { for (i, prop) in properties.iter_props().enumerate() { self.prop_with_index_mut(i).map(|p| p.apply(prop)); } } + _ => panic!("DynamicProperties cannot be Value types"), } } else { panic!("attempted to apply non-Properties type to Properties type"); @@ -171,11 +168,11 @@ impl Property for DynamicProperties { Some(self) } - fn is_sequence(&self) -> bool { - self.properties_type == PropertiesType::Seq - } - fn serializable(&self) -> Serializable { Serializable::Borrowed(self) } + + fn property_type(&self) -> PropertyType { + self.property_type + } } diff --git a/crates/bevy_property/src/impl_property_legion.rs b/crates/bevy_property/src/impl_property_legion.rs index 1a24323c4f..a85041730d 100644 --- a/crates/bevy_property/src/impl_property_legion.rs +++ b/crates/bevy_property/src/impl_property_legion.rs @@ -1,4 +1,4 @@ -use crate::{impl_property, Property, PropertyTypeRegistry, Serializable}; +use crate::{impl_property, Property, PropertyTypeRegistry, property_serde::Serializable}; use erased_serde::Deserializer; use legion::prelude::Entity; use serde::Deserialize; diff --git a/crates/bevy_property/src/impl_property_smallvec.rs b/crates/bevy_property/src/impl_property_smallvec.rs index 7e25581654..cf9d0d1bd7 100644 --- a/crates/bevy_property/src/impl_property_smallvec.rs +++ b/crates/bevy_property/src/impl_property_smallvec.rs @@ -1,4 +1,4 @@ -use crate::{Serializable, Property}; +use crate::{Property, PropertyType, property_serde::Serializable}; use serde::Serialize; use smallvec::{Array, SmallVec}; use std::any::Any; @@ -43,4 +43,8 @@ where fn serializable(&self) -> Serializable { Serializable::Borrowed(self) } + + fn property_type(&self) -> PropertyType { + PropertyType::Value + } } diff --git a/crates/bevy_property/src/impl_property_std.rs b/crates/bevy_property/src/impl_property_std.rs index aa5455eed9..8e04438cc3 100644 --- a/crates/bevy_property/src/impl_property_std.rs +++ b/crates/bevy_property/src/impl_property_std.rs @@ -1,4 +1,4 @@ -use crate::{impl_property, Properties, PropertiesType, Property, PropertyIter, Serializable, property_serde::SeqSerializer}; +use crate::{impl_property, Properties, Property, PropertyIter, property_serde::{Serializable, SeqSerializer}}; use serde::{Serialize, Deserialize}; use std::{ any::Any, @@ -32,9 +32,6 @@ where fn iter_props(&self) -> PropertyIter { PropertyIter::new(self) } - fn properties_type(&self) -> PropertiesType { - PropertiesType::Seq - } } impl Property for Vec @@ -56,11 +53,11 @@ where } fn set(&mut self, value: &dyn Property) { if let Some(properties) = value.as_properties() { - if properties.properties_type() != self.properties_type() { + if properties.property_type() != self.property_type() { panic!( "Properties type mismatch. This type is {:?} but the applied type is {:?}", - self.properties_type(), - properties.properties_type() + self.property_type(), + properties.property_type() ); } for (i, prop) in properties.iter_props().enumerate() { @@ -78,10 +75,6 @@ where Some(self) } - fn is_sequence(&self) -> bool { - true - } - fn serializable(&self) -> Serializable { Serializable::Owned(Box::new(SeqSerializer::new(self))) } diff --git a/crates/bevy_property/src/properties.rs b/crates/bevy_property/src/properties.rs index 6e4ed020c9..a59cd094e6 100644 --- a/crates/bevy_property/src/properties.rs +++ b/crates/bevy_property/src/properties.rs @@ -1,10 +1,4 @@ -use crate::{DynamicProperties, Property, PropertyVal}; - -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)] -pub enum PropertiesType { - Map, - Seq, -} +use crate::{DynamicProperties, Property, PropertyType, PropertyVal}; pub trait Properties: Property { fn prop(&self, name: &str) -> Option<&dyn Property>; @@ -14,7 +8,6 @@ pub trait Properties: Property { fn prop_name(&self, index: usize) -> Option<&str>; fn prop_len(&self) -> usize; fn iter_props(&self) -> PropertyIter; - fn properties_type(&self) -> PropertiesType; fn set_prop(&mut self, name: &str, value: &dyn Property) { if let Some(prop) = self.prop_mut(name) { prop.set(value); @@ -22,25 +15,27 @@ pub trait Properties: Property { panic!("prop does not exist: {}", name); } } - fn to_dynamic(&self) -> DynamicProperties - { - let mut dynamic_props = match self.properties_type() { - PropertiesType::Map => { + fn to_dynamic(&self) -> DynamicProperties { + let mut dynamic_props = match self.property_type() { + PropertyType::Map => { let mut dynamic_props = DynamicProperties::map(); for (i, prop) in self.iter_props().enumerate() { - let name = self.prop_name(i).expect("All properties in maps should have a name"); + let name = self + .prop_name(i) + .expect("All properties in maps should have a name"); dynamic_props.set_box(name, prop.clone_prop()); } dynamic_props - }, - PropertiesType::Seq => { + } + PropertyType::Seq => { let mut dynamic_props = DynamicProperties::seq(); for prop in self.iter_props() { dynamic_props.push(prop.clone_prop(), None); } dynamic_props } - } ; + _ => panic!("Properties cannot be Value types"), + }; dynamic_props.type_name = self.type_name().to_string(); dynamic_props @@ -92,4 +87,4 @@ where panic!("prop does not exist or is incorrect type: {}", name); } } -} \ No newline at end of file +} diff --git a/crates/bevy_property/src/property.rs b/crates/bevy_property/src/property.rs index 53153dd221..8d162f3161 100644 --- a/crates/bevy_property/src/property.rs +++ b/crates/bevy_property/src/property.rs @@ -1,20 +1,12 @@ -use crate::{PropertyTypeRegistry, Properties}; +use crate::{property_serde::Serializable, Properties, PropertyTypeRegistry}; +use erased_serde::Deserializer; use std::any::Any; -use erased_serde::{Deserializer, Serialize}; - -pub enum Serializable<'a> { - Owned(Box), - Borrowed(&'a dyn Serialize), -} - -impl<'a> Serializable<'a> { - pub fn borrow(&self) -> &dyn Serialize { - match self { - Serializable::Borrowed(serialize) => serialize, - Serializable::Owned(serialize) => serialize, - } - } +#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)] +pub enum PropertyType { + Map, + Seq, + Value, } // TODO: consider removing send + sync requirements @@ -25,18 +17,20 @@ pub trait Property: Send + Sync + Any + 'static { fn clone_prop(&self) -> Box; fn set(&mut self, value: &dyn Property); fn apply(&mut self, value: &dyn Property); + fn property_type(&self) -> PropertyType { + PropertyType::Value + } fn as_properties(&self) -> Option<&dyn Properties> { None } - fn is_sequence(&self) -> bool { - false - } - fn serializable(&self) -> Serializable; } pub trait DeserializeProperty { - fn deserialize(deserializer: &mut dyn Deserializer, property_type_registry: &PropertyTypeRegistry) -> Result, erased_serde::Error>; + fn deserialize( + deserializer: &mut dyn Deserializer, + property_type_registry: &PropertyTypeRegistry, + ) -> Result, erased_serde::Error>; } pub trait PropertyVal { @@ -58,4 +52,4 @@ impl PropertyVal for dyn Property { panic!("prop value is not {}", std::any::type_name::()); } } -} \ No newline at end of file +} diff --git a/crates/bevy_property/src/property_serde.rs b/crates/bevy_property/src/property_serde.rs index 98f18c6839..6189bf1af8 100644 --- a/crates/bevy_property/src/property_serde.rs +++ b/crates/bevy_property/src/property_serde.rs @@ -1,61 +1,77 @@ -use crate::{DynamicProperties, Properties, PropertiesType, Property, PropertyTypeRegistry}; +use crate::{DynamicProperties, Properties, Property, PropertyType, PropertyTypeRegistry}; use de::SeqAccess; use serde::{ de::{self, DeserializeSeed, MapAccess, Visitor}, ser::{SerializeMap, SerializeSeq}, Serialize, }; -use std::{cell::RefCell, rc::Rc}; + +pub const TYPE_FIELD: &str = "type"; +pub const MAP_FIELD: &str = "map"; +pub const SEQ_FIELD: &str = "seq"; +pub const VALUE_FIELD: &str = "value"; + +pub enum Serializable<'a> { + Owned(Box), + Borrowed(&'a dyn erased_serde::Serialize), +} + +impl<'a> Serializable<'a> { + pub fn borrow(&self) -> &dyn erased_serde::Serialize { + match self { + Serializable::Borrowed(serialize) => serialize, + Serializable::Owned(serialize) => serialize, + } + } +} +pub struct PropertyValueSerializer<'a, T> +where + T: Property + Serialize, +{ + pub property: &'a T, +} + +impl<'a, T> PropertyValueSerializer<'a, T> +where + T: Property + Serialize, +{ + pub fn new(property: &'a T) -> Self { + PropertyValueSerializer { property } + } +} + +impl<'a, T> Serialize for PropertyValueSerializer<'a, T> +where + T: Property + Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_map(Some(2))?; + state.serialize_entry(TYPE_FIELD, self.property.type_name())?; + state.serialize_entry(VALUE_FIELD, self.property)?; + state.end() + } +} impl Serialize for DynamicProperties { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { - match self.properties_type { - PropertiesType::Map => MapSerializer::new(self).serialize(serializer), - PropertiesType::Seq => SeqSerializer::new(self).serialize(serializer), + match self.property_type { + PropertyType::Map => MapSerializer::new(self).serialize(serializer), + PropertyType::Seq => SeqSerializer::new(self).serialize(serializer), + _ => { + return Err(serde::ser::Error::custom( + "DynamicProperties cannot be Value type", + )) + } } } } -pub struct DynamicPropertiesDeserializer<'a> { - pub registry: &'a PropertyTypeRegistry, - pub current_type_name: Rc>>, -} - -impl<'a, 'de> DeserializeSeed<'de> for DynamicPropertiesDeserializer<'a> { - type Value = DynamicProperties; - fn deserialize(self, deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - deserializer.deserialize_map(DynamicPropertyMapVisiter { - registry: self.registry, - current_type_name: self.current_type_name, - }) - } -} - -pub struct DynamicPropertyMapVisiter<'a> { - registry: &'a PropertyTypeRegistry, - current_type_name: Rc>>, -} - -impl<'a, 'de> Visitor<'de> for DynamicPropertyMapVisiter<'a> { - type Value = DynamicProperties; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("properties map") - } - - fn visit_map(self, map: V) -> Result - where - V: MapAccess<'de>, - { - visit_map(map, self.registry, self.current_type_name) - } -} - pub struct MapSerializer<'a> { pub properties: &'a dyn Properties, } @@ -67,31 +83,47 @@ impl<'a> MapSerializer<'a> { } impl<'a> Serialize for MapSerializer<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_map(Some(2))?; + state.serialize_entry(TYPE_FIELD, self.properties.type_name())?; + state.serialize_entry( + MAP_FIELD, + &MapValueSerializer { + properties: self.properties, + }, + )?; + state.end() + } +} + +pub struct MapValueSerializer<'a> { + pub properties: &'a dyn Properties, +} + +impl<'a> Serialize for MapValueSerializer<'a> { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { let mut state = serializer.serialize_map(Some(self.properties.prop_len()))?; - state.serialize_entry("type", self.properties.type_name())?; for (index, property) in self.properties.iter_props().enumerate() { let name = self.properties.prop_name(index).unwrap(); - if property.is_sequence() { - state.serialize_entry(name, &SeqSerializer { property })?; - } else { - state.serialize_entry(name, property.serializable().borrow())?; - } + state.serialize_entry(name, property.serializable().borrow())?; } state.end() } } pub struct SeqSerializer<'a> { - pub property: &'a dyn Property, + pub properties: &'a dyn Properties, } impl<'a> SeqSerializer<'a> { - pub fn new(property: &'a dyn Property) -> Self { - SeqSerializer { property } + pub fn new(properties: &'a dyn Properties) -> Self { + SeqSerializer { properties } } } @@ -101,22 +133,22 @@ impl<'a> Serialize for SeqSerializer<'a> { S: serde::Serializer, { let mut state = serializer.serialize_map(Some(2))?; - if let Some(properties) = self.property.as_properties() { - state.serialize_entry("seq_type", self.property.type_name())?; - state.serialize_entry("data", &PropertiesSeqSerializer { properties })?; - } else { - state.serialize_entry("seq_value_type", self.property.type_name())?; - state.serialize_entry("data", self.property.serializable().borrow())?; - } + state.serialize_entry(TYPE_FIELD, self.properties.type_name())?; + state.serialize_entry( + SEQ_FIELD, + &SeqValueSerializer { + properties: self.properties, + }, + )?; state.end() } } -pub struct PropertiesSeqSerializer<'a> { +pub struct SeqValueSerializer<'a> { pub properties: &'a dyn Properties, } -impl<'a> Serialize for PropertiesSeqSerializer<'a> { +impl<'a> Serialize for SeqValueSerializer<'a> { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, @@ -130,8 +162,8 @@ impl<'a> Serialize for PropertiesSeqSerializer<'a> { } pub struct PropertyDeserializer<'a> { - pub registry: &'a PropertyTypeRegistry, - pub current_type_name: Rc>>, + type_name: Option<&'a str>, + registry: &'a PropertyTypeRegistry, } impl<'a, 'de> DeserializeSeed<'de> for PropertyDeserializer<'a> { @@ -140,37 +172,41 @@ impl<'a, 'de> DeserializeSeed<'de> for PropertyDeserializer<'a> { where D: serde::Deserializer<'de>, { - deserializer.deserialize_any(AnyPropVisiter { - property_type_registry: self.registry, - current_type_name: self.current_type_name, - }) + if let Some(type_name) = self.type_name { + let registration = self.registry.get_short(type_name).ok_or_else(|| { + de::Error::custom(format!("TypeRegistration is missing for {}", type_name)) + })?; + let mut erased = erased_serde::Deserializer::erase(deserializer); + (registration.deserialize)(&mut erased, self.registry) + .map_err(<>::Error as serde::de::Error>::custom) + } else { + deserializer.deserialize_any(AnyPropVisiter { + registry: self.registry, + }) + } } } - -pub struct PropSeqDeserializer<'a> { +pub struct SeqPropertyDeserializer<'a> { registry: &'a PropertyTypeRegistry, - current_type_name: Rc>>, } -impl<'a, 'de> DeserializeSeed<'de> for PropSeqDeserializer<'a> { +impl<'a, 'de> DeserializeSeed<'de> for SeqPropertyDeserializer<'a> { type Value = DynamicProperties; fn deserialize(self, deserializer: D) -> Result where D: serde::Deserializer<'de>, { - deserializer.deserialize_seq(PropSeqVisiter { + deserializer.deserialize_seq(SeqPropertyVisiter { registry: self.registry, - current_type_name: self.current_type_name.clone(), }) } } -pub struct PropSeqVisiter<'a> { +pub struct SeqPropertyVisiter<'a> { registry: &'a PropertyTypeRegistry, - current_type_name: Rc>>, } -impl<'a, 'de> Visitor<'de> for PropSeqVisiter<'a> { +impl<'a, 'de> Visitor<'de> for SeqPropertyVisiter<'a> { type Value = DynamicProperties; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("property value") @@ -183,7 +219,7 @@ impl<'a, 'de> Visitor<'de> for PropSeqVisiter<'a> { let mut dynamic_properties = DynamicProperties::seq(); while let Some(prop) = seq.next_element_seed(PropertyDeserializer { registry: self.registry, - current_type_name: self.current_type_name.clone(), + type_name: None, })? { dynamic_properties.push(prop, None); } @@ -191,40 +227,59 @@ impl<'a, 'de> Visitor<'de> for PropSeqVisiter<'a> { } } -pub struct MapValueDeserializer<'a> { +pub struct MapPropertyDeserializer<'a> { registry: &'a PropertyTypeRegistry, - current_type_name: Rc>>, } -impl<'a, 'de> DeserializeSeed<'de> for MapValueDeserializer<'a> { - type Value = Box; - fn deserialize(self, deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - if self.current_type_name.borrow().is_some() { - let registration = { - let current_type_name = self.current_type_name.borrow(); - let type_name = current_type_name.as_ref().unwrap(); - self.registry.get_short(type_name).ok_or_else(|| { - de::Error::custom(format!("TypeRegistration is missing for {}", type_name)) - })? - }; - let mut erased = erased_serde::Deserializer::erase(deserializer); - (registration.deserialize)(&mut erased, self.registry) - .map_err(<>::Error as serde::de::Error>::custom) - } else { - deserializer.deserialize_any(AnyPropVisiter { - property_type_registry: self.registry, - current_type_name: self.current_type_name, - }) +impl<'a> MapPropertyDeserializer<'a> { + pub fn new(registry: &'a PropertyTypeRegistry) -> Self { + MapPropertyDeserializer { + registry, } } } +impl<'a, 'de> DeserializeSeed<'de> for MapPropertyDeserializer<'a> { + type Value = DynamicProperties; + fn deserialize(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_map(MapPropertyVisiter { + registry: self.registry, + }) + } +} + +struct MapPropertyVisiter<'a> { + registry: &'a PropertyTypeRegistry, +} + +impl<'a, 'de> Visitor<'de> for MapPropertyVisiter<'a> { + type Value = DynamicProperties; + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("map value") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut dynamic_properties = DynamicProperties::map(); + while let Some(key) = map.next_key::()? { + let property = map.next_value_seed(PropertyDeserializer { + registry: self.registry, + type_name: None, + })?; + dynamic_properties.set_box(&key, property); + } + + Ok(dynamic_properties) + } +} + struct AnyPropVisiter<'a> { - property_type_registry: &'a PropertyTypeRegistry, - current_type_name: Rc>>, + registry: &'a PropertyTypeRegistry, } impl<'a, 'de> Visitor<'de> for AnyPropVisiter<'a> { @@ -324,57 +379,53 @@ impl<'a, 'de> Visitor<'de> for AnyPropVisiter<'a> { Ok(Box::new(v.to_string())) } - fn visit_map(self, map: V) -> Result + fn visit_map(self, mut map: V) -> Result where V: MapAccess<'de>, { - Ok(Box::new(visit_map( - map, - self.property_type_registry, - self.current_type_name, - )?)) - } -} - -fn visit_map<'a, 'de, V>( - mut map: V, - property_type_registry: &'a PropertyTypeRegistry, - current_type_name: Rc>>, -) -> Result -where - V: MapAccess<'de>, -{ - let mut dynamic_properties = DynamicProperties::map(); - let mut type_name: Option = None; - let mut is_seq = false; - // TODO: support seq_value_type - while let Some(key) = map.next_key::()? { - if key == "type" { - type_name = Some(map.next_value()?); - } else if key == "seq_type" { - type_name = Some(map.next_value()?); - is_seq = true; - } else if is_seq { - if key != "data" { - return Err(de::Error::custom( - "seq_type must be immediately followed by a data field", - )); + let mut type_name: Option = None; + while let Some(key) = map.next_key::()? { + match key.as_str() { + TYPE_FIELD => { + type_name = Some(map.next_value()?); + } + MAP_FIELD => { + let type_name = type_name + .take() + .ok_or_else(|| de::Error::missing_field(TYPE_FIELD))?; + let mut dynamic_properties = + map.next_value_seed(MapPropertyDeserializer { registry: self.registry })?; + dynamic_properties.type_name = type_name.to_string(); + return Ok(Box::new( + dynamic_properties, + )); + } + SEQ_FIELD => { + let type_name = type_name + .take() + .ok_or_else(|| de::Error::missing_field(TYPE_FIELD))?; + let mut dynamic_properties = + map.next_value_seed(SeqPropertyDeserializer { registry: self.registry })?; + dynamic_properties.type_name = type_name; + return Ok(Box::new( + dynamic_properties, + )); + } + VALUE_FIELD => { + let type_name = type_name + .take() + .ok_or_else(|| de::Error::missing_field(TYPE_FIELD))?; + return map.next_value_seed( + PropertyDeserializer { + registry: self.registry, + type_name: Some(&type_name), + }, + ); + } + _ => return Err(de::Error::unknown_field(key.as_str(), &[])), } - dynamic_properties = map.next_value_seed(PropSeqDeserializer { - registry: property_type_registry, - current_type_name: current_type_name.clone(), - })?; - break; - } else { - let prop = map.next_value_seed(MapValueDeserializer { - registry: property_type_registry, - current_type_name: current_type_name.clone(), - })?; - dynamic_properties.set_box(&key, prop); } - } - let type_name = type_name.ok_or_else(|| de::Error::missing_field("type"))?; - dynamic_properties.type_name = type_name.to_string(); - Ok(dynamic_properties) -} + Err(de::Error::custom("Maps in this location must have the \'type\' field and one of the following fields: \'map\', \'seq\', \'value\'")) + } +} \ No newline at end of file diff --git a/crates/bevy_property/src/ron.rs b/crates/bevy_property/src/ron.rs index ed9d5742b0..a2d41548c8 100644 --- a/crates/bevy_property/src/ron.rs +++ b/crates/bevy_property/src/ron.rs @@ -1,24 +1,12 @@ -use crate::{ - property_serde::DynamicPropertiesDeserializer, DynamicProperties, PropertyTypeRegistry, -}; +use crate::{property_serde::MapPropertyDeserializer, DynamicProperties, PropertyTypeRegistry}; use ron::de::Deserializer; use serde::de::DeserializeSeed; -use std::{cell::RefCell, rc::Rc}; pub fn deserialize_dynamic_properties( ron_string: &str, property_type_registry: &PropertyTypeRegistry, ) -> Result { let mut deserializer = Deserializer::from_str(&ron_string).unwrap(); - let last_type_name = Rc::new(RefCell::new(None)); - let mut callback = |ident: &Option<&[u8]>| { - let mut last_type_name = last_type_name.borrow_mut(); - *last_type_name = ident.map(|i| String::from_utf8(i.to_vec()).unwrap()); - }; - deserializer.set_callback(&mut callback); - let dynamic_properties_deserializer = DynamicPropertiesDeserializer { - current_type_name: last_type_name.clone(), - registry: &property_type_registry, - }; + let dynamic_properties_deserializer = MapPropertyDeserializer::new(&property_type_registry); dynamic_properties_deserializer.deserialize(&mut deserializer) } diff --git a/crates/bevy_scene/src/scene_loader.rs b/crates/bevy_scene/src/scene_loader.rs index 00273adb17..0ee4fc5650 100644 --- a/crates/bevy_scene/src/scene_loader.rs +++ b/crates/bevy_scene/src/scene_loader.rs @@ -5,7 +5,7 @@ use bevy_asset::AssetLoader; use bevy_component_registry::PropertyTypeRegistryContext; use legion::prelude::Resources; use serde::de::DeserializeSeed; -use std::{cell::RefCell, path::Path, rc::Rc}; +use std::path::Path; pub struct SceneLoader { property_type_registry: PropertyTypeRegistryContext, @@ -24,19 +24,9 @@ impl AssetLoader for SceneLoader { fn from_bytes(&self, _asset_path: &Path, bytes: Vec) -> Result { let registry = self.property_type_registry.value.read().unwrap(); let mut deserializer = ron::de::Deserializer::from_bytes(&bytes).unwrap(); - let current_type_name = Rc::new(RefCell::new(None)); let scene_deserializer = SceneDeserializer { property_type_registry: ®istry, - current_type_name: current_type_name.clone(), }; - - // this callback is executed whenever an explicit type name is encountered in a map - let mut callback = |ident: &Option<&[u8]>| { - let mut last_type_name = current_type_name.borrow_mut(); - *last_type_name = ident.map(|i| String::from_utf8(i.to_vec()).unwrap()); - }; - deserializer.set_callback(&mut callback); - let scene = scene_deserializer.deserialize(&mut deserializer).unwrap(); Ok(scene) } @@ -44,4 +34,4 @@ impl AssetLoader for SceneLoader { static EXTENSIONS: &[&str] = &["scn"]; EXTENSIONS } -} \ No newline at end of file +} diff --git a/crates/bevy_scene/src/serde.rs b/crates/bevy_scene/src/serde.rs index ba25a669ba..692353771a 100644 --- a/crates/bevy_scene/src/serde.rs +++ b/crates/bevy_scene/src/serde.rs @@ -1,11 +1,12 @@ use crate::{Entity, Scene}; use anyhow::Result; -use bevy_property::{DynamicProperties, PropertyTypeRegistry, property_serde::DynamicPropertiesDeserializer}; +use bevy_property::{ + property_serde::MapPropertyDeserializer, DynamicProperties, PropertyTypeRegistry, +}; use serde::{ de::{DeserializeSeed, Error, MapAccess, SeqAccess, Visitor}, Deserialize, Serialize, }; -use std::{cell::RefCell, rc::Rc}; impl Serialize for Scene { fn serialize(&self, serializer: S) -> Result @@ -18,7 +19,6 @@ impl Serialize for Scene { pub struct SceneDeserializer<'a> { pub property_type_registry: &'a PropertyTypeRegistry, - pub current_type_name: Rc>>, } impl<'a, 'de> DeserializeSeed<'de> for SceneDeserializer<'a> { @@ -30,7 +30,6 @@ impl<'a, 'de> DeserializeSeed<'de> for SceneDeserializer<'a> { let mut scene = Scene::default(); scene.entities = deserializer.deserialize_seq(SceneEntitySeqVisiter { property_type_registry: self.property_type_registry, - current_type_name: self.current_type_name, })?; Ok(scene) @@ -39,7 +38,6 @@ impl<'a, 'de> DeserializeSeed<'de> for SceneDeserializer<'a> { struct SceneEntitySeqVisiter<'a> { pub property_type_registry: &'a PropertyTypeRegistry, - pub current_type_name: Rc>>, } impl<'a, 'de> Visitor<'de> for SceneEntitySeqVisiter<'a> { @@ -55,7 +53,6 @@ impl<'a, 'de> Visitor<'de> for SceneEntitySeqVisiter<'a> { let mut entities = Vec::new(); while let Some(entity) = seq.next_element_seed(SceneEntityDeserializer { property_type_registry: self.property_type_registry, - current_type_name: self.current_type_name.clone(), })? { entities.push(entity); } @@ -66,7 +63,6 @@ impl<'a, 'de> Visitor<'de> for SceneEntitySeqVisiter<'a> { pub struct SceneEntityDeserializer<'a> { pub property_type_registry: &'a PropertyTypeRegistry, - pub current_type_name: Rc>>, } impl<'a, 'de> DeserializeSeed<'de> for SceneEntityDeserializer<'a> { @@ -79,8 +75,7 @@ impl<'a, 'de> DeserializeSeed<'de> for SceneEntityDeserializer<'a> { "Entity", &["id", "components"], SceneEntityVisiter { - property_type_registry: self.property_type_registry, - current_type_name: self.current_type_name, + registry: self.property_type_registry, }, ) } @@ -97,8 +92,7 @@ pub const ENTITY_FIELD_ID: &str = "id"; pub const ENTITY_FIELD_COMPONENTS: &str = "components"; struct SceneEntityVisiter<'a> { - pub property_type_registry: &'a PropertyTypeRegistry, - pub current_type_name: Rc>>, + pub registry: &'a PropertyTypeRegistry, } impl<'a, 'de> Visitor<'de> for SceneEntityVisiter<'a> { @@ -127,8 +121,7 @@ impl<'a, 'de> Visitor<'de> for SceneEntityVisiter<'a> { } components = Some(map.next_value_seed(ComponentVecDeserializer { - current_type_name: self.current_type_name.clone(), - registry: self.property_type_registry, + registry: self.registry, })?); } } @@ -150,7 +143,6 @@ impl<'a, 'de> Visitor<'de> for SceneEntityVisiter<'a> { pub struct ComponentVecDeserializer<'a> { pub registry: &'a PropertyTypeRegistry, - pub current_type_name: Rc>>, } impl<'a, 'de> DeserializeSeed<'de> for ComponentVecDeserializer<'a> { @@ -161,14 +153,12 @@ impl<'a, 'de> DeserializeSeed<'de> for ComponentVecDeserializer<'a> { { deserializer.deserialize_seq(ComponentSeqVisiter { registry: self.registry, - current_type_name: self.current_type_name, }) } } struct ComponentSeqVisiter<'a> { pub registry: &'a PropertyTypeRegistry, - pub current_type_name: Rc>>, } impl<'a, 'de> Visitor<'de> for ComponentSeqVisiter<'a> { @@ -182,10 +172,9 @@ impl<'a, 'de> Visitor<'de> for ComponentSeqVisiter<'a> { A: SeqAccess<'de>, { let mut dynamic_properties = Vec::new(); - while let Some(entity) = seq.next_element_seed(DynamicPropertiesDeserializer { - current_type_name: self.current_type_name.clone(), - registry: self.registry, - })? { + while let Some(entity) = + seq.next_element_seed(MapPropertyDeserializer::new(self.registry))? + { dynamic_properties.push(entity); }