rework scene format. use property value serializer, removing the need for ron fork / enabling any serde target
This commit is contained in:
parent
d86d3ddcbc
commit
59dbf22e39
@ -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 {
|
||||||
|
|||||||
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
}
|
||||||
}
|
|
||||||
@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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: ®istry,
|
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();
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user