rework scene format. use property value serializer, removing the need for ron fork / enabling any serde target

This commit is contained in:
Carter Anderson 2020-05-27 13:07:32 -07:00
parent d86d3ddcbc
commit 59dbf22e39
11 changed files with 295 additions and 282 deletions

View File

@ -148,10 +148,6 @@ pub fn derive_properties(input: TokenStream) -> TokenStream {
fn iter_props(&self) -> #bevy_property_path::PropertyIter { fn iter_props(&self) -> #bevy_property_path::PropertyIter {
#bevy_property_path::PropertyIter::new(self) #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 { impl #impl_generics #bevy_property_path::Property for #struct_name#ty_generics {
@ -181,11 +177,11 @@ pub fn derive_properties(input: TokenStream) -> TokenStream {
#[inline] #[inline]
fn apply(&mut self, value: &dyn #bevy_property_path::Property) { fn apply(&mut self, value: &dyn #bevy_property_path::Property) {
if let Some(properties) = value.as_properties() { if let Some(properties) = value.as_properties() {
if properties.properties_type() != self.properties_type() { if properties.property_type() != self.property_type() {
panic!( panic!(
"Properties type mismatch. This type is {:?} but the applied type is {:?}", "Properties type mismatch. This type is {:?} but the applied type is {:?}",
self.properties_type(), self.property_type(),
properties.properties_type() properties.property_type()
); );
} }
for (i, prop) in properties.iter_props().enumerate() { for (i, prop) in properties.iter_props().enumerate() {
@ -202,8 +198,12 @@ pub fn derive_properties(input: TokenStream) -> TokenStream {
Some(self) Some(self)
} }
fn serializable(&self) -> #bevy_property_path::Serializable { fn serializable(&self) -> #bevy_property_path::property_serde::Serializable {
#bevy_property_path::Serializable::Owned(Box::new(#bevy_property_path::property_serde::MapSerializer::new(self))) #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] #[inline]
fn serializable(&self) -> #bevy_property_path::Serializable { fn serializable(&self) -> #bevy_property_path::property_serde::Serializable {
#bevy_property_path::Serializable::Borrowed(self) #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) } quote! { #serialize_fn(self) }
} else { } else {
quote! { 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 { let deserialize_fn = if let Some(deserialize_fn) = property_def.deserialize_fn {
@ -387,9 +395,13 @@ pub fn impl_property(input: TokenStream) -> TokenStream {
} }
#[inline] #[inline]
fn serializable(&self) -> #bevy_property_path::Serializable { fn serializable(&self) -> #bevy_property_path::property_serde::Serializable {
#serialize_fn #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 { impl #impl_generics #bevy_property_path::DeserializeProperty for #ty#ty_generics #where_clause {

View File

@ -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}; use std::{any::Any, borrow::Cow, collections::HashMap};
pub struct DynamicProperties { pub struct DynamicProperties {
@ -6,7 +6,7 @@ pub struct DynamicProperties {
pub props: Vec<Box<dyn Property>>, pub props: Vec<Box<dyn Property>>,
pub prop_names: Vec<Cow<'static, str>>, pub prop_names: Vec<Cow<'static, str>>,
pub prop_indices: HashMap<Cow<'static, str>, usize>, pub prop_indices: HashMap<Cow<'static, str>, usize>,
pub properties_type: PropertiesType, pub property_type: PropertyType,
} }
impl DynamicProperties { impl DynamicProperties {
@ -16,7 +16,7 @@ impl DynamicProperties {
props: Default::default(), props: Default::default(),
prop_names: Default::default(), prop_names: Default::default(),
prop_indices: Default::default(), prop_indices: Default::default(),
properties_type: PropertiesType::Map, property_type: PropertyType::Map,
} }
} }
@ -26,7 +26,7 @@ impl DynamicProperties {
props: Default::default(), props: Default::default(),
prop_names: Default::default(), prop_names: Default::default(),
prop_indices: Default::default(), prop_indices: Default::default(),
properties_type: PropertiesType::Seq, property_type: PropertyType::Seq,
} }
} }
@ -88,9 +88,10 @@ impl Properties for DynamicProperties {
#[inline] #[inline]
fn prop_name(&self, index: usize) -> Option<&str> { fn prop_name(&self, index: usize) -> Option<&str> {
match self.properties_type { match self.property_type {
PropertiesType::Seq => None, PropertyType::Seq => None,
PropertiesType::Map => self.prop_names.get(index).map(|name| name.as_ref()), 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, index: 0,
} }
} }
#[inline]
fn properties_type(&self) -> PropertiesType {
self.properties_type
}
} }
impl Property for DynamicProperties { impl Property for DynamicProperties {
@ -142,25 +138,26 @@ impl Property for DynamicProperties {
#[inline] #[inline]
fn apply(&mut self, value: &dyn Property) { fn apply(&mut self, value: &dyn Property) {
if let Some(properties) = value.as_properties() { if let Some(properties) = value.as_properties() {
if properties.properties_type() != self.properties_type { if properties.property_type() != self.property_type {
panic!( panic!(
"Properties type mismatch. This type is {:?} but the applied type is {:?}", "Properties type mismatch. This type is {:?} but the applied type is {:?}",
self.properties_type, self.property_type,
properties.properties_type() properties.property_type()
); );
} }
match self.properties_type { match self.property_type {
PropertiesType::Map => { PropertyType::Map => {
for (i, prop) in properties.iter_props().enumerate() { for (i, prop) in properties.iter_props().enumerate() {
let name = properties.prop_name(i).unwrap(); let name = properties.prop_name(i).unwrap();
self.prop_mut(name).map(|p| p.apply(prop)); self.prop_mut(name).map(|p| p.apply(prop));
} }
} }
PropertiesType::Seq => { PropertyType::Seq => {
for (i, prop) in properties.iter_props().enumerate() { for (i, prop) in properties.iter_props().enumerate() {
self.prop_with_index_mut(i).map(|p| p.apply(prop)); self.prop_with_index_mut(i).map(|p| p.apply(prop));
} }
} }
_ => panic!("DynamicProperties cannot be Value types"),
} }
} else { } else {
panic!("attempted to apply non-Properties type to Properties type"); panic!("attempted to apply non-Properties type to Properties type");
@ -171,11 +168,11 @@ impl Property for DynamicProperties {
Some(self) Some(self)
} }
fn is_sequence(&self) -> bool {
self.properties_type == PropertiesType::Seq
}
fn serializable(&self) -> Serializable { fn serializable(&self) -> Serializable {
Serializable::Borrowed(self) Serializable::Borrowed(self)
} }
fn property_type(&self) -> PropertyType {
self.property_type
}
} }

View File

@ -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 erased_serde::Deserializer;
use legion::prelude::Entity; use legion::prelude::Entity;
use serde::Deserialize; use serde::Deserialize;

View File

@ -1,4 +1,4 @@
use crate::{Serializable, Property}; use crate::{Property, PropertyType, property_serde::Serializable};
use serde::Serialize; use serde::Serialize;
use smallvec::{Array, SmallVec}; use smallvec::{Array, SmallVec};
use std::any::Any; use std::any::Any;
@ -43,4 +43,8 @@ where
fn serializable(&self) -> Serializable { fn serializable(&self) -> Serializable {
Serializable::Borrowed(self) Serializable::Borrowed(self)
} }
fn property_type(&self) -> PropertyType {
PropertyType::Value
}
} }

View File

@ -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 serde::{Serialize, Deserialize};
use std::{ use std::{
any::Any, any::Any,
@ -32,9 +32,6 @@ where
fn iter_props(&self) -> PropertyIter { fn iter_props(&self) -> PropertyIter {
PropertyIter::new(self) PropertyIter::new(self)
} }
fn properties_type(&self) -> PropertiesType {
PropertiesType::Seq
}
} }
impl<T> Property for Vec<T> impl<T> Property for Vec<T>
@ -56,11 +53,11 @@ where
} }
fn set(&mut self, value: &dyn Property) { fn set(&mut self, value: &dyn Property) {
if let Some(properties) = value.as_properties() { if let Some(properties) = value.as_properties() {
if properties.properties_type() != self.properties_type() { if properties.property_type() != self.property_type() {
panic!( panic!(
"Properties type mismatch. This type is {:?} but the applied type is {:?}", "Properties type mismatch. This type is {:?} but the applied type is {:?}",
self.properties_type(), self.property_type(),
properties.properties_type() properties.property_type()
); );
} }
for (i, prop) in properties.iter_props().enumerate() { for (i, prop) in properties.iter_props().enumerate() {
@ -78,10 +75,6 @@ where
Some(self) Some(self)
} }
fn is_sequence(&self) -> bool {
true
}
fn serializable(&self) -> Serializable { fn serializable(&self) -> Serializable {
Serializable::Owned(Box::new(SeqSerializer::new(self))) Serializable::Owned(Box::new(SeqSerializer::new(self)))
} }

View File

@ -1,10 +1,4 @@
use crate::{DynamicProperties, Property, PropertyVal}; use crate::{DynamicProperties, Property, PropertyType, PropertyVal};
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
pub enum PropertiesType {
Map,
Seq,
}
pub trait Properties: Property { pub trait Properties: Property {
fn prop(&self, name: &str) -> Option<&dyn 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_name(&self, index: usize) -> Option<&str>;
fn prop_len(&self) -> usize; fn prop_len(&self) -> usize;
fn iter_props(&self) -> PropertyIter; fn iter_props(&self) -> PropertyIter;
fn properties_type(&self) -> PropertiesType;
fn set_prop(&mut self, name: &str, value: &dyn Property) { fn set_prop(&mut self, name: &str, value: &dyn Property) {
if let Some(prop) = self.prop_mut(name) { if let Some(prop) = self.prop_mut(name) {
prop.set(value); prop.set(value);
@ -22,25 +15,27 @@ pub trait Properties: Property {
panic!("prop does not exist: {}", name); panic!("prop does not exist: {}", name);
} }
} }
fn to_dynamic(&self) -> DynamicProperties fn to_dynamic(&self) -> DynamicProperties {
{ let mut dynamic_props = match self.property_type() {
let mut dynamic_props = match self.properties_type() { PropertyType::Map => {
PropertiesType::Map => {
let mut dynamic_props = DynamicProperties::map(); let mut dynamic_props = DynamicProperties::map();
for (i, prop) in self.iter_props().enumerate() { 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.set_box(name, prop.clone_prop());
} }
dynamic_props dynamic_props
}, }
PropertiesType::Seq => { PropertyType::Seq => {
let mut dynamic_props = DynamicProperties::seq(); let mut dynamic_props = DynamicProperties::seq();
for prop in self.iter_props() { for prop in self.iter_props() {
dynamic_props.push(prop.clone_prop(), None); dynamic_props.push(prop.clone_prop(), None);
} }
dynamic_props dynamic_props
} }
} ; _ => panic!("Properties cannot be Value types"),
};
dynamic_props.type_name = self.type_name().to_string(); dynamic_props.type_name = self.type_name().to_string();
dynamic_props dynamic_props
@ -92,4 +87,4 @@ where
panic!("prop does not exist or is incorrect type: {}", name); panic!("prop does not exist or is incorrect type: {}", name);
} }
} }
} }

View File

@ -1,20 +1,12 @@
use crate::{PropertyTypeRegistry, Properties}; use crate::{property_serde::Serializable, Properties, PropertyTypeRegistry};
use erased_serde::Deserializer;
use std::any::Any; use std::any::Any;
use erased_serde::{Deserializer, Serialize};
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
pub enum Serializable<'a> { pub enum PropertyType {
Owned(Box<dyn Serialize + 'a>), Map,
Borrowed(&'a dyn Serialize), Seq,
} Value,
impl<'a> Serializable<'a> {
pub fn borrow(&self) -> &dyn Serialize {
match self {
Serializable::Borrowed(serialize) => serialize,
Serializable::Owned(serialize) => serialize,
}
}
} }
// TODO: consider removing send + sync requirements // TODO: consider removing send + sync requirements
@ -25,18 +17,20 @@ pub trait Property: Send + Sync + Any + 'static {
fn clone_prop(&self) -> Box<dyn Property>; fn clone_prop(&self) -> Box<dyn Property>;
fn set(&mut self, value: &dyn Property); fn set(&mut self, value: &dyn Property);
fn apply(&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> { fn as_properties(&self) -> Option<&dyn Properties> {
None None
} }
fn is_sequence(&self) -> bool {
false
}
fn serializable(&self) -> Serializable; fn serializable(&self) -> Serializable;
} }
pub trait DeserializeProperty { pub trait DeserializeProperty {
fn deserialize(deserializer: &mut dyn Deserializer, property_type_registry: &PropertyTypeRegistry) -> Result<Box<dyn Property>, erased_serde::Error>; fn deserialize(
deserializer: &mut dyn Deserializer,
property_type_registry: &PropertyTypeRegistry,
) -> Result<Box<dyn Property>, erased_serde::Error>;
} }
pub trait PropertyVal { pub trait PropertyVal {
@ -58,4 +52,4 @@ impl PropertyVal for dyn Property {
panic!("prop value is not {}", std::any::type_name::<T>()); panic!("prop value is not {}", std::any::type_name::<T>());
} }
} }
} }

View File

@ -1,61 +1,77 @@
use crate::{DynamicProperties, Properties, PropertiesType, Property, PropertyTypeRegistry}; use crate::{DynamicProperties, Properties, Property, PropertyType, PropertyTypeRegistry};
use de::SeqAccess; use de::SeqAccess;
use serde::{ use serde::{
de::{self, DeserializeSeed, MapAccess, Visitor}, de::{self, DeserializeSeed, MapAccess, Visitor},
ser::{SerializeMap, SerializeSeq}, ser::{SerializeMap, SerializeSeq},
Serialize, 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<dyn erased_serde::Serialize + 'a>),
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<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
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 { impl Serialize for DynamicProperties {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
S: serde::Serializer, S: serde::Serializer,
{ {
match self.properties_type { match self.property_type {
PropertiesType::Map => MapSerializer::new(self).serialize(serializer), PropertyType::Map => MapSerializer::new(self).serialize(serializer),
PropertiesType::Seq => SeqSerializer::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<RefCell<Option<String>>>,
}
impl<'a, 'de> DeserializeSeed<'de> for DynamicPropertiesDeserializer<'a> {
type Value = DynamicProperties;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
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<RefCell<Option<String>>>,
}
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<V>(self, map: V) -> Result<Self::Value, V::Error>
where
V: MapAccess<'de>,
{
visit_map(map, self.registry, self.current_type_name)
}
}
pub struct MapSerializer<'a> { pub struct MapSerializer<'a> {
pub properties: &'a dyn Properties, pub properties: &'a dyn Properties,
} }
@ -67,31 +83,47 @@ impl<'a> MapSerializer<'a> {
} }
impl<'a> Serialize for MapSerializer<'a> { impl<'a> Serialize for MapSerializer<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
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<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
S: serde::Serializer, S: serde::Serializer,
{ {
let mut state = serializer.serialize_map(Some(self.properties.prop_len()))?; 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() { for (index, property) in self.properties.iter_props().enumerate() {
let name = self.properties.prop_name(index).unwrap(); let name = self.properties.prop_name(index).unwrap();
if property.is_sequence() { state.serialize_entry(name, property.serializable().borrow())?;
state.serialize_entry(name, &SeqSerializer { property })?;
} else {
state.serialize_entry(name, property.serializable().borrow())?;
}
} }
state.end() state.end()
} }
} }
pub struct SeqSerializer<'a> { pub struct SeqSerializer<'a> {
pub property: &'a dyn Property, pub properties: &'a dyn Properties,
} }
impl<'a> SeqSerializer<'a> { impl<'a> SeqSerializer<'a> {
pub fn new(property: &'a dyn Property) -> Self { pub fn new(properties: &'a dyn Properties) -> Self {
SeqSerializer { property } SeqSerializer { properties }
} }
} }
@ -101,22 +133,22 @@ impl<'a> Serialize for SeqSerializer<'a> {
S: serde::Serializer, S: serde::Serializer,
{ {
let mut state = serializer.serialize_map(Some(2))?; let mut state = serializer.serialize_map(Some(2))?;
if let Some(properties) = self.property.as_properties() { state.serialize_entry(TYPE_FIELD, self.properties.type_name())?;
state.serialize_entry("seq_type", self.property.type_name())?; state.serialize_entry(
state.serialize_entry("data", &PropertiesSeqSerializer { properties })?; SEQ_FIELD,
} else { &SeqValueSerializer {
state.serialize_entry("seq_value_type", self.property.type_name())?; properties: self.properties,
state.serialize_entry("data", self.property.serializable().borrow())?; },
} )?;
state.end() state.end()
} }
} }
pub struct PropertiesSeqSerializer<'a> { pub struct SeqValueSerializer<'a> {
pub properties: &'a dyn Properties, pub properties: &'a dyn Properties,
} }
impl<'a> Serialize for PropertiesSeqSerializer<'a> { impl<'a> Serialize for SeqValueSerializer<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
S: serde::Serializer, S: serde::Serializer,
@ -130,8 +162,8 @@ impl<'a> Serialize for PropertiesSeqSerializer<'a> {
} }
pub struct PropertyDeserializer<'a> { pub struct PropertyDeserializer<'a> {
pub registry: &'a PropertyTypeRegistry, type_name: Option<&'a str>,
pub current_type_name: Rc<RefCell<Option<String>>>, registry: &'a PropertyTypeRegistry,
} }
impl<'a, 'de> DeserializeSeed<'de> for PropertyDeserializer<'a> { impl<'a, 'de> DeserializeSeed<'de> for PropertyDeserializer<'a> {
@ -140,37 +172,41 @@ impl<'a, 'de> DeserializeSeed<'de> for PropertyDeserializer<'a> {
where where
D: serde::Deserializer<'de>, D: serde::Deserializer<'de>,
{ {
deserializer.deserialize_any(AnyPropVisiter { if let Some(type_name) = self.type_name {
property_type_registry: self.registry, let registration = self.registry.get_short(type_name).ok_or_else(|| {
current_type_name: self.current_type_name, 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(<<D as serde::Deserializer<'de>>::Error as serde::de::Error>::custom)
} else {
deserializer.deserialize_any(AnyPropVisiter {
registry: self.registry,
})
}
} }
} }
pub struct SeqPropertyDeserializer<'a> {
pub struct PropSeqDeserializer<'a> {
registry: &'a PropertyTypeRegistry, registry: &'a PropertyTypeRegistry,
current_type_name: Rc<RefCell<Option<String>>>,
} }
impl<'a, 'de> DeserializeSeed<'de> for PropSeqDeserializer<'a> { impl<'a, 'de> DeserializeSeed<'de> for SeqPropertyDeserializer<'a> {
type Value = DynamicProperties; type Value = DynamicProperties;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where where
D: serde::Deserializer<'de>, D: serde::Deserializer<'de>,
{ {
deserializer.deserialize_seq(PropSeqVisiter { deserializer.deserialize_seq(SeqPropertyVisiter {
registry: self.registry, registry: self.registry,
current_type_name: self.current_type_name.clone(),
}) })
} }
} }
pub struct PropSeqVisiter<'a> { pub struct SeqPropertyVisiter<'a> {
registry: &'a PropertyTypeRegistry, registry: &'a PropertyTypeRegistry,
current_type_name: Rc<RefCell<Option<String>>>,
} }
impl<'a, 'de> Visitor<'de> for PropSeqVisiter<'a> { impl<'a, 'de> Visitor<'de> for SeqPropertyVisiter<'a> {
type Value = DynamicProperties; type Value = DynamicProperties;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("property value") formatter.write_str("property value")
@ -183,7 +219,7 @@ impl<'a, 'de> Visitor<'de> for PropSeqVisiter<'a> {
let mut dynamic_properties = DynamicProperties::seq(); let mut dynamic_properties = DynamicProperties::seq();
while let Some(prop) = seq.next_element_seed(PropertyDeserializer { while let Some(prop) = seq.next_element_seed(PropertyDeserializer {
registry: self.registry, registry: self.registry,
current_type_name: self.current_type_name.clone(), type_name: None,
})? { })? {
dynamic_properties.push(prop, 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, registry: &'a PropertyTypeRegistry,
current_type_name: Rc<RefCell<Option<String>>>,
} }
impl<'a, 'de> DeserializeSeed<'de> for MapValueDeserializer<'a> { impl<'a> MapPropertyDeserializer<'a> {
type Value = Box<dyn Property>; pub fn new(registry: &'a PropertyTypeRegistry) -> Self {
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> MapPropertyDeserializer {
where registry,
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(<<D as serde::Deserializer<'de>>::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, 'de> DeserializeSeed<'de> for MapPropertyDeserializer<'a> {
type Value = DynamicProperties;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
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<V>(self, mut map: V) -> Result<Self::Value, V::Error>
where
V: MapAccess<'de>,
{
let mut dynamic_properties = DynamicProperties::map();
while let Some(key) = map.next_key::<String>()? {
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> { struct AnyPropVisiter<'a> {
property_type_registry: &'a PropertyTypeRegistry, registry: &'a PropertyTypeRegistry,
current_type_name: Rc<RefCell<Option<String>>>,
} }
impl<'a, 'de> Visitor<'de> for AnyPropVisiter<'a> { 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())) Ok(Box::new(v.to_string()))
} }
fn visit_map<V>(self, map: V) -> Result<Self::Value, V::Error> fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
where where
V: MapAccess<'de>, V: MapAccess<'de>,
{ {
Ok(Box::new(visit_map( let mut type_name: Option<String> = None;
map, while let Some(key) = map.next_key::<String>()? {
self.property_type_registry, match key.as_str() {
self.current_type_name, TYPE_FIELD => {
)?)) type_name = Some(map.next_value()?);
} }
} MAP_FIELD => {
let type_name = type_name
fn visit_map<'a, 'de, V>( .take()
mut map: V, .ok_or_else(|| de::Error::missing_field(TYPE_FIELD))?;
property_type_registry: &'a PropertyTypeRegistry, let mut dynamic_properties =
current_type_name: Rc<RefCell<Option<String>>>, map.next_value_seed(MapPropertyDeserializer { registry: self.registry })?;
) -> Result<DynamicProperties, V::Error> dynamic_properties.type_name = type_name.to_string();
where return Ok(Box::new(
V: MapAccess<'de>, dynamic_properties,
{ ));
let mut dynamic_properties = DynamicProperties::map(); }
let mut type_name: Option<String> = None; SEQ_FIELD => {
let mut is_seq = false; let type_name = type_name
// TODO: support seq_value_type .take()
while let Some(key) = map.next_key::<String>()? { .ok_or_else(|| de::Error::missing_field(TYPE_FIELD))?;
if key == "type" { let mut dynamic_properties =
type_name = Some(map.next_value()?); map.next_value_seed(SeqPropertyDeserializer { registry: self.registry })?;
} else if key == "seq_type" { dynamic_properties.type_name = type_name;
type_name = Some(map.next_value()?); return Ok(Box::new(
is_seq = true; dynamic_properties,
} else if is_seq { ));
if key != "data" { }
return Err(de::Error::custom( VALUE_FIELD => {
"seq_type must be immediately followed by a data 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"))?; Err(de::Error::custom("Maps in this location must have the \'type\' field and one of the following fields: \'map\', \'seq\', \'value\'"))
dynamic_properties.type_name = type_name.to_string(); }
Ok(dynamic_properties) }
}

View File

@ -1,24 +1,12 @@
use crate::{ use crate::{property_serde::MapPropertyDeserializer, DynamicProperties, PropertyTypeRegistry};
property_serde::DynamicPropertiesDeserializer, DynamicProperties, PropertyTypeRegistry,
};
use ron::de::Deserializer; use ron::de::Deserializer;
use serde::de::DeserializeSeed; use serde::de::DeserializeSeed;
use std::{cell::RefCell, rc::Rc};
pub fn deserialize_dynamic_properties( pub fn deserialize_dynamic_properties(
ron_string: &str, ron_string: &str,
property_type_registry: &PropertyTypeRegistry, property_type_registry: &PropertyTypeRegistry,
) -> Result<DynamicProperties, ron::Error> { ) -> Result<DynamicProperties, ron::Error> {
let mut deserializer = Deserializer::from_str(&ron_string).unwrap(); let mut deserializer = Deserializer::from_str(&ron_string).unwrap();
let last_type_name = Rc::new(RefCell::new(None)); let dynamic_properties_deserializer = MapPropertyDeserializer::new(&property_type_registry);
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,
};
dynamic_properties_deserializer.deserialize(&mut deserializer) dynamic_properties_deserializer.deserialize(&mut deserializer)
} }

View File

@ -5,7 +5,7 @@ use bevy_asset::AssetLoader;
use bevy_component_registry::PropertyTypeRegistryContext; use bevy_component_registry::PropertyTypeRegistryContext;
use legion::prelude::Resources; use legion::prelude::Resources;
use serde::de::DeserializeSeed; use serde::de::DeserializeSeed;
use std::{cell::RefCell, path::Path, rc::Rc}; use std::path::Path;
pub struct SceneLoader { pub struct SceneLoader {
property_type_registry: PropertyTypeRegistryContext, property_type_registry: PropertyTypeRegistryContext,
@ -24,19 +24,9 @@ impl AssetLoader<Scene> for SceneLoader {
fn from_bytes(&self, _asset_path: &Path, bytes: Vec<u8>) -> Result<Scene> { fn from_bytes(&self, _asset_path: &Path, bytes: Vec<u8>) -> Result<Scene> {
let registry = self.property_type_registry.value.read().unwrap(); let registry = self.property_type_registry.value.read().unwrap();
let mut deserializer = ron::de::Deserializer::from_bytes(&bytes).unwrap(); let mut deserializer = ron::de::Deserializer::from_bytes(&bytes).unwrap();
let current_type_name = Rc::new(RefCell::new(None));
let scene_deserializer = SceneDeserializer { let scene_deserializer = SceneDeserializer {
property_type_registry: &registry, property_type_registry: &registry,
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(); let scene = scene_deserializer.deserialize(&mut deserializer).unwrap();
Ok(scene) Ok(scene)
} }
@ -44,4 +34,4 @@ impl AssetLoader<Scene> for SceneLoader {
static EXTENSIONS: &[&str] = &["scn"]; static EXTENSIONS: &[&str] = &["scn"];
EXTENSIONS EXTENSIONS
} }
} }

View File

@ -1,11 +1,12 @@
use crate::{Entity, Scene}; use crate::{Entity, Scene};
use anyhow::Result; use anyhow::Result;
use bevy_property::{DynamicProperties, PropertyTypeRegistry, property_serde::DynamicPropertiesDeserializer}; use bevy_property::{
property_serde::MapPropertyDeserializer, DynamicProperties, PropertyTypeRegistry,
};
use serde::{ use serde::{
de::{DeserializeSeed, Error, MapAccess, SeqAccess, Visitor}, de::{DeserializeSeed, Error, MapAccess, SeqAccess, Visitor},
Deserialize, Serialize, Deserialize, Serialize,
}; };
use std::{cell::RefCell, rc::Rc};
impl Serialize for Scene { impl Serialize for Scene {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@ -18,7 +19,6 @@ impl Serialize for Scene {
pub struct SceneDeserializer<'a> { pub struct SceneDeserializer<'a> {
pub property_type_registry: &'a PropertyTypeRegistry, pub property_type_registry: &'a PropertyTypeRegistry,
pub current_type_name: Rc<RefCell<Option<String>>>,
} }
impl<'a, 'de> DeserializeSeed<'de> for SceneDeserializer<'a> { 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(); let mut scene = Scene::default();
scene.entities = deserializer.deserialize_seq(SceneEntitySeqVisiter { scene.entities = deserializer.deserialize_seq(SceneEntitySeqVisiter {
property_type_registry: self.property_type_registry, property_type_registry: self.property_type_registry,
current_type_name: self.current_type_name,
})?; })?;
Ok(scene) Ok(scene)
@ -39,7 +38,6 @@ impl<'a, 'de> DeserializeSeed<'de> for SceneDeserializer<'a> {
struct SceneEntitySeqVisiter<'a> { struct SceneEntitySeqVisiter<'a> {
pub property_type_registry: &'a PropertyTypeRegistry, pub property_type_registry: &'a PropertyTypeRegistry,
pub current_type_name: Rc<RefCell<Option<String>>>,
} }
impl<'a, 'de> Visitor<'de> for SceneEntitySeqVisiter<'a> { 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(); let mut entities = Vec::new();
while let Some(entity) = seq.next_element_seed(SceneEntityDeserializer { while let Some(entity) = seq.next_element_seed(SceneEntityDeserializer {
property_type_registry: self.property_type_registry, property_type_registry: self.property_type_registry,
current_type_name: self.current_type_name.clone(),
})? { })? {
entities.push(entity); entities.push(entity);
} }
@ -66,7 +63,6 @@ impl<'a, 'de> Visitor<'de> for SceneEntitySeqVisiter<'a> {
pub struct SceneEntityDeserializer<'a> { pub struct SceneEntityDeserializer<'a> {
pub property_type_registry: &'a PropertyTypeRegistry, pub property_type_registry: &'a PropertyTypeRegistry,
pub current_type_name: Rc<RefCell<Option<String>>>,
} }
impl<'a, 'de> DeserializeSeed<'de> for SceneEntityDeserializer<'a> { impl<'a, 'de> DeserializeSeed<'de> for SceneEntityDeserializer<'a> {
@ -79,8 +75,7 @@ impl<'a, 'de> DeserializeSeed<'de> for SceneEntityDeserializer<'a> {
"Entity", "Entity",
&["id", "components"], &["id", "components"],
SceneEntityVisiter { SceneEntityVisiter {
property_type_registry: self.property_type_registry, registry: self.property_type_registry,
current_type_name: self.current_type_name,
}, },
) )
} }
@ -97,8 +92,7 @@ pub const ENTITY_FIELD_ID: &str = "id";
pub const ENTITY_FIELD_COMPONENTS: &str = "components"; pub const ENTITY_FIELD_COMPONENTS: &str = "components";
struct SceneEntityVisiter<'a> { struct SceneEntityVisiter<'a> {
pub property_type_registry: &'a PropertyTypeRegistry, pub registry: &'a PropertyTypeRegistry,
pub current_type_name: Rc<RefCell<Option<String>>>,
} }
impl<'a, 'de> Visitor<'de> for SceneEntityVisiter<'a> { 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 { components = Some(map.next_value_seed(ComponentVecDeserializer {
current_type_name: self.current_type_name.clone(), registry: self.registry,
registry: self.property_type_registry,
})?); })?);
} }
} }
@ -150,7 +143,6 @@ impl<'a, 'de> Visitor<'de> for SceneEntityVisiter<'a> {
pub struct ComponentVecDeserializer<'a> { pub struct ComponentVecDeserializer<'a> {
pub registry: &'a PropertyTypeRegistry, pub registry: &'a PropertyTypeRegistry,
pub current_type_name: Rc<RefCell<Option<String>>>,
} }
impl<'a, 'de> DeserializeSeed<'de> for ComponentVecDeserializer<'a> { impl<'a, 'de> DeserializeSeed<'de> for ComponentVecDeserializer<'a> {
@ -161,14 +153,12 @@ impl<'a, 'de> DeserializeSeed<'de> for ComponentVecDeserializer<'a> {
{ {
deserializer.deserialize_seq(ComponentSeqVisiter { deserializer.deserialize_seq(ComponentSeqVisiter {
registry: self.registry, registry: self.registry,
current_type_name: self.current_type_name,
}) })
} }
} }
struct ComponentSeqVisiter<'a> { struct ComponentSeqVisiter<'a> {
pub registry: &'a PropertyTypeRegistry, pub registry: &'a PropertyTypeRegistry,
pub current_type_name: Rc<RefCell<Option<String>>>,
} }
impl<'a, 'de> Visitor<'de> for ComponentSeqVisiter<'a> { impl<'a, 'de> Visitor<'de> for ComponentSeqVisiter<'a> {
@ -182,10 +172,9 @@ impl<'a, 'de> Visitor<'de> for ComponentSeqVisiter<'a> {
A: SeqAccess<'de>, A: SeqAccess<'de>,
{ {
let mut dynamic_properties = Vec::new(); let mut dynamic_properties = Vec::new();
while let Some(entity) = seq.next_element_seed(DynamicPropertiesDeserializer { while let Some(entity) =
current_type_name: self.current_type_name.clone(), seq.next_element_seed(MapPropertyDeserializer::new(self.registry))?
registry: self.registry, {
})? {
dynamic_properties.push(entity); dynamic_properties.push(entity);
} }