bevy_reflect_derive/
registration.rs

1//! Contains code related specifically to Bevy's type registration.
2
3use crate::{serialization::SerializationDataDef, where_clause_options::WhereClauseOptions};
4use quote::quote;
5use syn::Type;
6
7/// Creates the `GetTypeRegistration` impl for the given type data.
8pub(crate) fn impl_get_type_registration<'a>(
9    where_clause_options: &WhereClauseOptions,
10    serialization_data: Option<&SerializationDataDef>,
11    type_dependencies: Option<impl Iterator<Item = &'a Type>>,
12) -> proc_macro2::TokenStream {
13    let meta = where_clause_options.meta();
14    let type_path = meta.type_path();
15    let bevy_reflect_path = meta.bevy_reflect_path();
16    let registration_data = meta.attrs().idents();
17
18    let type_deps_fn = type_dependencies.map(|deps| {
19        quote! {
20            #[inline(never)]
21            fn register_type_dependencies(registry: &mut #bevy_reflect_path::TypeRegistry) {
22                #(<#deps as #bevy_reflect_path::__macro_exports::RegisterForReflection>::__register(registry);)*
23            }
24        }
25    });
26
27    let (impl_generics, ty_generics, where_clause) = type_path.generics().split_for_impl();
28    let where_reflect_clause = where_clause_options.extend_where_clause(where_clause);
29
30    let from_reflect_data = if meta.from_reflect().should_auto_derive() {
31        Some(quote! {
32            registration.insert::<#bevy_reflect_path::ReflectFromReflect>(#bevy_reflect_path::FromType::<Self>::from_type());
33        })
34    } else {
35        None
36    };
37
38    let serialization_data = serialization_data.map(|data| {
39        let serialization_data = data.as_serialization_data(bevy_reflect_path);
40        quote! {
41            registration.insert::<#bevy_reflect_path::serde::SerializationData>(#serialization_data);
42        }
43    });
44
45    quote! {
46        impl #impl_generics #bevy_reflect_path::GetTypeRegistration for #type_path #ty_generics #where_reflect_clause {
47            fn get_type_registration() -> #bevy_reflect_path::TypeRegistration {
48                let mut registration = #bevy_reflect_path::TypeRegistration::of::<Self>();
49                registration.insert::<#bevy_reflect_path::ReflectFromPtr>(#bevy_reflect_path::FromType::<Self>::from_type());
50                #from_reflect_data
51                #serialization_data
52                #(registration.insert::<#registration_data>(#bevy_reflect_path::FromType::<Self>::from_type());)*
53                registration
54            }
55
56            #type_deps_fn
57        }
58    }
59}