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 {
#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 {

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};
pub struct DynamicProperties {
@ -6,7 +6,7 @@ pub struct DynamicProperties {
pub props: Vec<Box<dyn Property>>,
pub prop_names: Vec<Cow<'static, str>>,
pub prop_indices: HashMap<Cow<'static, str>, 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
}
}

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

View file

@ -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
}
}

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 std::{
any::Any,
@ -32,9 +32,6 @@ where
fn iter_props(&self) -> PropertyIter {
PropertyIter::new(self)
}
fn properties_type(&self) -> PropertiesType {
PropertiesType::Seq
}
}
impl<T> Property for Vec<T>
@ -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)))
}

View file

@ -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);
}
}
}
}

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 erased_serde::{Deserializer, Serialize};
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,
}
}
#[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<dyn Property>;
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<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 {
@ -58,4 +52,4 @@ impl PropertyVal for dyn Property {
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 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<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 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
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<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 properties: &'a dyn Properties,
}
@ -67,31 +83,47 @@ impl<'a> 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>
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<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
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<RefCell<Option<String>>>,
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(<<D as serde::Deserializer<'de>>::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<RefCell<Option<String>>>,
}
impl<'a, 'de> DeserializeSeed<'de> for PropSeqDeserializer<'a> {
impl<'a, 'de> DeserializeSeed<'de> for SeqPropertyDeserializer<'a> {
type Value = DynamicProperties;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
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<RefCell<Option<String>>>,
}
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<RefCell<Option<String>>>,
}
impl<'a, 'de> DeserializeSeed<'de> for MapValueDeserializer<'a> {
type Value = Box<dyn Property>;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
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(<<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> MapPropertyDeserializer<'a> {
pub fn new(registry: &'a PropertyTypeRegistry) -> Self {
MapPropertyDeserializer {
registry,
}
}
}
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> {
property_type_registry: &'a PropertyTypeRegistry,
current_type_name: Rc<RefCell<Option<String>>>,
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<V>(self, map: V) -> Result<Self::Value, V::Error>
fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
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<RefCell<Option<String>>>,
) -> Result<DynamicProperties, V::Error>
where
V: MapAccess<'de>,
{
let mut dynamic_properties = DynamicProperties::map();
let mut type_name: Option<String> = None;
let mut is_seq = false;
// TODO: support seq_value_type
while let Some(key) = map.next_key::<String>()? {
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<String> = None;
while let Some(key) = map.next_key::<String>()? {
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\'"))
}
}

View file

@ -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<DynamicProperties, ron::Error> {
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)
}

View file

@ -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<Scene> for SceneLoader {
fn from_bytes(&self, _asset_path: &Path, bytes: Vec<u8>) -> Result<Scene> {
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: &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();
Ok(scene)
}
@ -44,4 +34,4 @@ impl AssetLoader<Scene> for SceneLoader {
static EXTENSIONS: &[&str] = &["scn"];
EXTENSIONS
}
}
}

View file

@ -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<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@ -18,7 +19,6 @@ impl Serialize for Scene {
pub struct SceneDeserializer<'a> {
pub property_type_registry: &'a PropertyTypeRegistry,
pub current_type_name: Rc<RefCell<Option<String>>>,
}
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<RefCell<Option<String>>>,
}
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<RefCell<Option<String>>>,
}
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<RefCell<Option<String>>>,
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<RefCell<Option<String>>>,
}
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<RefCell<Option<String>>>,
}
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);
}