Skip to main content

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        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "inline");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "never");
                    _s
                });
            _s
        });
    ::quote::__private::push_ident(&mut _s, "fn");
    ::quote::__private::push_ident(&mut _s, "register_type_dependencies");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "registry");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_ident(&mut _s, "mut");
            ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "TypeRegistry");
            _s
        });
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            {
                use ::quote::__private::ext::*;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut deps, i) = deps.quote_into_iter();
                let has_iter = has_iter | i;
                #[allow(unused_mut)]
                let (mut bevy_reflect_path, i) =
                    bevy_reflect_path.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let deps =
                        match deps.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    let bevy_reflect_path =
                        match bevy_reflect_path.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::ToTokens::to_tokens(&deps, &mut _s);
                    ::quote::__private::push_ident(&mut _s, "as");
                    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__macro_exports");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s,
                        "RegisterForReflection");
                    ::quote::__private::push_gt(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__register");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "registry");
                            _s
                        });
                    ::quote::__private::push_semi(&mut _s);
                }
            }
            _s
        });
    _s
}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({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "registration");
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "insert");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ReflectFromReflect");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "FromType");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "from_type");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}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        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "registration");
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "insert");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "serde");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "SerializationData");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&serialization_data, &mut _s);
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
41            registration.insert::<#bevy_reflect_path::serde::SerializationData>(#serialization_data);
42        }
43    });
44
45    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "GetTypeRegistration");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&type_path, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&where_reflect_clause, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "get_type_registration");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "TypeRegistration");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::__private::push_ident(&mut _s, "mut");
                    ::quote::__private::push_ident(&mut _s, "registration");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "TypeRegistration");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "of");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Self");
                    ::quote::__private::push_gt(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "registration");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "insert");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "ReflectFromPtr");
                    ::quote::__private::push_gt(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::ToTokens::to_tokens(&bevy_reflect_path, &mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "FromType");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Self");
                            ::quote::__private::push_gt(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "from_type");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            _s
                        });
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::ToTokens::to_tokens(&from_reflect_data, &mut _s);
                    ::quote::ToTokens::to_tokens(&serialization_data, &mut _s);
                    {
                        use ::quote::__private::ext::*;
                        let has_iter = ::quote::__private::HasIterator::<false>;
                        #[allow(unused_mut)]
                        let (mut registration_data, i) =
                            registration_data.quote_into_iter();
                        let has_iter = has_iter | i;
                        <_ as
                                ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                        while true {
                            let registration_data =
                                match registration_data.next() {
                                    Some(_x) => ::quote::__private::RepInterp(_x),
                                    None => break,
                                };
                            ::quote::__private::push_ident(&mut _s, "registration");
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s,
                                "register_type_data");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::ToTokens::to_tokens(&registration_data, &mut _s);
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Self");
                            ::quote::__private::push_gt(&mut _s);
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            ::quote::__private::push_semi(&mut _s);
                        }
                    }
                    ::quote::__private::push_ident(&mut _s, "registration");
                    _s
                });
            ::quote::ToTokens::to_tokens(&type_deps_fn, &mut _s);
            _s
        });
    _s
}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.register_type_data::<#registration_data, Self>();)*
53                registration
54            }
55
56            #type_deps_fn
57        }
58    }
59}