 bf765e61b5
			
		
	
	
		bf765e61b5
		
			
		
	
	
	
	
		
			
			# Objective - Contributes to #15460 ## Solution - Added `std` feature (enabled by default) ## Testing - CI - `cargo check -p bevy_reflect --no-default-features --target "x86_64-unknown-none"` - UEFI demo application runs with this branch of `bevy_reflect`, allowing `derive(Reflect)` ## Notes - The [`spin`](https://crates.io/crates/spin) crate has been included to provide `RwLock` and `Once` (as an alternative to `OnceLock`) when the `std` feature is not enabled. Another alternative may be more desirable, please provide feedback if you have a strong opinion here! - Certain items (`Box`, `String`, `ToString`) provided by `alloc` have been added to `__macro_exports` as a way to avoid `alloc` vs `std` namespacing. I'm personally quite annoyed that we can't rely on `alloc` as a crate name in `std` environments within macros. I'd love an alternative to my approach here, but I suspect it's the least-bad option. - I would've liked to have an `alloc` feature (for allocation-free `bevy_reflect`), unfortunately, `erased_serde` unconditionally requires access to `Box`. Maybe one day we could design around this, but for now it just means `bevy_reflect` requires `alloc`. --------- Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com> Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
		
			
				
	
	
		
			150 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use crate::{
 | |
|     impls::{common_partial_reflect_methods, impl_full_reflect, impl_type_path, impl_typed},
 | |
|     struct_utility::FieldAccessors,
 | |
|     ReflectStruct,
 | |
| };
 | |
| use bevy_macro_utils::fq_std::{FQDefault, FQOption, FQResult};
 | |
| use quote::{quote, ToTokens};
 | |
| 
 | |
| /// Implements `TupleStruct`, `GetTypeRegistration`, and `Reflect` for the given derive data.
 | |
| pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> proc_macro2::TokenStream {
 | |
|     let fqoption = FQOption.into_token_stream();
 | |
| 
 | |
|     let bevy_reflect_path = reflect_struct.meta().bevy_reflect_path();
 | |
|     let struct_path = reflect_struct.meta().type_path();
 | |
| 
 | |
|     let FieldAccessors {
 | |
|         fields_ref,
 | |
|         fields_mut,
 | |
|         field_indices,
 | |
|         field_count,
 | |
|         ..
 | |
|     } = FieldAccessors::new(reflect_struct);
 | |
| 
 | |
|     let where_clause_options = reflect_struct.where_clause_options();
 | |
|     let get_type_registration_impl = reflect_struct.get_type_registration(&where_clause_options);
 | |
| 
 | |
|     let typed_impl = impl_typed(
 | |
|         reflect_struct.meta(),
 | |
|         &where_clause_options,
 | |
|         reflect_struct.to_info_tokens(true),
 | |
|     );
 | |
| 
 | |
|     let type_path_impl = impl_type_path(reflect_struct.meta());
 | |
|     let full_reflect_impl = impl_full_reflect(reflect_struct.meta(), &where_clause_options);
 | |
|     let common_methods = common_partial_reflect_methods(
 | |
|         reflect_struct.meta(),
 | |
|         || Some(quote!(#bevy_reflect_path::tuple_struct_partial_eq)),
 | |
|         || None,
 | |
|     );
 | |
| 
 | |
|     #[cfg(not(feature = "functions"))]
 | |
|     let function_impls = None::<proc_macro2::TokenStream>;
 | |
|     #[cfg(feature = "functions")]
 | |
|     let function_impls =
 | |
|         crate::impls::impl_function_traits(reflect_struct.meta(), &where_clause_options);
 | |
| 
 | |
|     let (impl_generics, ty_generics, where_clause) = reflect_struct
 | |
|         .meta()
 | |
|         .type_path()
 | |
|         .generics()
 | |
|         .split_for_impl();
 | |
| 
 | |
|     let where_reflect_clause = where_clause_options.extend_where_clause(where_clause);
 | |
| 
 | |
|     quote! {
 | |
|         #get_type_registration_impl
 | |
| 
 | |
|         #typed_impl
 | |
| 
 | |
|         #type_path_impl
 | |
| 
 | |
|         #full_reflect_impl
 | |
| 
 | |
|         #function_impls
 | |
| 
 | |
|         impl #impl_generics #bevy_reflect_path::TupleStruct for #struct_path #ty_generics #where_reflect_clause {
 | |
|             fn field(&self, index: usize) -> #FQOption<&dyn #bevy_reflect_path::PartialReflect> {
 | |
|                 match index {
 | |
|                     #(#field_indices => #fqoption::Some(#fields_ref),)*
 | |
|                     _ => #FQOption::None,
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             fn field_mut(&mut self, index: usize) -> #FQOption<&mut dyn #bevy_reflect_path::PartialReflect> {
 | |
|                 match index {
 | |
|                     #(#field_indices => #fqoption::Some(#fields_mut),)*
 | |
|                     _ => #FQOption::None,
 | |
|                 }
 | |
|             }
 | |
|             #[inline]
 | |
|             fn field_len(&self) -> usize {
 | |
|                 #field_count
 | |
|             }
 | |
|             #[inline]
 | |
|             fn iter_fields(&self) -> #bevy_reflect_path::TupleStructFieldIter {
 | |
|                 #bevy_reflect_path::TupleStructFieldIter::new(self)
 | |
|             }
 | |
| 
 | |
|             fn clone_dynamic(&self) -> #bevy_reflect_path::DynamicTupleStruct {
 | |
|                 let mut dynamic: #bevy_reflect_path::DynamicTupleStruct = #FQDefault::default();
 | |
|                 dynamic.set_represented_type(#bevy_reflect_path::PartialReflect::get_represented_type_info(self));
 | |
|                 #(dynamic.insert_boxed(#bevy_reflect_path::PartialReflect::clone_value(#fields_ref));)*
 | |
|                 dynamic
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         impl #impl_generics #bevy_reflect_path::PartialReflect for #struct_path #ty_generics #where_reflect_clause {
 | |
|             #[inline]
 | |
|             fn get_represented_type_info(&self) -> #FQOption<&'static #bevy_reflect_path::TypeInfo> {
 | |
|                 #FQOption::Some(<Self as #bevy_reflect_path::Typed>::type_info())
 | |
|             }
 | |
|             #[inline]
 | |
|             fn clone_value(&self) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box<dyn #bevy_reflect_path::PartialReflect> {
 | |
|                 #bevy_reflect_path::__macro_exports::alloc_utils::Box::new(#bevy_reflect_path::TupleStruct::clone_dynamic(self))
 | |
|             }
 | |
| 
 | |
|             #[inline]
 | |
|             fn try_apply(
 | |
|                 &mut self,
 | |
|                 value: &dyn #bevy_reflect_path::PartialReflect
 | |
|             ) -> #FQResult<(), #bevy_reflect_path::ApplyError> {
 | |
|                 if let #bevy_reflect_path::ReflectRef::TupleStruct(struct_value) =
 | |
|                     #bevy_reflect_path::PartialReflect::reflect_ref(value) {
 | |
|                     for (i, value) in ::core::iter::Iterator::enumerate(#bevy_reflect_path::TupleStruct::iter_fields(struct_value)) {
 | |
|                         if let #FQOption::Some(v) = #bevy_reflect_path::TupleStruct::field_mut(self, i) {
 | |
|                             #bevy_reflect_path::PartialReflect::try_apply(v, value)?;
 | |
|                         }
 | |
|                     }
 | |
|                 } else {
 | |
|                     return #FQResult::Err(
 | |
|                         #bevy_reflect_path::ApplyError::MismatchedKinds {
 | |
|                             from_kind: #bevy_reflect_path::PartialReflect::reflect_kind(value),
 | |
|                             to_kind: #bevy_reflect_path::ReflectKind::TupleStruct,
 | |
|                         }
 | |
|                     );
 | |
|                 }
 | |
|                #FQResult::Ok(())
 | |
|             }
 | |
|             #[inline]
 | |
|             fn reflect_kind(&self) -> #bevy_reflect_path::ReflectKind {
 | |
|                 #bevy_reflect_path::ReflectKind::TupleStruct
 | |
|             }
 | |
|             #[inline]
 | |
|             fn reflect_ref(&self) -> #bevy_reflect_path::ReflectRef {
 | |
|                 #bevy_reflect_path::ReflectRef::TupleStruct(self)
 | |
|             }
 | |
|             #[inline]
 | |
|             fn reflect_mut(&mut self) -> #bevy_reflect_path::ReflectMut {
 | |
|                 #bevy_reflect_path::ReflectMut::TupleStruct(self)
 | |
|             }
 | |
|             #[inline]
 | |
|             fn reflect_owned(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box<Self>) -> #bevy_reflect_path::ReflectOwned {
 | |
|                 #bevy_reflect_path::ReflectOwned::TupleStruct(self)
 | |
|             }
 | |
| 
 | |
|             #common_methods
 | |
|         }
 | |
|     }
 | |
| }
 |