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:
radiish 2024-01-30 14:39:01 +00:00 committed by GitHub
parent 4b7ef44bb4
commit df761af49b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 258 additions and 188 deletions

View file

@ -5,11 +5,12 @@
//! the derive helper attribute for `Reflect`, which looks like:
//! `#[reflect(PartialEq, Default, ...)]` and `#[reflect_value(PartialEq, Default, ...)]`.
use crate::derive_data::ReflectTraitToImpl;
use crate::utility;
use bevy_macro_utils::fq_std::{FQAny, FQOption};
use proc_macro2::{Ident, Span, TokenTree};
use quote::quote_spanned;
use syn::parse::{Parse, ParseStream};
use syn::parse::ParseStream;
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::token::Comma;
@ -220,10 +221,7 @@ pub(crate) struct ReflectTraits {
}
impl ReflectTraits {
pub fn from_meta_list(
meta: &MetaList,
is_from_reflect_derive: bool,
) -> Result<Self, syn::Error> {
pub fn from_meta_list(meta: &MetaList, trait_: ReflectTraitToImpl) -> Result<Self, syn::Error> {
match meta.tokens.clone().into_iter().next() {
// Handles `#[reflect(where T: Trait, U::Assoc: Trait)]`
Some(TokenTree::Ident(ident)) if ident == "where" => Ok(Self {
@ -232,14 +230,14 @@ impl ReflectTraits {
}),
_ => Self::from_metas(
meta.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)?,
is_from_reflect_derive,
trait_,
),
}
}
fn from_metas(
metas: Punctuated<Meta, Comma>,
is_from_reflect_derive: bool,
trait_: ReflectTraitToImpl,
) -> Result<Self, syn::Error> {
let mut traits = ReflectTraits::default();
for meta in &metas {
@ -317,7 +315,7 @@ impl ReflectTraits {
// Override `lit` if this is a `FromReflect` derive.
// This typically means a user is opting out of the default implementation
// 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()))
.unwrap_or_else(|| lit.clone())
})?);
@ -334,6 +332,10 @@ impl ReflectTraits {
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`)
/// is registered for this type.
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.
///
/// Returns an error if the identifier already exists in the list.

View file

@ -1,3 +1,5 @@
use core::fmt;
use crate::container_attributes::{FromReflectAttrs, ReflectTraits, TypePathAttrs};
use crate::field_attributes::{parse_field_attrs, ReflectFieldAttr};
use crate::type_path::parse_path_no_leading_colon;
@ -140,10 +142,46 @@ enum ReflectMode {
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> {
pub fn from_input(
input: &'a DeriveInput,
is_from_reflect_derive: bool,
provenance: ReflectProvenance,
) -> Result<Self, syn::Error> {
let mut traits = ReflectTraits::default();
// Should indicate whether `#[reflect_value]` was used.
@ -167,8 +205,7 @@ impl<'a> ReflectDerive<'a> {
}
reflect_mode = Some(ReflectMode::Normal);
let new_traits =
ReflectTraits::from_meta_list(meta_list, is_from_reflect_derive)?;
let new_traits = ReflectTraits::from_meta_list(meta_list, provenance.trait_)?;
traits.merge(new_traits)?;
}
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);
let new_traits =
ReflectTraits::from_meta_list(meta_list, is_from_reflect_derive)?;
let new_traits = ReflectTraits::from_meta_list(meta_list, provenance.trait_)?;
traits.merge(new_traits)?;
}
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);
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")]
let meta = meta.with_docs(doc);

View file

