mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 20:53:53 +00:00
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
11 changed files with 295 additions and 282 deletions
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)))
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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\'"))
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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: ®istry,
|
||||
current_type_name: current_type_name.clone(),
|
||||
};
|
||||
|
||||
// this callback is executed whenever an explicit type name is encountered in a map
|
||||
let mut callback = |ident: &Option<&[u8]>| {
|
||||
let mut last_type_name = current_type_name.borrow_mut();
|
||||
*last_type_name = ident.map(|i| String::from_utf8(i.to_vec()).unwrap());
|
||||
};
|
||||
deserializer.set_callback(&mut callback);
|
||||
|
||||
let scene = scene_deserializer.deserialize(&mut deserializer).unwrap();
|
||||
Ok(scene)
|
||||
}
|
||||
|
@ -44,4 +34,4 @@ impl AssetLoader<Scene> for SceneLoader {
|
|||
static EXTENSIONS: &[&str] = &["scn"];
|
||||
EXTENSIONS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue