props: remove need for explicit serde::Deserialize impl. replace impl_property macro_rules with proc_macro_fn
This commit is contained in:
		
							parent
							
								
									4bc3772749
								
							
						
					
					
						commit
						76adb888d3
					
				@ -1,7 +1,6 @@
 | 
			
		||||
 | 
			
		||||
use bevy_property::{Property, Properties};
 | 
			
		||||
use bevy_property::{Property, Properties, DeserializeProperty};
 | 
			
		||||
use legion::storage::Component;
 | 
			
		||||
use serde::Deserialize;
 | 
			
		||||
use crate::{PropertyTypeRegistryContext, ComponentRegistryContext};
 | 
			
		||||
use bevy_app::{FromResources, AppBuilder};
 | 
			
		||||
 | 
			
		||||
@ -11,7 +10,7 @@ pub trait RegisterComponent {
 | 
			
		||||
        T: Properties + Component + FromResources;
 | 
			
		||||
    fn register_property_type<T>(&mut self) -> &mut Self
 | 
			
		||||
    where
 | 
			
		||||
        T: Property + for<'de> Deserialize<'de>;
 | 
			
		||||
        T: Property + DeserializeProperty;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl RegisterComponent for AppBuilder {
 | 
			
		||||
@ -31,7 +30,7 @@ impl RegisterComponent for AppBuilder {
 | 
			
		||||
 | 
			
		||||
    fn register_property_type<T>(&mut self) -> &mut Self
 | 
			
		||||
    where
 | 
			
		||||
        T: Property + for<'de> Deserialize<'de>,
 | 
			
		||||
        T: Property + DeserializeProperty,
 | 
			
		||||
    {
 | 
			
		||||
        {
 | 
			
		||||
            let registry_context = self
 | 
			
		||||
 | 
			
		||||
@ -5,8 +5,15 @@ mod modules;
 | 
			
		||||
use darling::FromMeta;
 | 
			
		||||
use modules::{get_modules, get_path};
 | 
			
		||||
use proc_macro::TokenStream;
 | 
			
		||||
use proc_macro_crate::crate_name;
 | 
			
		||||
use quote::quote;
 | 
			
		||||
use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Field, Fields, Index, Member, punctuated::Punctuated};
 | 
			
		||||
use syn::{
 | 
			
		||||
    parse::Parse,
 | 
			
		||||
    parse_macro_input,
 | 
			
		||||
    punctuated::Punctuated,
 | 
			
		||||
    token::{Comma, Where},
 | 
			
		||||
    Data, DataStruct, DeriveInput, Field, Fields, Generics, Ident, Index, Member,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#[derive(FromMeta, Debug, Default)]
 | 
			
		||||
struct PropAttributeArgs {
 | 
			
		||||
@ -152,7 +159,7 @@ pub fn derive_properties(input: TokenStream) -> TokenStream {
 | 
			
		||||
            fn type_name(&self) -> &str {
 | 
			
		||||
                std::any::type_name::<Self>()
 | 
			
		||||
            }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn any(&self) -> &dyn std::any::Any {
 | 
			
		||||
                self
 | 
			
		||||
@ -254,6 +261,144 @@ pub fn derive_property(input: TokenStream) -> TokenStream {
 | 
			
		||||
            fn serializable(&self) -> #bevy_property_path::Serializable {
 | 
			
		||||
                #bevy_property_path::Serializable::Borrowed(self)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        impl #impl_generics #bevy_property_path::DeserializeProperty for #struct_name#ty_generics  {
 | 
			
		||||
            fn deserialize(
 | 
			
		||||
                deserializer: &mut dyn #bevy_property_path::erased_serde::Deserializer,
 | 
			
		||||
                property_type_registry: &#bevy_property_path::PropertyTypeRegistry) ->
 | 
			
		||||
                    Result<Box<dyn #bevy_property_path::Property>, #bevy_property_path::erased_serde::Error> {
 | 
			
		||||
                    let property = <#struct_name#ty_generics as Deserialize>::deserialize(deserializer)?;
 | 
			
		||||
                    Ok(Box::new(property))
 | 
			
		||||
            }
 | 
			
		||||
       }
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
struct PropertyDef {
 | 
			
		||||
    type_name: Ident,
 | 
			
		||||
    generics: Generics,
 | 
			
		||||
    serialize_fn: Option<Ident>,
 | 
			
		||||
    deserialize_fn: Option<Ident>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Parse for PropertyDef {
 | 
			
		||||
    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
 | 
			
		||||
        let type_ident = input.parse::<Ident>()?;
 | 
			
		||||
        let generics = input.parse::<Generics>()?;
 | 
			
		||||
        let mut lookahead = input.lookahead1();
 | 
			
		||||
        let mut where_clause = None;
 | 
			
		||||
        if lookahead.peek(Where) {
 | 
			
		||||
            where_clause = Some(input.parse()?);
 | 
			
		||||
            lookahead = input.lookahead1();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let mut serialize_fn = None;
 | 
			
		||||
        if lookahead.peek(Comma) {
 | 
			
		||||
            input.parse::<Comma>()?;
 | 
			
		||||
            serialize_fn = Some(input.parse::<Ident>()?);
 | 
			
		||||
            lookahead = input.lookahead1();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let mut deserialize_fn = None;
 | 
			
		||||
        if lookahead.peek(Comma) {
 | 
			
		||||
            input.parse::<Comma>()?;
 | 
			
		||||
            deserialize_fn = Some(input.parse::<Ident>()?);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Ok(PropertyDef {
 | 
			
		||||
            type_name: type_ident,
 | 
			
		||||
            generics: Generics {
 | 
			
		||||
                where_clause,
 | 
			
		||||
                ..generics
 | 
			
		||||
            },
 | 
			
		||||
            serialize_fn,
 | 
			
		||||
            deserialize_fn,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[proc_macro]
 | 
			
		||||
pub fn impl_property(input: TokenStream) -> TokenStream {
 | 
			
		||||
    let property_def = parse_macro_input!(input as PropertyDef);
 | 
			
		||||
 | 
			
		||||
    let bevy_property_path = get_path(if crate_name("bevy").is_ok() {
 | 
			
		||||
        "bevy::property"
 | 
			
		||||
    } else if crate_name("bevy_property").is_ok() {
 | 
			
		||||
        "bevy_property"
 | 
			
		||||
    } else {
 | 
			
		||||
        "crate"
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    let (impl_generics, ty_generics, where_clause) = property_def.generics.split_for_impl();
 | 
			
		||||
    let ty = &property_def.type_name;
 | 
			
		||||
    let serialize_fn = if let Some(serialize_fn) = property_def.serialize_fn {
 | 
			
		||||
        quote! { #serialize_fn(self) }
 | 
			
		||||
    } else {
 | 
			
		||||
        quote! {
 | 
			
		||||
            #bevy_property_path::Serializable::Borrowed(self)
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    let deserialize_fn = if let Some(deserialize_fn) = property_def.deserialize_fn {
 | 
			
		||||
        quote! { #deserialize_fn(deserializer, property_type_registry) }
 | 
			
		||||
    } else {
 | 
			
		||||
        quote! {
 | 
			
		||||
            let property = <#ty#ty_generics as #bevy_property_path::serde::Deserialize>::deserialize(deserializer)?;
 | 
			
		||||
            Ok(Box::new(property))
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    TokenStream::from(quote! {
 | 
			
		||||
        impl #impl_generics #bevy_property_path::Property for #ty#ty_generics #where_clause  {
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn type_name(&self) -> &str {
 | 
			
		||||
                std::any::type_name::<Self>()
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn any(&self) -> &dyn std::any::Any {
 | 
			
		||||
                self
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn any_mut(&mut self) -> &mut dyn std::any::Any {
 | 
			
		||||
                self
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn clone_prop(&self) -> Box<dyn #bevy_property_path::Property> {
 | 
			
		||||
                Box::new(self.clone())
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn apply(&mut self, value: &dyn #bevy_property_path::Property) {
 | 
			
		||||
                self.set(value);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn set(&mut self, value: &dyn #bevy_property_path::Property) {
 | 
			
		||||
                let value = value.any();
 | 
			
		||||
                if let Some(prop) = value.downcast_ref::<Self>() {
 | 
			
		||||
                    *self = prop.clone();
 | 
			
		||||
                } else {
 | 
			
		||||
                    panic!("prop value is not {}", std::any::type_name::<Self>());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn serializable(&self) -> #bevy_property_path::Serializable {
 | 
			
		||||
                #serialize_fn
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        impl #impl_generics #bevy_property_path::DeserializeProperty for #ty#ty_generics #where_clause  {
 | 
			
		||||
            fn deserialize(
 | 
			
		||||
                deserializer: &mut dyn #bevy_property_path::erased_serde::Deserializer,
 | 
			
		||||
                property_type_registry: &#bevy_property_path::PropertyTypeRegistry) ->
 | 
			
		||||
                    Result<Box<dyn #bevy_property_path::Property>, #bevy_property_path::erased_serde::Error> {
 | 
			
		||||
                    #deserialize_fn
 | 
			
		||||
            }
 | 
			
		||||
       }
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
use crate::{
 | 
			
		||||
    Properties, PropertiesType, Property, PropertyIter, PropertyTypeRegistration,
 | 
			
		||||
    Properties, PropertiesType, Property, PropertyIter,
 | 
			
		||||
    PropertyTypeRegistry, Serializable,
 | 
			
		||||
};
 | 
			
		||||
use de::SeqAccess;
 | 
			
		||||
@ -21,7 +21,7 @@ pub struct DynamicProperties {
 | 
			
		||||
impl DynamicProperties {
 | 
			
		||||
    pub fn map() -> Self {
 | 
			
		||||
        DynamicProperties {
 | 
			
		||||
            type_name: Default::default(),
 | 
			
		||||
            type_name: std::any::type_name::<Self>().to_string(),
 | 
			
		||||
            props: Default::default(),
 | 
			
		||||
            prop_names: Default::default(),
 | 
			
		||||
            prop_indices: Default::default(),
 | 
			
		||||
@ -31,7 +31,7 @@ impl DynamicProperties {
 | 
			
		||||
 | 
			
		||||
    pub fn seq() -> Self {
 | 
			
		||||
        DynamicProperties {
 | 
			
		||||
            type_name: Default::default(),
 | 
			
		||||
            type_name: std::any::type_name::<Self>().to_string(),
 | 
			
		||||
            props: Default::default(),
 | 
			
		||||
            prop_names: Default::default(),
 | 
			
		||||
            prop_indices: Default::default(),
 | 
			
		||||
@ -275,7 +275,7 @@ impl<'a> Serialize for PropertiesSeqSerializer<'a> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct DynamicPropertiesDeserializer<'a> {
 | 
			
		||||
    pub property_type_registry: &'a PropertyTypeRegistry,
 | 
			
		||||
    pub registry: &'a PropertyTypeRegistry,
 | 
			
		||||
    pub current_type_name: Rc<RefCell<Option<String>>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -286,14 +286,14 @@ impl<'a, 'de> DeserializeSeed<'de> for DynamicPropertiesDeserializer<'a> {
 | 
			
		||||
        D: serde::Deserializer<'de>,
 | 
			
		||||
    {
 | 
			
		||||
        deserializer.deserialize_map(DynamicPropertyMapVisiter {
 | 
			
		||||
            property_type_registry: self.property_type_registry,
 | 
			
		||||
            registry: self.registry,
 | 
			
		||||
            current_type_name: self.current_type_name,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct DynamicPropertyMapVisiter<'a> {
 | 
			
		||||
    property_type_registry: &'a PropertyTypeRegistry,
 | 
			
		||||
    registry: &'a PropertyTypeRegistry,
 | 
			
		||||
    current_type_name: Rc<RefCell<Option<String>>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -307,11 +307,11 @@ impl<'a, 'de> Visitor<'de> for DynamicPropertyMapVisiter<'a> {
 | 
			
		||||
    where
 | 
			
		||||
        V: MapAccess<'de>,
 | 
			
		||||
    {
 | 
			
		||||
        visit_map(map, self.property_type_registry, self.current_type_name)
 | 
			
		||||
        visit_map(map, self.registry, self.current_type_name)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
pub struct PropertyDeserializer<'a> {
 | 
			
		||||
    pub property_type_registry: &'a PropertyTypeRegistry,
 | 
			
		||||
    pub registry: &'a PropertyTypeRegistry,
 | 
			
		||||
    pub current_type_name: Rc<RefCell<Option<String>>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -322,14 +322,14 @@ impl<'a, 'de> DeserializeSeed<'de> for PropertyDeserializer<'a> {
 | 
			
		||||
        D: serde::Deserializer<'de>,
 | 
			
		||||
    {
 | 
			
		||||
        deserializer.deserialize_any(AnyPropVisiter {
 | 
			
		||||
            property_type_registry: self.property_type_registry,
 | 
			
		||||
            property_type_registry: self.registry,
 | 
			
		||||
            current_type_name: self.current_type_name,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct PropSeqDeserializer<'a> {
 | 
			
		||||
    property_type_registry: &'a PropertyTypeRegistry,
 | 
			
		||||
    registry: &'a PropertyTypeRegistry,
 | 
			
		||||
    current_type_name: Rc<RefCell<Option<String>>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -340,14 +340,14 @@ impl<'a, 'de> DeserializeSeed<'de> for PropSeqDeserializer<'a> {
 | 
			
		||||
        D: serde::Deserializer<'de>,
 | 
			
		||||
    {
 | 
			
		||||
        deserializer.deserialize_seq(PropSeqVisiter {
 | 
			
		||||
            property_type_registry: self.property_type_registry,
 | 
			
		||||
            registry: self.registry,
 | 
			
		||||
            current_type_name: self.current_type_name.clone(),
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct PropSeqVisiter<'a> {
 | 
			
		||||
    property_type_registry: &'a PropertyTypeRegistry,
 | 
			
		||||
    registry: &'a PropertyTypeRegistry,
 | 
			
		||||
    current_type_name: Rc<RefCell<Option<String>>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -363,7 +363,7 @@ impl<'a, 'de> Visitor<'de> for PropSeqVisiter<'a> {
 | 
			
		||||
    {
 | 
			
		||||
        let mut dynamic_properties = DynamicProperties::seq();
 | 
			
		||||
        while let Some(prop) = seq.next_element_seed(PropertyDeserializer {
 | 
			
		||||
            property_type_registry: self.property_type_registry,
 | 
			
		||||
            registry: self.registry,
 | 
			
		||||
            current_type_name: self.current_type_name.clone(),
 | 
			
		||||
        })? {
 | 
			
		||||
            dynamic_properties.push(prop, None);
 | 
			
		||||
@ -373,7 +373,7 @@ impl<'a, 'de> Visitor<'de> for PropSeqVisiter<'a> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct MapValueDeserializer<'a> {
 | 
			
		||||
    property_type_registry: &'a PropertyTypeRegistry,
 | 
			
		||||
    registry: &'a PropertyTypeRegistry,
 | 
			
		||||
    current_type_name: Rc<RefCell<Option<String>>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -387,18 +387,18 @@ impl<'a, 'de> DeserializeSeed<'de> for MapValueDeserializer<'a> {
 | 
			
		||||
            let registration = {
 | 
			
		||||
                let current_type_name = self.current_type_name.borrow();
 | 
			
		||||
                let type_name = current_type_name.as_ref().unwrap();
 | 
			
		||||
                self.property_type_registry
 | 
			
		||||
                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)
 | 
			
		||||
            (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.property_type_registry,
 | 
			
		||||
                property_type_registry: self.registry,
 | 
			
		||||
                current_type_name: self.current_type_name,
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
@ -540,13 +540,13 @@ where
 | 
			
		||||
                ));
 | 
			
		||||
            }
 | 
			
		||||
            dynamic_properties = map.next_value_seed(PropSeqDeserializer {
 | 
			
		||||
                property_type_registry,
 | 
			
		||||
                registry: property_type_registry,
 | 
			
		||||
                current_type_name: current_type_name.clone(),
 | 
			
		||||
            })?;
 | 
			
		||||
            break;
 | 
			
		||||
        } else {
 | 
			
		||||
            let prop = map.next_value_seed(MapValueDeserializer {
 | 
			
		||||
                property_type_registry: property_type_registry,
 | 
			
		||||
                registry: property_type_registry,
 | 
			
		||||
                current_type_name: current_type_name.clone(),
 | 
			
		||||
            })?;
 | 
			
		||||
            dynamic_properties.set_box(&key, prop);
 | 
			
		||||
@ -556,20 +556,4 @@ where
 | 
			
		||||
    let type_name = type_name.ok_or_else(|| de::Error::missing_field("type"))?;
 | 
			
		||||
    dynamic_properties.type_name = type_name.to_string();
 | 
			
		||||
    Ok(dynamic_properties)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct PropertyTypeDeserializer<'a> {
 | 
			
		||||
    registration: &'a PropertyTypeRegistration,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a, 'de> DeserializeSeed<'de> for PropertyTypeDeserializer<'a> {
 | 
			
		||||
    type Value = Box<dyn Property>;
 | 
			
		||||
    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
 | 
			
		||||
    where
 | 
			
		||||
        D: serde::Deserializer<'de>,
 | 
			
		||||
    {
 | 
			
		||||
        let mut erased = erased_serde::Deserializer::erase(deserializer);
 | 
			
		||||
        (self.registration.deserialize)(&mut erased)
 | 
			
		||||
            .map_err(<<D as serde::Deserializer<'de>>::Error as serde::de::Error>::custom)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
use crate::{impl_property, Property, Serializable};
 | 
			
		||||
use crate::impl_property;
 | 
			
		||||
use glam::{Mat3, Mat4, Quat, Vec2, Vec3};
 | 
			
		||||
 | 
			
		||||
impl_property!(Vec2);
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,25 @@
 | 
			
		||||
use crate::{impl_property, Property, Serializable};
 | 
			
		||||
use crate::{impl_property, Property, PropertyTypeRegistry, Serializable};
 | 
			
		||||
use erased_serde::Deserializer;
 | 
			
		||||
use legion::prelude::Entity;
 | 
			
		||||
use serde::Deserialize;
 | 
			
		||||
use std::num::Wrapping;
 | 
			
		||||
 | 
			
		||||
impl_property!(Entity);
 | 
			
		||||
impl_property!(Entity, serialize_entity, deserialize_entity);
 | 
			
		||||
 | 
			
		||||
mod private {
 | 
			
		||||
    use serde::{Deserialize, Serialize};
 | 
			
		||||
    #[derive(Serialize, Deserialize)]
 | 
			
		||||
    pub(super) struct Entity(pub(super) u32);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn serialize_entity(entity: &Entity) -> Serializable {
 | 
			
		||||
    Serializable::Owned(Box::new(private::Entity(entity.index())))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn deserialize_entity(
 | 
			
		||||
    deserializer: &mut dyn Deserializer,
 | 
			
		||||
    _registry: &PropertyTypeRegistry,
 | 
			
		||||
) -> Result<Box<dyn Property>, erased_serde::Error> {
 | 
			
		||||
    let entity = private::Entity::deserialize(deserializer)?;
 | 
			
		||||
    Ok(Box::new(Entity::new(entity.0, Wrapping(1))))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,8 @@
 | 
			
		||||
use crate::{impl_property, Properties, PropertiesType, Property, PropertyIter, SeqSerializer, Serializable};
 | 
			
		||||
use serde::Serialize;
 | 
			
		||||
use serde::{Serialize, Deserialize};
 | 
			
		||||
use std::{
 | 
			
		||||
    any::Any,
 | 
			
		||||
    collections::{BTreeMap, HashMap, HashSet, VecDeque},
 | 
			
		||||
    collections::{BTreeMap, HashMap, HashSet},
 | 
			
		||||
    hash::Hash,
 | 
			
		||||
    ops::Range,
 | 
			
		||||
};
 | 
			
		||||
@ -89,15 +89,15 @@ where
 | 
			
		||||
 | 
			
		||||
impl_property!(String);
 | 
			
		||||
impl_property!(bool);
 | 
			
		||||
impl_property!(SEQUENCE, VecDeque<T> where T: Clone + Send + Sync + Serialize + 'static);
 | 
			
		||||
impl_property!(HashSet<T> where T: Clone + Eq + Send + Sync + Hash + Serialize + 'static);
 | 
			
		||||
// impl_property!(SEQUENCE, VecDeque<T> where T: Clone + Send + Sync + Serialize + 'static);
 | 
			
		||||
impl_property!(HashSet<T> where T: Clone + Eq + Send + Sync + Hash + Serialize + for<'de> Deserialize<'de> + 'static);
 | 
			
		||||
impl_property!(HashMap<K, V> where
 | 
			
		||||
    K: Clone + Eq + Send + Sync + Hash + Serialize + 'static,
 | 
			
		||||
    V: Clone + Send + Sync + Serialize + 'static,);
 | 
			
		||||
    K: Clone + Eq + Send + Sync + Hash + Serialize + for<'de> Deserialize<'de> + 'static,
 | 
			
		||||
    V: Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static,);
 | 
			
		||||
impl_property!(BTreeMap<K, V> where
 | 
			
		||||
    K: Clone + Ord + Send + Sync + Serialize + 'static,
 | 
			
		||||
    V: Clone + Send + Sync + Serialize + 'static);
 | 
			
		||||
impl_property!(Range<T> where T: Clone + Send + Sync + Serialize + 'static);
 | 
			
		||||
    K: Clone + Ord + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static,
 | 
			
		||||
    V: Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static);
 | 
			
		||||
impl_property!(Range<T> where T: Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + 'static);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// TODO: Implement lossless primitive types in RON and remove all of these primitive "cast checks"
 | 
			
		||||
 | 
			
		||||
@ -18,4 +18,5 @@ pub use impl_property_smallvec::*;
 | 
			
		||||
pub use impl_property_legion::*;
 | 
			
		||||
 | 
			
		||||
pub use bevy_property_derive::*; 
 | 
			
		||||
pub use serde;
 | 
			
		||||
pub use serde;
 | 
			
		||||
pub use erased_serde;
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
use crate::Properties;
 | 
			
		||||
use crate::{PropertyTypeRegistry, Properties};
 | 
			
		||||
use std::any::Any;
 | 
			
		||||
use erased_serde::Serialize;
 | 
			
		||||
use erased_serde::{Deserializer, Serialize};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pub enum Serializable<'a> {
 | 
			
		||||
@ -17,6 +17,7 @@ impl<'a> Serializable<'a> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: consider removing send + sync requirements
 | 
			
		||||
pub trait Property: Send + Sync + Any + 'static {
 | 
			
		||||
    fn type_name(&self) -> &str;
 | 
			
		||||
    fn any(&self) -> &dyn Any;
 | 
			
		||||
@ -34,6 +35,10 @@ pub trait Property: Send + Sync + Any + 'static {
 | 
			
		||||
    fn serializable(&self) -> Serializable;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait DeserializeProperty {
 | 
			
		||||
    fn deserialize(deserializer: &mut dyn Deserializer, property_type_registry: &PropertyTypeRegistry) -> Result<Box<dyn Property>, erased_serde::Error>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait PropertyVal {
 | 
			
		||||
    fn val<T: 'static>(&self) -> Option<&T>;
 | 
			
		||||
    fn set_val<T: 'static>(&mut self, value: T);
 | 
			
		||||
@ -53,165 +58,4 @@ impl PropertyVal for dyn Property {
 | 
			
		||||
            panic!("prop value is not {}", std::any::type_name::<T>());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// used by impl_property
 | 
			
		||||
#[allow(unused_macros)]
 | 
			
		||||
macro_rules! as_item {
 | 
			
		||||
    ($i:item) => {
 | 
			
		||||
        $i
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[macro_export]
 | 
			
		||||
macro_rules! impl_property {
 | 
			
		||||
    ($ty:ident) => {
 | 
			
		||||
        impl Property for $ty {
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn type_name(&self) -> &str {
 | 
			
		||||
                std::any::type_name::<Self>()
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn any(&self) -> &dyn std::any::Any {
 | 
			
		||||
                self
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn any_mut(&mut self) -> &mut dyn std::any::Any {
 | 
			
		||||
                self
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn clone_prop(&self) -> Box<dyn Property> {
 | 
			
		||||
                Box::new(self.clone())
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[inline]
 | 
			
		||||
            fn apply(&mut self, value: &dyn Property) {
 | 
			
		||||
                self.set(value);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            fn set(&mut self, value: &dyn Property) {
 | 
			
		||||
                let value = value.any();
 | 
			
		||||
                if let Some(prop) = value.downcast_ref::<Self>() {
 | 
			
		||||
                    *self = prop.clone();
 | 
			
		||||
                } else {
 | 
			
		||||
                    panic!("prop value is not {}", std::any::type_name::<Self>());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            fn serializable(&self) -> Serializable {
 | 
			
		||||
                Serializable::Borrowed(self)
 | 
			
		||||
            }
 | 
			
		||||
       }
 | 
			
		||||
    };
 | 
			
		||||
    (SEQUENCE, @$trait_:ident [$($args:ident,)*] where [$($preds:tt)+]) => {
 | 
			
		||||
        impl_property! {
 | 
			
		||||
            @as_item
 | 
			
		||||
            impl<$($args),*> Property for $trait_<$($args),*> where $($args: ::std::any::Any + 'static,)*
 | 
			
		||||
            $($preds)* {
 | 
			
		||||
                #[inline]
 | 
			
		||||
                fn type_name(&self) -> &str {
 | 
			
		||||
                    std::any::type_name::<Self>()
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                #[inline]
 | 
			
		||||
                fn any(&self) -> &dyn std::any::Any {
 | 
			
		||||
                    self
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                #[inline]
 | 
			
		||||
                fn any_mut(&mut self) -> &mut dyn std::any::Any {
 | 
			
		||||
                    self
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                #[inline]
 | 
			
		||||
                fn clone_prop(&self) -> Box<dyn Property> {
 | 
			
		||||
                    Box::new(self.clone())
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                #[inline]
 | 
			
		||||
                fn apply(&mut self, value: &dyn Property) {
 | 
			
		||||
                    self.set(value);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                fn set(&mut self, value: &dyn Property) {
 | 
			
		||||
                    let value = value.any();
 | 
			
		||||
                    if let Some(prop) = value.downcast_ref::<Self>() {
 | 
			
		||||
                        *self = prop.clone();
 | 
			
		||||
                    } else {
 | 
			
		||||
                        panic!("prop value is not {}", std::any::type_name::<Self>());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                fn is_sequence(&self) -> bool {
 | 
			
		||||
                    true
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                fn serializable(&self) -> Serializable {
 | 
			
		||||
                    Serializable::Borrowed(self)
 | 
			
		||||
                }
 | 
			
		||||
           }
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    (@$trait_:ident [$($args:ident,)*] where [$($preds:tt)+]) => {
 | 
			
		||||
        impl_property! {
 | 
			
		||||
            @as_item
 | 
			
		||||
            impl<$($args),*> Property for $trait_<$($args),*> where $($args: ::std::any::Any + 'static,)*
 | 
			
		||||
            $($preds)* {
 | 
			
		||||
                #[inline]
 | 
			
		||||
                fn type_name(&self) -> &str {
 | 
			
		||||
                    std::any::type_name::<Self>()
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                #[inline]
 | 
			
		||||
                fn any(&self) -> &dyn std::any::Any {
 | 
			
		||||
                    self
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                #[inline]
 | 
			
		||||
                fn any_mut(&mut self) -> &mut dyn std::any::Any {
 | 
			
		||||
                    self
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                #[inline]
 | 
			
		||||
                fn clone_prop(&self) -> Box<dyn Property> {
 | 
			
		||||
                    Box::new(self.clone())
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                #[inline]
 | 
			
		||||
                fn apply(&mut self, value: &dyn Property) {
 | 
			
		||||
                    self.set(value);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                fn set(&mut self, value: &dyn Property) {
 | 
			
		||||
                    let value = value.any();
 | 
			
		||||
                    if let Some(prop) = value.downcast_ref::<Self>() {
 | 
			
		||||
                        *self = prop.clone();
 | 
			
		||||
                    } else {
 | 
			
		||||
                        panic!("prop value is not {}", std::any::type_name::<Self>());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                fn serializable(&self) -> Serializable {
 | 
			
		||||
                    Serializable::Borrowed(self)
 | 
			
		||||
                }
 | 
			
		||||
           }
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    (@as_item $i:item) => { $i };
 | 
			
		||||
 | 
			
		||||
    (
 | 
			
		||||
        SEQUENCE, $trait_:ident < $($args:ident),* $(,)* >
 | 
			
		||||
        where $($preds:tt)+
 | 
			
		||||
    ) => {
 | 
			
		||||
        impl_property! {SEQUENCE, @$trait_ [$($args,)*] where [$($preds)*] }
 | 
			
		||||
    };
 | 
			
		||||
    (
 | 
			
		||||
        $trait_:ident < $($args:ident),* $(,)* >
 | 
			
		||||
        where $($preds:tt)+
 | 
			
		||||
    ) => {
 | 
			
		||||
        impl_property! { @$trait_ [$($args,)*] where [$($preds)*] }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
@ -13,7 +13,7 @@ pub fn deserialize_dynamic_properties(ron_string: &str, property_type_registry:
 | 
			
		||||
    deserializer.set_callback(&mut callback);
 | 
			
		||||
    let dynamic_properties_deserializer = DynamicPropertiesDeserializer {
 | 
			
		||||
        current_type_name: last_type_name.clone(),
 | 
			
		||||
        property_type_registry: &property_type_registry,
 | 
			
		||||
        registry: &property_type_registry,
 | 
			
		||||
    };
 | 
			
		||||
    dynamic_properties_deserializer.deserialize(&mut deserializer)
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,4 @@
 | 
			
		||||
use crate::Property;
 | 
			
		||||
use serde::Deserialize;
 | 
			
		||||
use crate::{DeserializeProperty, Property};
 | 
			
		||||
use std::{any::TypeId, collections::HashMap};
 | 
			
		||||
 | 
			
		||||
#[derive(Default)]
 | 
			
		||||
@ -11,7 +10,7 @@ pub struct PropertyTypeRegistry {
 | 
			
		||||
impl PropertyTypeRegistry {
 | 
			
		||||
    pub fn register<T>(&mut self)
 | 
			
		||||
    where
 | 
			
		||||
        T: Property + for<'de> Deserialize<'de>,
 | 
			
		||||
        T: Property + DeserializeProperty,
 | 
			
		||||
    {
 | 
			
		||||
        let registration = PropertyTypeRegistration::of::<T>();
 | 
			
		||||
        self.short_names
 | 
			
		||||
@ -36,19 +35,19 @@ pub struct PropertyTypeRegistration {
 | 
			
		||||
    pub ty: TypeId,
 | 
			
		||||
    pub deserialize: fn(
 | 
			
		||||
        deserializer: &mut dyn erased_serde::Deserializer,
 | 
			
		||||
        property_type_registry: &PropertyTypeRegistry,
 | 
			
		||||
    ) -> Result<Box<dyn Property>, erased_serde::Error>,
 | 
			
		||||
    pub short_name: &'static str,
 | 
			
		||||
    pub name: &'static str,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl PropertyTypeRegistration {
 | 
			
		||||
    pub fn of<T: Property + for<'de> Deserialize<'de>>() -> Self {
 | 
			
		||||
    pub fn of<T: Property + DeserializeProperty>() -> Self {
 | 
			
		||||
        let ty = TypeId::of::<T>();
 | 
			
		||||
        Self {
 | 
			
		||||
            ty,
 | 
			
		||||
            deserialize: |deserializer: &mut dyn erased_serde::Deserializer| {
 | 
			
		||||
                let property = <T as Deserialize>::deserialize(deserializer)?;
 | 
			
		||||
                Ok(Box::new(property))
 | 
			
		||||
            deserialize: |deserializer: &mut dyn erased_serde::Deserializer, property_type_registry: &PropertyTypeRegistry| {
 | 
			
		||||
                T::deserialize(deserializer, property_type_registry)
 | 
			
		||||
            },
 | 
			
		||||
            name: std::any::type_name::<T>(),
 | 
			
		||||
            short_name: std::any::type_name::<T>().split("::").last().unwrap(),
 | 
			
		||||
 | 
			
		||||
@ -128,7 +128,7 @@ impl<'a, 'de> Visitor<'de> for SceneEntityVisiter<'a> {
 | 
			
		||||
 | 
			
		||||
                    components = Some(map.next_value_seed(ComponentVecDeserializer {
 | 
			
		||||
                        current_type_name: self.current_type_name.clone(),
 | 
			
		||||
                        property_type_registry: self.property_type_registry,
 | 
			
		||||
                        registry: self.property_type_registry,
 | 
			
		||||
                    })?);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@ -149,7 +149,7 @@ impl<'a, 'de> Visitor<'de> for SceneEntityVisiter<'a> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct ComponentVecDeserializer<'a> {
 | 
			
		||||
    pub property_type_registry: &'a PropertyTypeRegistry,
 | 
			
		||||
    pub registry: &'a PropertyTypeRegistry,
 | 
			
		||||
    pub current_type_name: Rc<RefCell<Option<String>>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -160,14 +160,14 @@ impl<'a, 'de> DeserializeSeed<'de> for ComponentVecDeserializer<'a> {
 | 
			
		||||
        D: serde::Deserializer<'de>,
 | 
			
		||||
    {
 | 
			
		||||
        deserializer.deserialize_seq(ComponentSeqVisiter {
 | 
			
		||||
            property_type_registry: self.property_type_registry,
 | 
			
		||||
            registry: self.registry,
 | 
			
		||||
            current_type_name: self.current_type_name,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct ComponentSeqVisiter<'a> {
 | 
			
		||||
    pub property_type_registry: &'a PropertyTypeRegistry,
 | 
			
		||||
    pub registry: &'a PropertyTypeRegistry,
 | 
			
		||||
    pub current_type_name: Rc<RefCell<Option<String>>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -184,7 +184,7 @@ impl<'a, 'de> Visitor<'de> for ComponentSeqVisiter<'a> {
 | 
			
		||||
        let mut dynamic_properties = Vec::new();
 | 
			
		||||
        while let Some(entity) = seq.next_element_seed(DynamicPropertiesDeserializer {
 | 
			
		||||
            current_type_name: self.current_type_name.clone(),
 | 
			
		||||
            property_type_registry: self.property_type_registry,
 | 
			
		||||
            registry: self.registry,
 | 
			
		||||
        })? {
 | 
			
		||||
            dynamic_properties.push(entity);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user