mirror of
https://github.com/bevyengine/bevy
synced 2025-02-16 14:08:32 +00:00
reflection: replace impl_reflect_struct
with impl_reflect
(#11437)
# Objective - `impl_reflect_struct` doesn't cover tuple structs or enums. - Problem brought up [on Discord](https://discord.com/channels/691052431525675048/1002362493634629796/1190623345817960463). ## Solution - Replaces `impl_reflect_struct` with the new `impl_reflect` which works for tuple structs and enums too. --- ## Changelog - Internally in `bevy_reflect_derive`, we have a new `ReflectProvenance` type which is composed of `ReflectTraitToImpl` and `ReflectSource`. - `impl_reflect_struct` is gone and totally superseded by `impl_reflect`. --------- Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
This commit is contained in:
parent
4b7ef44bb4
commit
df761af49b
9 changed files with 258 additions and 188 deletions
|
@ -5,11 +5,12 @@
|
||||||
//! the derive helper attribute for `Reflect`, which looks like:
|
//! the derive helper attribute for `Reflect`, which looks like:
|
||||||
//! `#[reflect(PartialEq, Default, ...)]` and `#[reflect_value(PartialEq, Default, ...)]`.
|
//! `#[reflect(PartialEq, Default, ...)]` and `#[reflect_value(PartialEq, Default, ...)]`.
|
||||||
|
|
||||||
|
use crate::derive_data::ReflectTraitToImpl;
|
||||||
use crate::utility;
|
use crate::utility;
|
||||||
use bevy_macro_utils::fq_std::{FQAny, FQOption};
|
use bevy_macro_utils::fq_std::{FQAny, FQOption};
|
||||||
use proc_macro2::{Ident, Span, TokenTree};
|
use proc_macro2::{Ident, Span, TokenTree};
|
||||||
use quote::quote_spanned;
|
use quote::quote_spanned;
|
||||||
use syn::parse::{Parse, ParseStream};
|
use syn::parse::ParseStream;
|
||||||
use syn::punctuated::Punctuated;
|
use syn::punctuated::Punctuated;
|
||||||
use syn::spanned::Spanned;
|
use syn::spanned::Spanned;
|
||||||
use syn::token::Comma;
|
use syn::token::Comma;
|
||||||
|
@ -220,10 +221,7 @@ pub(crate) struct ReflectTraits {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReflectTraits {
|
impl ReflectTraits {
|
||||||
pub fn from_meta_list(
|
pub fn from_meta_list(meta: &MetaList, trait_: ReflectTraitToImpl) -> Result<Self, syn::Error> {
|
||||||
meta: &MetaList,
|
|
||||||
is_from_reflect_derive: bool,
|
|
||||||
) -> Result<Self, syn::Error> {
|
|
||||||
match meta.tokens.clone().into_iter().next() {
|
match meta.tokens.clone().into_iter().next() {
|
||||||
// Handles `#[reflect(where T: Trait, U::Assoc: Trait)]`
|
// Handles `#[reflect(where T: Trait, U::Assoc: Trait)]`
|
||||||
Some(TokenTree::Ident(ident)) if ident == "where" => Ok(Self {
|
Some(TokenTree::Ident(ident)) if ident == "where" => Ok(Self {
|
||||||
|
@ -232,14 +230,14 @@ impl ReflectTraits {
|
||||||
}),
|
}),
|
||||||
_ => Self::from_metas(
|
_ => Self::from_metas(
|
||||||
meta.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)?,
|
meta.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)?,
|
||||||
is_from_reflect_derive,
|
trait_,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_metas(
|
fn from_metas(
|
||||||
metas: Punctuated<Meta, Comma>,
|
metas: Punctuated<Meta, Comma>,
|
||||||
is_from_reflect_derive: bool,
|
trait_: ReflectTraitToImpl,
|
||||||
) -> Result<Self, syn::Error> {
|
) -> Result<Self, syn::Error> {
|
||||||
let mut traits = ReflectTraits::default();
|
let mut traits = ReflectTraits::default();
|
||||||
for meta in &metas {
|
for meta in &metas {
|
||||||
|
@ -317,7 +315,7 @@ impl ReflectTraits {
|
||||||
// Override `lit` if this is a `FromReflect` derive.
|
// Override `lit` if this is a `FromReflect` derive.
|
||||||
// This typically means a user is opting out of the default implementation
|
// This typically means a user is opting out of the default implementation
|
||||||
// from the `Reflect` derive and using the `FromReflect` derive directly instead.
|
// from the `Reflect` derive and using the `FromReflect` derive directly instead.
|
||||||
is_from_reflect_derive
|
(trait_ == ReflectTraitToImpl::FromReflect)
|
||||||
.then(|| LitBool::new(true, Span::call_site()))
|
.then(|| LitBool::new(true, Span::call_site()))
|
||||||
.unwrap_or_else(|| lit.clone())
|
.unwrap_or_else(|| lit.clone())
|
||||||
})?);
|
})?);
|
||||||
|
@ -334,6 +332,10 @@ impl ReflectTraits {
|
||||||
Ok(traits)
|
Ok(traits)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse(input: ParseStream, trait_: ReflectTraitToImpl) -> syn::Result<Self> {
|
||||||
|
ReflectTraits::from_metas(Punctuated::parse_terminated(input)?, trait_)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if the given reflected trait name (i.e. `ReflectDefault` for `Default`)
|
/// Returns true if the given reflected trait name (i.e. `ReflectDefault` for `Default`)
|
||||||
/// is registered for this type.
|
/// is registered for this type.
|
||||||
pub fn contains(&self, name: &str) -> bool {
|
pub fn contains(&self, name: &str) -> bool {
|
||||||
|
@ -466,12 +468,6 @@ impl ReflectTraits {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for ReflectTraits {
|
|
||||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
|
||||||
ReflectTraits::from_metas(Punctuated::<Meta, Comma>::parse_terminated(input)?, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds an identifier to a vector of identifiers if it is not already present.
|
/// Adds an identifier to a vector of identifiers if it is not already present.
|
||||||
///
|
///
|
||||||
/// Returns an error if the identifier already exists in the list.
|
/// Returns an error if the identifier already exists in the list.
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
use crate::container_attributes::{FromReflectAttrs, ReflectTraits, TypePathAttrs};
|
use crate::container_attributes::{FromReflectAttrs, ReflectTraits, TypePathAttrs};
|
||||||
use crate::field_attributes::{parse_field_attrs, ReflectFieldAttr};
|
use crate::field_attributes::{parse_field_attrs, ReflectFieldAttr};
|
||||||
use crate::type_path::parse_path_no_leading_colon;
|
use crate::type_path::parse_path_no_leading_colon;
|
||||||
|
@ -140,10 +142,46 @@ enum ReflectMode {
|
||||||
Value,
|
Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// How the macro was invoked.
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
pub(crate) enum ReflectImplSource {
|
||||||
|
ImplRemoteType,
|
||||||
|
DeriveLocalType,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Which trait the macro explicitly implements.
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
pub(crate) enum ReflectTraitToImpl {
|
||||||
|
Reflect,
|
||||||
|
FromReflect,
|
||||||
|
TypePath,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The provenance of a macro invocation.
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
pub(crate) struct ReflectProvenance {
|
||||||
|
pub source: ReflectImplSource,
|
||||||
|
pub trait_: ReflectTraitToImpl,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ReflectProvenance {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
use self::{ReflectImplSource as S, ReflectTraitToImpl as T};
|
||||||
|
let str = match (self.source, self.trait_) {
|
||||||
|
(S::ImplRemoteType, T::Reflect) => "`impl_reflect`",
|
||||||
|
(S::DeriveLocalType, T::Reflect) => "`#[derive(Reflect)]`",
|
||||||
|
(S::DeriveLocalType, T::FromReflect) => "`#[derive(FromReflect)]`",
|
||||||
|
(S::DeriveLocalType, T::TypePath) => "`#[derive(TypePath)]`",
|
||||||
|
(S::ImplRemoteType, T::FromReflect | T::TypePath) => unreachable!(),
|
||||||
|
};
|
||||||
|
f.write_str(str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> ReflectDerive<'a> {
|
impl<'a> ReflectDerive<'a> {
|
||||||
pub fn from_input(
|
pub fn from_input(
|
||||||
input: &'a DeriveInput,
|
input: &'a DeriveInput,
|
||||||
is_from_reflect_derive: bool,
|
provenance: ReflectProvenance,
|
||||||
) -> Result<Self, syn::Error> {
|
) -> Result<Self, syn::Error> {
|
||||||
let mut traits = ReflectTraits::default();
|
let mut traits = ReflectTraits::default();
|
||||||
// Should indicate whether `#[reflect_value]` was used.
|
// Should indicate whether `#[reflect_value]` was used.
|
||||||
|
@ -167,8 +205,7 @@ impl<'a> ReflectDerive<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
reflect_mode = Some(ReflectMode::Normal);
|
reflect_mode = Some(ReflectMode::Normal);
|
||||||
let new_traits =
|
let new_traits = ReflectTraits::from_meta_list(meta_list, provenance.trait_)?;
|
||||||
ReflectTraits::from_meta_list(meta_list, is_from_reflect_derive)?;
|
|
||||||
traits.merge(new_traits)?;
|
traits.merge(new_traits)?;
|
||||||
}
|
}
|
||||||
Meta::List(meta_list) if meta_list.path.is_ident(REFLECT_VALUE_ATTRIBUTE_NAME) => {
|
Meta::List(meta_list) if meta_list.path.is_ident(REFLECT_VALUE_ATTRIBUTE_NAME) => {
|
||||||
|
@ -180,8 +217,7 @@ impl<'a> ReflectDerive<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
reflect_mode = Some(ReflectMode::Value);
|
reflect_mode = Some(ReflectMode::Value);
|
||||||
let new_traits =
|
let new_traits = ReflectTraits::from_meta_list(meta_list, provenance.trait_)?;
|
||||||
ReflectTraits::from_meta_list(meta_list, is_from_reflect_derive)?;
|
|
||||||
traits.merge(new_traits)?;
|
traits.merge(new_traits)?;
|
||||||
}
|
}
|
||||||
Meta::Path(path) if path.is_ident(REFLECT_VALUE_ATTRIBUTE_NAME) => {
|
Meta::Path(path) if path.is_ident(REFLECT_VALUE_ATTRIBUTE_NAME) => {
|
||||||
|
@ -260,6 +296,16 @@ impl<'a> ReflectDerive<'a> {
|
||||||
|
|
||||||
let meta = ReflectMeta::new(type_path, traits);
|
let meta = ReflectMeta::new(type_path, traits);
|
||||||
|
|
||||||
|
if provenance.source == ReflectImplSource::ImplRemoteType
|
||||||
|
&& meta.type_path_attrs().should_auto_derive()
|
||||||
|
&& !meta.type_path().has_custom_path()
|
||||||
|
{
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
meta.type_path().span(),
|
||||||
|
format!("a #[{TYPE_PATH_ATTRIBUTE_NAME} = \"...\"] attribute must be specified when using {provenance}")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "documentation")]
|
#[cfg(feature = "documentation")]
|
||||||
let meta = meta.with_docs(doc);
|
let meta = meta.with_docs(doc);
|
||||||
|
|
||||||
|
|
|
@ -31,11 +31,10 @@ mod utility;
|
||||||
|
|
||||||
use crate::derive_data::{ReflectDerive, ReflectMeta, ReflectStruct};
|
use crate::derive_data::{ReflectDerive, ReflectMeta, ReflectStruct};
|
||||||
use container_attributes::ReflectTraits;
|
use container_attributes::ReflectTraits;
|
||||||
use derive_data::ReflectTypePath;
|
use derive_data::{ReflectImplSource, ReflectProvenance, ReflectTraitToImpl, ReflectTypePath};
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use reflect_value::ReflectValueDef;
|
use reflect_value::ReflectValueDef;
|
||||||
use syn::spanned::Spanned;
|
|
||||||
use syn::{parse_macro_input, DeriveInput};
|
use syn::{parse_macro_input, DeriveInput};
|
||||||
use type_path::NamedTypePathDef;
|
use type_path::NamedTypePathDef;
|
||||||
|
|
||||||
|
@ -44,6 +43,65 @@ pub(crate) static REFLECT_VALUE_ATTRIBUTE_NAME: &str = "reflect_value";
|
||||||
pub(crate) static TYPE_PATH_ATTRIBUTE_NAME: &str = "type_path";
|
pub(crate) static TYPE_PATH_ATTRIBUTE_NAME: &str = "type_path";
|
||||||
pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name";
|
pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name";
|
||||||
|
|
||||||
|
/// Used both for [`impl_reflect`] and [`derive_reflect`].
|
||||||
|
///
|
||||||
|
/// [`impl_reflect`]: macro@impl_reflect
|
||||||
|
/// [`derive_reflect`]: derive_reflect()
|
||||||
|
fn match_reflect_impls(ast: DeriveInput, source: ReflectImplSource) -> TokenStream {
|
||||||
|
let derive_data = match ReflectDerive::from_input(
|
||||||
|
&ast,
|
||||||
|
ReflectProvenance {
|
||||||
|
source,
|
||||||
|
trait_: ReflectTraitToImpl::Reflect,
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Ok(data) => data,
|
||||||
|
Err(err) => return err.into_compile_error().into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let (reflect_impls, from_reflect_impl) = match derive_data {
|
||||||
|
ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => (
|
||||||
|
impls::impl_struct(&struct_data),
|
||||||
|
if struct_data.meta().from_reflect().should_auto_derive() {
|
||||||
|
Some(from_reflect::impl_struct(&struct_data))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ReflectDerive::TupleStruct(struct_data) => (
|
||||||
|
impls::impl_tuple_struct(&struct_data),
|
||||||
|
if struct_data.meta().from_reflect().should_auto_derive() {
|
||||||
|
Some(from_reflect::impl_tuple_struct(&struct_data))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ReflectDerive::Enum(enum_data) => (
|
||||||
|
impls::impl_enum(&enum_data),
|
||||||
|
if enum_data.meta().from_reflect().should_auto_derive() {
|
||||||
|
Some(from_reflect::impl_enum(&enum_data))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ReflectDerive::Value(meta) => (
|
||||||
|
impls::impl_value(&meta),
|
||||||
|
if meta.from_reflect().should_auto_derive() {
|
||||||
|
Some(from_reflect::impl_value(&meta))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
TokenStream::from(quote! {
|
||||||
|
const _: () = {
|
||||||
|
#reflect_impls
|
||||||
|
#from_reflect_impl
|
||||||
|
};
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// The main derive macro used by `bevy_reflect` for deriving its `Reflect` trait.
|
/// The main derive macro used by `bevy_reflect` for deriving its `Reflect` trait.
|
||||||
///
|
///
|
||||||
/// This macro can be used on all structs and enums (unions are not supported).
|
/// This macro can be used on all structs and enums (unions are not supported).
|
||||||
|
@ -240,53 +298,7 @@ pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name";
|
||||||
#[proc_macro_derive(Reflect, attributes(reflect, reflect_value, type_path, type_name))]
|
#[proc_macro_derive(Reflect, attributes(reflect, reflect_value, type_path, type_name))]
|
||||||
pub fn derive_reflect(input: TokenStream) -> TokenStream {
|
pub fn derive_reflect(input: TokenStream) -> TokenStream {
|
||||||
let ast = parse_macro_input!(input as DeriveInput);
|
let ast = parse_macro_input!(input as DeriveInput);
|
||||||
|
match_reflect_impls(ast, ReflectImplSource::DeriveLocalType)
|
||||||
let derive_data = match ReflectDerive::from_input(&ast, false) {
|
|
||||||
Ok(data) => data,
|
|
||||||
Err(err) => return err.into_compile_error().into(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let (reflect_impls, from_reflect_impl) = match derive_data {
|
|
||||||
ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => (
|
|
||||||
impls::impl_struct(&struct_data),
|
|
||||||
if struct_data.meta().from_reflect().should_auto_derive() {
|
|
||||||
Some(from_reflect::impl_struct(&struct_data))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ReflectDerive::TupleStruct(struct_data) => (
|
|
||||||
impls::impl_tuple_struct(&struct_data),
|
|
||||||
if struct_data.meta().from_reflect().should_auto_derive() {
|
|
||||||
Some(from_reflect::impl_tuple_struct(&struct_data))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ReflectDerive::Enum(enum_data) => (
|
|
||||||
impls::impl_enum(&enum_data),
|
|
||||||
if enum_data.meta().from_reflect().should_auto_derive() {
|
|
||||||
Some(from_reflect::impl_enum(&enum_data))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
),
|
|
||||||
ReflectDerive::Value(meta) => (
|
|
||||||
impls::impl_value(&meta),
|
|
||||||
if meta.from_reflect().should_auto_derive() {
|
|
||||||
Some(from_reflect::impl_value(&meta))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
TokenStream::from(quote! {
|
|
||||||
const _: () = {
|
|
||||||
#reflect_impls
|
|
||||||
#from_reflect_impl
|
|
||||||
};
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Derives the `FromReflect` trait.
|
/// Derives the `FromReflect` trait.
|
||||||
|
@ -319,7 +331,13 @@ pub fn derive_reflect(input: TokenStream) -> TokenStream {
|
||||||
pub fn derive_from_reflect(input: TokenStream) -> TokenStream {
|
pub fn derive_from_reflect(input: TokenStream) -> TokenStream {
|
||||||
let ast = parse_macro_input!(input as DeriveInput);
|
let ast = parse_macro_input!(input as DeriveInput);
|
||||||
|
|
||||||
let derive_data = match ReflectDerive::from_input(&ast, true) {
|
let derive_data = match ReflectDerive::from_input(
|
||||||
|
&ast,
|
||||||
|
ReflectProvenance {
|
||||||
|
source: ReflectImplSource::DeriveLocalType,
|
||||||
|
trait_: ReflectTraitToImpl::FromReflect,
|
||||||
|
},
|
||||||
|
) {
|
||||||
Ok(data) => data,
|
Ok(data) => data,
|
||||||
Err(err) => return err.into_compile_error().into(),
|
Err(err) => return err.into_compile_error().into(),
|
||||||
};
|
};
|
||||||
|
@ -358,7 +376,13 @@ pub fn derive_from_reflect(input: TokenStream) -> TokenStream {
|
||||||
#[proc_macro_derive(TypePath, attributes(type_path, type_name))]
|
#[proc_macro_derive(TypePath, attributes(type_path, type_name))]
|
||||||
pub fn derive_type_path(input: TokenStream) -> TokenStream {
|
pub fn derive_type_path(input: TokenStream) -> TokenStream {
|
||||||
let ast = parse_macro_input!(input as DeriveInput);
|
let ast = parse_macro_input!(input as DeriveInput);
|
||||||
let derive_data = match ReflectDerive::from_input(&ast, false) {
|
let derive_data = match ReflectDerive::from_input(
|
||||||
|
&ast,
|
||||||
|
ReflectProvenance {
|
||||||
|
source: ReflectImplSource::DeriveLocalType,
|
||||||
|
trait_: ReflectTraitToImpl::TypePath,
|
||||||
|
},
|
||||||
|
) {
|
||||||
Ok(data) => data,
|
Ok(data) => data,
|
||||||
Err(err) => return err.into_compile_error().into(),
|
Err(err) => return err.into_compile_error().into(),
|
||||||
};
|
};
|
||||||
|
@ -459,7 +483,7 @@ pub fn reflect_trait(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||||
/// [deriving `Reflect`]: Reflect
|
/// [deriving `Reflect`]: Reflect
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn impl_reflect_value(input: TokenStream) -> TokenStream {
|
pub fn impl_reflect_value(input: TokenStream) -> TokenStream {
|
||||||
let def = parse_macro_input!(input as ReflectValueDef);
|
let def = parse_macro_input!(input with ReflectValueDef::parse_reflect);
|
||||||
|
|
||||||
let default_name = &def.type_path.segments.last().unwrap().ident;
|
let default_name = &def.type_path.segments.last().unwrap().ident;
|
||||||
let type_path = if def.type_path.leading_colon.is_none() && def.custom_path.is_none() {
|
let type_path = if def.type_path.leading_colon.is_none() && def.custom_path.is_none() {
|
||||||
|
@ -492,8 +516,9 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream {
|
||||||
/// the definitions of cannot be altered.
|
/// the definitions of cannot be altered.
|
||||||
///
|
///
|
||||||
/// This macro is an alternative to [`impl_reflect_value!`] and [`impl_from_reflect_value!`]
|
/// This macro is an alternative to [`impl_reflect_value!`] and [`impl_from_reflect_value!`]
|
||||||
/// which implement foreign types as Value types. Note that there is no `impl_from_reflect_struct`,
|
/// which implement foreign types as Value types. Note that there is no `impl_from_reflect`,
|
||||||
/// as this macro will do the job of both. This macro implements them as `Struct` types,
|
/// as this macro will do the job of both. This macro implements them using one of the reflect
|
||||||
|
/// variant traits (`bevy_reflect::{Struct, TupleStruct, Enum}`, etc.),
|
||||||
/// which have greater functionality. The type being reflected must be in scope, as you cannot
|
/// which have greater functionality. The type being reflected must be in scope, as you cannot
|
||||||
/// qualify it in the macro as e.g. `bevy::prelude::Vec3`.
|
/// qualify it in the macro as e.g. `bevy::prelude::Vec3`.
|
||||||
///
|
///
|
||||||
|
@ -510,7 +535,7 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream {
|
||||||
/// ```ignore (bevy_reflect is not accessible from this crate)
|
/// ```ignore (bevy_reflect is not accessible from this crate)
|
||||||
/// use bevy::prelude::Vec3;
|
/// use bevy::prelude::Vec3;
|
||||||
///
|
///
|
||||||
/// impl_reflect_struct!(
|
/// impl_reflect!(
|
||||||
/// #[reflect(PartialEq, Serialize, Deserialize, Default)]
|
/// #[reflect(PartialEq, Serialize, Deserialize, Default)]
|
||||||
/// #[type_path = "bevy::prelude"]
|
/// #[type_path = "bevy::prelude"]
|
||||||
/// struct Vec3 {
|
/// struct Vec3 {
|
||||||
|
@ -521,51 +546,9 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream {
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn impl_reflect_struct(input: TokenStream) -> TokenStream {
|
pub fn impl_reflect(input: TokenStream) -> TokenStream {
|
||||||
let ast = parse_macro_input!(input as DeriveInput);
|
let ast = parse_macro_input!(input as DeriveInput);
|
||||||
let derive_data = match ReflectDerive::from_input(&ast, false) {
|
match_reflect_impls(ast, ReflectImplSource::ImplRemoteType)
|
||||||
Ok(data) => data,
|
|
||||||
Err(err) => return err.into_compile_error().into(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let output = match derive_data {
|
|
||||||
ReflectDerive::Struct(struct_data) => {
|
|
||||||
if !struct_data.meta().type_path().has_custom_path() {
|
|
||||||
return syn::Error::new(
|
|
||||||
struct_data.meta().type_path().span(),
|
|
||||||
format!("a #[{TYPE_PATH_ATTRIBUTE_NAME} = \"...\"] attribute must be specified when using `impl_reflect_struct`")
|
|
||||||
)
|
|
||||||
.into_compile_error()
|
|
||||||
.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
let impl_struct = impls::impl_struct(&struct_data);
|
|
||||||
let impl_from_struct = from_reflect::impl_struct(&struct_data);
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
#impl_struct
|
|
||||||
#impl_from_struct
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ReflectDerive::TupleStruct(..) => syn::Error::new(
|
|
||||||
ast.span(),
|
|
||||||
"impl_reflect_struct does not support tuple structs",
|
|
||||||
)
|
|
||||||
.into_compile_error(),
|
|
||||||
ReflectDerive::UnitStruct(..) => syn::Error::new(
|
|
||||||
ast.span(),
|
|
||||||
"impl_reflect_struct does not support unit structs",
|
|
||||||
)
|
|
||||||
.into_compile_error(),
|
|
||||||
_ => syn::Error::new(ast.span(), "impl_reflect_struct only supports structs")
|
|
||||||
.into_compile_error(),
|
|
||||||
};
|
|
||||||
|
|
||||||
TokenStream::from(quote! {
|
|
||||||
const _: () = {
|
|
||||||
#output
|
|
||||||
};
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A macro used to generate a `FromReflect` trait implementation for the given type.
|
/// A macro used to generate a `FromReflect` trait implementation for the given type.
|
||||||
|
@ -590,7 +573,7 @@ pub fn impl_reflect_struct(input: TokenStream) -> TokenStream {
|
||||||
/// [derives `Reflect`]: Reflect
|
/// [derives `Reflect`]: Reflect
|
||||||
#[proc_macro]
|
#[proc_macro]
|
||||||
pub fn impl_from_reflect_value(input: TokenStream) -> TokenStream {
|
pub fn impl_from_reflect_value(input: TokenStream) -> TokenStream {
|
||||||
let def = parse_macro_input!(input as ReflectValueDef);
|
let def = parse_macro_input!(input with ReflectValueDef::parse_from_reflect);
|
||||||
|
|
||||||
let default_name = &def.type_path.segments.last().unwrap().ident;
|
let default_name = &def.type_path.segments.last().unwrap().ident;
|
||||||
let type_path = if def.type_path.leading_colon.is_none()
|
let type_path = if def.type_path.leading_colon.is_none()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::container_attributes::ReflectTraits;
|
use crate::container_attributes::ReflectTraits;
|
||||||
|
use crate::derive_data::ReflectTraitToImpl;
|
||||||
use crate::type_path::CustomPathDef;
|
use crate::type_path::CustomPathDef;
|
||||||
use syn::parse::{Parse, ParseStream};
|
use syn::parse::ParseStream;
|
||||||
use syn::token::Paren;
|
use syn::token::Paren;
|
||||||
use syn::{parenthesized, Attribute, Generics, Path};
|
use syn::{parenthesized, Attribute, Generics, Path};
|
||||||
|
|
||||||
|
@ -32,8 +33,16 @@ pub(crate) struct ReflectValueDef {
|
||||||
pub custom_path: Option<CustomPathDef>,
|
pub custom_path: Option<CustomPathDef>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for ReflectValueDef {
|
impl ReflectValueDef {
|
||||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
pub fn parse_reflect(input: ParseStream) -> syn::Result<Self> {
|
||||||
|
Self::parse(input, ReflectTraitToImpl::Reflect)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_from_reflect(input: ParseStream) -> syn::Result<Self> {
|
||||||
|
Self::parse(input, ReflectTraitToImpl::FromReflect)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(input: ParseStream, trait_: ReflectTraitToImpl) -> syn::Result<Self> {
|
||||||
let attrs = input.call(Attribute::parse_outer)?;
|
let attrs = input.call(Attribute::parse_outer)?;
|
||||||
|
|
||||||
let custom_path = CustomPathDef::parse_parenthesized(input)?;
|
let custom_path = CustomPathDef::parse_parenthesized(input)?;
|
||||||
|
@ -46,7 +55,7 @@ impl Parse for ReflectValueDef {
|
||||||
if input.peek(Paren) {
|
if input.peek(Paren) {
|
||||||
let content;
|
let content;
|
||||||
parenthesized!(content in input);
|
parenthesized!(content in input);
|
||||||
traits = Some(content.parse::<ReflectTraits>()?);
|
traits = Some(ReflectTraits::parse(&content, trait_)?);
|
||||||
}
|
}
|
||||||
Ok(ReflectValueDef {
|
Ok(ReflectValueDef {
|
||||||
attrs,
|
attrs,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use crate as bevy_reflect;
|
use crate as bevy_reflect;
|
||||||
use crate::prelude::ReflectDefault;
|
use crate::prelude::ReflectDefault;
|
||||||
use bevy_reflect_derive::{impl_reflect_struct, impl_reflect_value};
|
use bevy_reflect_derive::{impl_reflect, impl_reflect_value};
|
||||||
use glam::*;
|
use glam::*;
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct IVec2 {
|
struct IVec2 {
|
||||||
|
@ -11,7 +11,7 @@ impl_reflect_struct!(
|
||||||
y: i32,
|
y: i32,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct IVec3 {
|
struct IVec3 {
|
||||||
|
@ -20,7 +20,7 @@ impl_reflect_struct!(
|
||||||
z: i32,
|
z: i32,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct IVec4 {
|
struct IVec4 {
|
||||||
|
@ -31,7 +31,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct I64Vec2 {
|
struct I64Vec2 {
|
||||||
|
@ -40,7 +40,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct I64Vec3 {
|
struct I64Vec3 {
|
||||||
|
@ -50,7 +50,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct I64Vec4 {
|
struct I64Vec4 {
|
||||||
|
@ -61,7 +61,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct UVec2 {
|
struct UVec2 {
|
||||||
|
@ -69,7 +69,7 @@ impl_reflect_struct!(
|
||||||
y: u32,
|
y: u32,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct UVec3 {
|
struct UVec3 {
|
||||||
|
@ -78,7 +78,7 @@ impl_reflect_struct!(
|
||||||
z: u32,
|
z: u32,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct UVec4 {
|
struct UVec4 {
|
||||||
|
@ -89,7 +89,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct U64Vec2 {
|
struct U64Vec2 {
|
||||||
|
@ -97,7 +97,7 @@ impl_reflect_struct!(
|
||||||
y: u64,
|
y: u64,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct U64Vec3 {
|
struct U64Vec3 {
|
||||||
|
@ -106,7 +106,7 @@ impl_reflect_struct!(
|
||||||
z: u64,
|
z: u64,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, Hash, PartialEq, Default)]
|
#[reflect(Debug, Hash, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct U64Vec4 {
|
struct U64Vec4 {
|
||||||
|
@ -117,7 +117,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct Vec2 {
|
struct Vec2 {
|
||||||
|
@ -125,7 +125,7 @@ impl_reflect_struct!(
|
||||||
y: f32,
|
y: f32,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct Vec3 {
|
struct Vec3 {
|
||||||
|
@ -134,7 +134,7 @@ impl_reflect_struct!(
|
||||||
z: f32,
|
z: f32,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct Vec3A {
|
struct Vec3A {
|
||||||
|
@ -143,7 +143,7 @@ impl_reflect_struct!(
|
||||||
z: f32,
|
z: f32,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct Vec4 {
|
struct Vec4 {
|
||||||
|
@ -154,7 +154,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct BVec2 {
|
struct BVec2 {
|
||||||
|
@ -162,7 +162,7 @@ impl_reflect_struct!(
|
||||||
y: bool,
|
y: bool,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct BVec3 {
|
struct BVec3 {
|
||||||
|
@ -171,7 +171,7 @@ impl_reflect_struct!(
|
||||||
z: bool,
|
z: bool,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct BVec4 {
|
struct BVec4 {
|
||||||
|
@ -182,7 +182,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct DVec2 {
|
struct DVec2 {
|
||||||
|
@ -190,7 +190,7 @@ impl_reflect_struct!(
|
||||||
y: f64,
|
y: f64,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct DVec3 {
|
struct DVec3 {
|
||||||
|
@ -199,7 +199,7 @@ impl_reflect_struct!(
|
||||||
z: f64,
|
z: f64,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct DVec4 {
|
struct DVec4 {
|
||||||
|
@ -210,7 +210,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct Mat2 {
|
struct Mat2 {
|
||||||
|
@ -218,7 +218,7 @@ impl_reflect_struct!(
|
||||||
y_axis: Vec2,
|
y_axis: Vec2,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct Mat3 {
|
struct Mat3 {
|
||||||
|
@ -227,7 +227,7 @@ impl_reflect_struct!(
|
||||||
z_axis: Vec3,
|
z_axis: Vec3,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct Mat3A {
|
struct Mat3A {
|
||||||
|
@ -236,7 +236,7 @@ impl_reflect_struct!(
|
||||||
z_axis: Vec3A,
|
z_axis: Vec3A,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct Mat4 {
|
struct Mat4 {
|
||||||
|
@ -247,7 +247,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct DMat2 {
|
struct DMat2 {
|
||||||
|
@ -255,7 +255,7 @@ impl_reflect_struct!(
|
||||||
y_axis: DVec2,
|
y_axis: DVec2,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct DMat3 {
|
struct DMat3 {
|
||||||
|
@ -264,7 +264,7 @@ impl_reflect_struct!(
|
||||||
z_axis: DVec3,
|
z_axis: DVec3,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct DMat4 {
|
struct DMat4 {
|
||||||
|
@ -275,7 +275,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct Affine2 {
|
struct Affine2 {
|
||||||
|
@ -283,7 +283,7 @@ impl_reflect_struct!(
|
||||||
translation: Vec2,
|
translation: Vec2,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct Affine3A {
|
struct Affine3A {
|
||||||
|
@ -292,7 +292,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct DAffine2 {
|
struct DAffine2 {
|
||||||
|
@ -300,7 +300,7 @@ impl_reflect_struct!(
|
||||||
translation: DVec2,
|
translation: DVec2,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct DAffine3 {
|
struct DAffine3 {
|
||||||
|
@ -309,7 +309,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct Quat {
|
struct Quat {
|
||||||
|
@ -319,7 +319,7 @@ impl_reflect_struct!(
|
||||||
w: f32,
|
w: f32,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Default)]
|
#[reflect(Debug, PartialEq, Default)]
|
||||||
#[type_path = "glam"]
|
#[type_path = "glam"]
|
||||||
struct DQuat {
|
struct DQuat {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate as bevy_reflect;
|
use crate as bevy_reflect;
|
||||||
use crate::{ReflectDeserialize, ReflectSerialize};
|
use crate::{ReflectDeserialize, ReflectSerialize};
|
||||||
use bevy_math::{primitives::*, Vec2};
|
use bevy_math::{primitives::*, Vec2};
|
||||||
use bevy_reflect_derive::{impl_reflect_struct, impl_reflect_value};
|
use bevy_reflect_derive::{impl_reflect, impl_reflect_value};
|
||||||
|
|
||||||
impl_reflect_value!(::bevy_math::primitives::Direction2d(
|
impl_reflect_value!(::bevy_math::primitives::Direction2d(
|
||||||
Debug,
|
Debug,
|
||||||
|
@ -10,7 +10,7 @@ impl_reflect_value!(::bevy_math::primitives::Direction2d(
|
||||||
Deserialize
|
Deserialize
|
||||||
));
|
));
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Circle {
|
struct Circle {
|
||||||
|
@ -18,7 +18,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Ellipse {
|
struct Ellipse {
|
||||||
|
@ -26,7 +26,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Plane2d {
|
struct Plane2d {
|
||||||
|
@ -34,7 +34,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Line2d {
|
struct Line2d {
|
||||||
|
@ -42,7 +42,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Segment2d {
|
struct Segment2d {
|
||||||
|
@ -51,7 +51,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq)]
|
#[reflect(Debug, PartialEq)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Polyline2d<const N: usize> {
|
struct Polyline2d<const N: usize> {
|
||||||
|
@ -59,7 +59,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Triangle2d {
|
struct Triangle2d {
|
||||||
|
@ -67,7 +67,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Rectangle {
|
struct Rectangle {
|
||||||
|
@ -75,7 +75,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq)]
|
#[reflect(Debug, PartialEq)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Polygon<const N: usize> {
|
struct Polygon<const N: usize> {
|
||||||
|
@ -83,7 +83,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct RegularPolygon {
|
struct RegularPolygon {
|
||||||
|
@ -92,7 +92,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Capsule2d {
|
struct Capsule2d {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate as bevy_reflect;
|
use crate as bevy_reflect;
|
||||||
use crate::{ReflectDeserialize, ReflectSerialize};
|
use crate::{ReflectDeserialize, ReflectSerialize};
|
||||||
use bevy_math::{primitives::*, Vec3};
|
use bevy_math::{primitives::*, Vec3};
|
||||||
use bevy_reflect_derive::{impl_reflect_struct, impl_reflect_value};
|
use bevy_reflect_derive::{impl_reflect, impl_reflect_value};
|
||||||
|
|
||||||
impl_reflect_value!(::bevy_math::primitives::Direction3d(
|
impl_reflect_value!(::bevy_math::primitives::Direction3d(
|
||||||
Debug,
|
Debug,
|
||||||
|
@ -10,7 +10,7 @@ impl_reflect_value!(::bevy_math::primitives::Direction3d(
|
||||||
Deserialize
|
Deserialize
|
||||||
));
|
));
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Sphere {
|
struct Sphere {
|
||||||
|
@ -18,7 +18,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Plane3d {
|
struct Plane3d {
|
||||||
|
@ -26,7 +26,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Line3d {
|
struct Line3d {
|
||||||
|
@ -34,7 +34,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Segment3d {
|
struct Segment3d {
|
||||||
|
@ -43,7 +43,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq)]
|
#[reflect(Debug, PartialEq)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Polyline3d<const N: usize> {
|
struct Polyline3d<const N: usize> {
|
||||||
|
@ -51,7 +51,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Cuboid {
|
struct Cuboid {
|
||||||
|
@ -59,7 +59,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Cylinder {
|
struct Cylinder {
|
||||||
|
@ -68,7 +68,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Capsule3d {
|
struct Capsule3d {
|
||||||
|
@ -77,7 +77,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Cone {
|
struct Cone {
|
||||||
|
@ -86,7 +86,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct ConicalFrustum {
|
struct ConicalFrustum {
|
||||||
|
@ -96,7 +96,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[type_path = "bevy_math::primitives"]
|
#[type_path = "bevy_math::primitives"]
|
||||||
struct Torus {
|
struct Torus {
|
||||||
|
|
|
@ -2,9 +2,9 @@ use crate as bevy_reflect;
|
||||||
use crate::prelude::ReflectDefault;
|
use crate::prelude::ReflectDefault;
|
||||||
use crate::{ReflectDeserialize, ReflectSerialize};
|
use crate::{ReflectDeserialize, ReflectSerialize};
|
||||||
use bevy_math::{IRect, IVec2, Rect, URect, UVec2, Vec2};
|
use bevy_math::{IRect, IVec2, Rect, URect, UVec2, Vec2};
|
||||||
use bevy_reflect_derive::impl_reflect_struct;
|
use bevy_reflect_derive::impl_reflect;
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Hash, Serialize, Deserialize, Default)]
|
#[reflect(Debug, PartialEq, Hash, Serialize, Deserialize, Default)]
|
||||||
#[type_path = "bevy_math"]
|
#[type_path = "bevy_math"]
|
||||||
struct IRect {
|
struct IRect {
|
||||||
|
@ -13,7 +13,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Serialize, Deserialize, Default)]
|
#[reflect(Debug, PartialEq, Serialize, Deserialize, Default)]
|
||||||
#[type_path = "bevy_math"]
|
#[type_path = "bevy_math"]
|
||||||
struct Rect {
|
struct Rect {
|
||||||
|
@ -22,7 +22,7 @@ impl_reflect_struct!(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_reflect_struct!(
|
impl_reflect!(
|
||||||
#[reflect(Debug, PartialEq, Hash, Serialize, Deserialize, Default)]
|
#[reflect(Debug, PartialEq, Hash, Serialize, Deserialize, Default)]
|
||||||
#[type_path = "bevy_math"]
|
#[type_path = "bevy_math"]
|
||||||
struct URect {
|
struct URect {
|
||||||
|
|
|
@ -1565,7 +1565,7 @@ mod tests {
|
||||||
|
|
||||||
let info = <SomeStruct as Typed>::type_info();
|
let info = <SomeStruct as Typed>::type_info();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Some(" Some struct.\n\n # Example\n\n ```ignore\n let some_struct = SomeStruct;\n ```"),
|
Some(" Some struct.\n\n # Example\n\n ```ignore (This is only used for a unit test, no need to doc test)\n let some_struct = SomeStruct;\n ```"),
|
||||||
info.docs()
|
info.docs()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2095,6 +2095,42 @@ bevy_reflect::tests::Test {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn assert_impl_reflect_macro_on_all() {
|
||||||
|
struct Struct {
|
||||||
|
foo: (),
|
||||||
|
}
|
||||||
|
struct TupleStruct(());
|
||||||
|
enum Enum {
|
||||||
|
Foo { foo: () },
|
||||||
|
Bar(()),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_reflect!(
|
||||||
|
#[type_path = "my_crate::foo"]
|
||||||
|
struct Struct {
|
||||||
|
foo: (),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
impl_reflect!(
|
||||||
|
#[type_path = "my_crate::foo"]
|
||||||
|
struct TupleStruct(());
|
||||||
|
);
|
||||||
|
|
||||||
|
impl_reflect!(
|
||||||
|
#[type_path = "my_crate::foo"]
|
||||||
|
enum Enum {
|
||||||
|
Foo { foo: () },
|
||||||
|
Bar(()),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_impl_all!(Struct: Reflect);
|
||||||
|
assert_impl_all!(TupleStruct: Reflect);
|
||||||
|
assert_impl_all!(Enum: Reflect);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "glam")]
|
#[cfg(feature = "glam")]
|
||||||
mod glam {
|
mod glam {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
Loading…
Add table
Reference in a new issue