@ -31,11 +31,10 @@ mod utility;
use crate::derive_data::{ReflectDerive, ReflectMeta, ReflectStruct};
use container_attributes::ReflectTraits;
use derive_data::ReflectTypePath;
use derive_data::{ReflectImplSource, ReflectProvenance, ReflectTraitToImpl, ReflectTypePath};
use proc_macro::TokenStream;
use quote::quote;
use reflect_value::ReflectValueDef;
use syn::spanned::Spanned;
use syn::{parse_macro_input, DeriveInput};
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_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.
///
/// 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))]
pub fn derive_reflect(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
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
};
})
match_reflect_impls(ast, ReflectImplSource::DeriveLocalType)
}
/// Derives the `FromReflect` trait.
@ -319,7 +331,13 @@ pub fn derive_reflect(input: TokenStream) -> TokenStream {
pub fn derive_from_reflect(input: TokenStream) -> TokenStream {
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,
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))]
pub fn derive_type_path(input: TokenStream) -> TokenStream {
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,
Err(err) => return err.into_compile_error().into(),
};
@ -459,7 +483,7 @@ pub fn reflect_trait(args: TokenStream, input: TokenStream) -> TokenStream {
/// [deriving `Reflect`]: Reflect
#[proc_macro]
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 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.
///
/// 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`,
/// as this macro will do the job of both. This macro implements them as `Struct` types,
/// 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 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
/// 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)
/// use bevy::prelude::Vec3;
///
/// impl_reflect_struct!(
/// impl_reflect!(
/// #[reflect(PartialEq, Serialize, Deserialize, Default)]
/// #[type_path = "bevy::prelude"]
/// struct Vec3 {
@ -521,51 +546,9 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream {
/// );
/// ```
#[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 derive_data = match ReflectDerive::from_input(&ast, false) {
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
};
})
match_reflect_impls(ast, ReflectImplSource::ImplRemoteType)
}
/// 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
#[proc_macro]
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 type_path = if def.type_path.leading_colon.is_none()

View file

