diff options
Diffstat (limited to 'engine-macros')
| -rw-r--r-- | engine-macros/src/reflection.rs | 1 | ||||
| -rw-r--r-- | engine-macros/src/reflection/default_value.rs | 42 | ||||
| -rw-r--r-- | engine-macros/src/reflection/enum_impl.rs | 8 | ||||
| -rw-r--r-- | engine-macros/src/reflection/struct_impl.rs | 8 |
4 files changed, 57 insertions, 2 deletions
diff --git a/engine-macros/src/reflection.rs b/engine-macros/src/reflection.rs index 825094b..5d40e0c 100644 --- a/engine-macros/src/reflection.rs +++ b/engine-macros/src/reflection.rs @@ -1,3 +1,4 @@ +mod default_value; mod enum_impl; mod field; mod struct_impl; diff --git a/engine-macros/src/reflection/default_value.rs b/engine-macros/src/reflection/default_value.rs new file mode 100644 index 0000000..567c3b1 --- /dev/null +++ b/engine-macros/src/reflection/default_value.rs @@ -0,0 +1,42 @@ +use quote::quote; + +pub fn gen_get_default_value_fn( + type_ident: &proc_macro2::Ident, + type_generics: &syn::TypeGenerics, +) -> proc_macro2::TokenStream +{ + quote! { + struct SpecializationTarget<T>(std::marker::PhantomData<T>); + + trait HasDefaultValue + { + fn default_value_fn(&self) -> Option<fn() -> Box<dyn std::any::Any>>; + } + + trait NoDefaultValue + { + fn default_value_fn(&self) -> Option<fn() -> Box<dyn std::any::Any>>; + } + + impl<T> NoDefaultValue for &SpecializationTarget<T> + { + fn default_value_fn(&self) -> Option<fn() -> Box<dyn std::any::Any>> + { + None + } + } + + impl<T> HasDefaultValue for SpecializationTarget<T> + where + T: std::default::Default + 'static + { + fn default_value_fn(&self) -> Option<fn() -> Box<dyn std::any::Any>> + { + Some(|| Box::new(T::default())) + } + } + + (&SpecializationTarget::<#type_ident #type_generics>(std::marker::PhantomData)) + .default_value_fn() + } +} diff --git a/engine-macros/src/reflection/enum_impl.rs b/engine-macros/src/reflection/enum_impl.rs index 14142bf..611da6d 100644 --- a/engine-macros/src/reflection/enum_impl.rs +++ b/engine-macros/src/reflection/enum_impl.rs @@ -1,5 +1,6 @@ use quote::{format_ident, quote, ToTokens}; +use crate::reflection::default_value::gen_get_default_value_fn; use crate::reflection::field::{generate as generate_field, ReflectionFieldGenOptions}; use crate::util::{find_engine_crate_path, syn_path, SynPathExt}; @@ -238,6 +239,8 @@ pub fn generate(input: syn::ItemEnum) -> proc_macro2::TokenStream } }; + let get_default_value_fn = gen_get_default_value_fn(&input_ident, &type_generics); + quote! { #[doc(hidden)] mod #mod_name { @@ -254,7 +257,10 @@ pub fn generate(input: syn::ItemEnum) -> proc_macro2::TokenStream variants: &[#(#variants),*], is_unit_only: #is_unit_only, discriminant_layout: #discriminant_layout, - fields_layout: #fields_layout + fields_layout: #fields_layout, + get_default_value: || { + #get_default_value_fn + } } ) }; diff --git a/engine-macros/src/reflection/struct_impl.rs b/engine-macros/src/reflection/struct_impl.rs index b1adea5..ce1086b 100644 --- a/engine-macros/src/reflection/struct_impl.rs +++ b/engine-macros/src/reflection/struct_impl.rs @@ -1,5 +1,6 @@ use quote::quote; +use crate::reflection::default_value::gen_get_default_value_fn; use crate::reflection::field::{generate as generate_field, ReflectionFieldGenOptions}; use crate::util::{find_engine_crate_path, syn_path, SynPathExt}; @@ -49,6 +50,8 @@ pub fn generate(input: syn::ItemStruct) -> proc_macro2::TokenStream ) }); + let get_default_value_fn = gen_get_default_value_fn(&input_ident, &type_generics); + quote! { unsafe impl #impl_generics #engine_crate_path::reflection::Reflection for #input_ident #type_generics #where_clause @@ -59,7 +62,10 @@ pub fn generate(input: syn::ItemStruct) -> proc_macro2::TokenStream #engine_crate_path::reflection::Struct { fields: &[ #(#fields),* - ] + ], + get_default_value: || { + #get_default_value_fn + } } ) }; |