@ -1,6 +1,7 @@
use crate::container_attributes::ReflectTraits;
use crate::derive_data::ReflectTraitToImpl;
use crate::type_path::CustomPathDef;
use syn::parse::{Parse, ParseStream};
use syn::parse::ParseStream;
use syn::token::Paren;
use syn::{parenthesized, Attribute, Generics, Path};
@ -32,8 +33,16 @@ pub(crate) struct ReflectValueDef {
pub custom_path: Option<CustomPathDef>,
}
impl Parse for ReflectValueDef {
fn parse(input: ParseStream) -> syn::Result<Self> {
impl ReflectValueDef {
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 custom_path = CustomPathDef::parse_parenthesized(input)?;
@ -46,7 +55,7 @@ impl Parse for ReflectValueDef {
if input.peek(Paren) {
let content;
parenthesized!(content in input);
traits = Some(content.parse::<ReflectTraits>()?);
traits = Some(ReflectTraits::parse(&content, trait_)?);
}
Ok(ReflectValueDef {
attrs,

View file

@ -1,9 +1,9 @@
use crate as bevy_reflect;
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::*;
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"]
struct IVec2 {
@ -11,7 +11,7 @@ impl_reflect_struct!(
y: i32,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"]
struct IVec3 {
@ -20,7 +20,7 @@ impl_reflect_struct!(
z: i32,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"]
struct IVec4 {
@ -31,7 +31,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"]
struct I64Vec2 {
@ -40,7 +40,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"]
struct I64Vec3 {
@ -50,7 +50,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"]
struct I64Vec4 {
@ -61,7 +61,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"]
struct UVec2 {
@ -69,7 +69,7 @@ impl_reflect_struct!(
y: u32,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"]
struct UVec3 {
@ -78,7 +78,7 @@ impl_reflect_struct!(
z: u32,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"]
struct UVec4 {
@ -89,7 +89,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"]
struct U64Vec2 {
@ -97,7 +97,7 @@ impl_reflect_struct!(
y: u64,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"]
struct U64Vec3 {
@ -106,7 +106,7 @@ impl_reflect_struct!(
z: u64,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, Hash, PartialEq, Default)]
#[type_path = "glam"]
struct U64Vec4 {
@ -117,7 +117,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct Vec2 {
@ -125,7 +125,7 @@ impl_reflect_struct!(
y: f32,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct Vec3 {
@ -134,7 +134,7 @@ impl_reflect_struct!(
z: f32,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct Vec3A {
@ -143,7 +143,7 @@ impl_reflect_struct!(
z: f32,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct Vec4 {
@ -154,7 +154,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct BVec2 {
@ -162,7 +162,7 @@ impl_reflect_struct!(
y: bool,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct BVec3 {
@ -171,7 +171,7 @@ impl_reflect_struct!(
z: bool,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct BVec4 {
@ -182,7 +182,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct DVec2 {
@ -190,7 +190,7 @@ impl_reflect_struct!(
y: f64,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct DVec3 {
@ -199,7 +199,7 @@ impl_reflect_struct!(
z: f64,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct DVec4 {
@ -210,7 +210,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct Mat2 {
@ -218,7 +218,7 @@ impl_reflect_struct!(
y_axis: Vec2,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct Mat3 {
@ -227,7 +227,7 @@ impl_reflect_struct!(
z_axis: Vec3,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct Mat3A {
@ -236,7 +236,7 @@ impl_reflect_struct!(
z_axis: Vec3A,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct Mat4 {
@ -247,7 +247,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct DMat2 {
@ -255,7 +255,7 @@ impl_reflect_struct!(
y_axis: DVec2,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct DMat3 {
@ -264,7 +264,7 @@ impl_reflect_struct!(
z_axis: DVec3,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct DMat4 {
@ -275,7 +275,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct Affine2 {
@ -283,7 +283,7 @@ impl_reflect_struct!(
translation: Vec2,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct Affine3A {
@ -292,7 +292,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct DAffine2 {
@ -300,7 +300,7 @@ impl_reflect_struct!(
translation: DVec2,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct DAffine3 {
@ -309,7 +309,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct Quat {
@ -319,7 +319,7 @@ impl_reflect_struct!(
w: f32,
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Default)]
#[type_path = "glam"]
struct DQuat {

View file

@ -1,7 +1,7 @@
use crate as bevy_reflect;
use crate::{ReflectDeserialize, ReflectSerialize};
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(
Debug,
@ -10,7 +10,7 @@ impl_reflect_value!(::bevy_math::primitives::Direction2d(
Deserialize
));
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Circle {
@ -18,7 +18,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Ellipse {
@ -26,7 +26,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Plane2d {
@ -34,7 +34,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Line2d {
@ -42,7 +42,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Segment2d {
@ -51,7 +51,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq)]
#[type_path = "bevy_math::primitives"]
struct Polyline2d<const N: usize> {
@ -59,7 +59,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Triangle2d {
@ -67,7 +67,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Rectangle {
@ -75,7 +75,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq)]
#[type_path = "bevy_math::primitives"]
struct Polygon<const N: usize> {
@ -83,7 +83,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct RegularPolygon {
@ -92,7 +92,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Capsule2d {

View file

@ -1,7 +1,7 @@
use crate as bevy_reflect;
use crate::{ReflectDeserialize, ReflectSerialize};
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(
Debug,
@ -10,7 +10,7 @@ impl_reflect_value!(::bevy_math::primitives::Direction3d(
Deserialize
));
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Sphere {
@ -18,7 +18,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Plane3d {
@ -26,7 +26,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Line3d {
@ -34,7 +34,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Segment3d {
@ -43,7 +43,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq)]
#[type_path = "bevy_math::primitives"]
struct Polyline3d<const N: usize> {
@ -51,7 +51,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Cuboid {
@ -59,7 +59,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Cylinder {
@ -68,7 +68,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Capsule3d {
@ -77,7 +77,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Cone {
@ -86,7 +86,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct ConicalFrustum {
@ -96,7 +96,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize)]
#[type_path = "bevy_math::primitives"]
struct Torus {

View file

@ -2,9 +2,9 @@ use crate as bevy_reflect;
use crate::prelude::ReflectDefault;
use crate::{ReflectDeserialize, ReflectSerialize};
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)]
#[type_path = "bevy_math"]
struct IRect {
@ -13,7 +13,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Serialize, Deserialize, Default)]
#[type_path = "bevy_math"]
struct Rect {
@ -22,7 +22,7 @@ impl_reflect_struct!(
}
);
impl_reflect_struct!(
impl_reflect!(
#[reflect(Debug, PartialEq, Hash, Serialize, Deserialize, Default)]
#[type_path = "bevy_math"]
struct URect {

View file

@ -1565,7 +1565,7 @@ mod tests {
let info = <SomeStruct as Typed>::type_info();
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()
);
@ -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")]
mod glam {
use super::*;