From ba72a330f95967d6d03f30b5681d61fdf3c93ae3 Mon Sep 17 00:00:00 2001 From: Gino Valente <49806985+MrGVSV@users.noreply.github.com> Date: Wed, 28 Jun 2023 18:31:34 -0700 Subject: [PATCH] bevy_reflect: `FromReflect` Ergonomics Implementation (#6056) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Objective **This implementation is based on https://github.com/bevyengine/rfcs/pull/59.** --- Resolves #4597 Full details and motivation can be found in the RFC, but here's a brief summary. `FromReflect` is a very powerful and important trait within the reflection API. It allows Dynamic types (e.g., `DynamicList`, etc.) to be formed into Real ones (e.g., `Vec`, etc.). This mainly comes into play concerning deserialization, where the reflection deserializers both return a `Box` that almost always contain one of these Dynamic representations of a Real type. To convert this to our Real type, we need to use `FromReflect`. It also sneaks up in other ways. For example, it's a required bound for `T` in `Vec` so that `Vec` as a whole can be made `FromReflect`. It's also required by all fields of an enum as it's used as part of the `Reflect::apply` implementation. So in other words, much like `GetTypeRegistration` and `Typed`, it is very much a core reflection trait. The problem is that it is not currently treated like a core trait and is not automatically derived alongside `Reflect`. This makes using it a bit cumbersome and easy to forget. ## Solution Automatically derive `FromReflect` when deriving `Reflect`. Users can then choose to opt-out if needed using the `#[reflect(from_reflect = false)]` attribute. ```rust #[derive(Reflect)] struct Foo; #[derive(Reflect)] #[reflect(from_reflect = false)] struct Bar; fn test(value: T) {} test(Foo); // <-- OK test(Bar); // <-- Panic! Bar does not implement trait `FromReflect` ``` #### `ReflectFromReflect` This PR also automatically adds the `ReflectFromReflect` (introduced in #6245) registration to the derived `GetTypeRegistration` impl— if the type hasn't opted out of `FromReflect` of course.

Improved Deserialization

> **Warning** > This section includes changes that have since been descoped from this PR. They will likely be implemented again in a followup PR. I am mainly leaving these details in for archival purposes, as well as for reference when implementing this logic again. And since we can do all the above, we might as well improve deserialization. We can now choose to deserialize into a Dynamic type or automatically convert it using `FromReflect` under the hood. `[Un]TypedReflectDeserializer::new` will now perform the conversion and return the `Box`'d Real type. `[Un]TypedReflectDeserializer::new_dynamic` will work like what we have now and simply return the `Box`'d Dynamic type. ```rust // Returns the Real type let reflect_deserializer = UntypedReflectDeserializer::new(®istry); let mut deserializer = ron::de::Deserializer::from_str(input)?; let output: SomeStruct = reflect_deserializer.deserialize(&mut deserializer)?.take()?; // Returns the Dynamic type let reflect_deserializer = UntypedReflectDeserializer::new_dynamic(®istry); let mut deserializer = ron::de::Deserializer::from_str(input)?; let output: DynamicStruct = reflect_deserializer.deserialize(&mut deserializer)?.take()?; ```
--- ## Changelog * `FromReflect` is now automatically derived within the `Reflect` derive macro * This includes auto-registering `ReflectFromReflect` in the derived `GetTypeRegistration` impl * ~~Renamed `TypedReflectDeserializer::new` and `UntypedReflectDeserializer::new` to `TypedReflectDeserializer::new_dynamic` and `UntypedReflectDeserializer::new_dynamic`, respectively~~ **Descoped** * ~~Changed `TypedReflectDeserializer::new` and `UntypedReflectDeserializer::new` to automatically convert the deserialized output using `FromReflect`~~ **Descoped** ## Migration Guide * `FromReflect` is now automatically derived within the `Reflect` derive macro. Items with both derives will need to remove the `FromReflect` one. ```rust // OLD #[derive(Reflect, FromReflect)] struct Foo; // NEW #[derive(Reflect)] struct Foo; ``` If using a manual implementation of `FromReflect` and the `Reflect` derive, users will need to opt-out of the automatic implementation. ```rust // OLD #[derive(Reflect)] struct Foo; impl FromReflect for Foo {/* ... */} // NEW #[derive(Reflect)] #[reflect(from_reflect = false)] struct Foo; impl FromReflect for Foo {/* ... */} ```

Removed Migrations

> **Warning** > This section includes changes that have since been descoped from this PR. They will likely be implemented again in a followup PR. I am mainly leaving these details in for archival purposes, as well as for reference when implementing this logic again. * The reflect deserializers now perform a `FromReflect` conversion internally. The expected output of `TypedReflectDeserializer::new` and `UntypedReflectDeserializer::new` is no longer a Dynamic (e.g., `DynamicList`), but its Real counterpart (e.g., `Vec`). ```rust let reflect_deserializer = UntypedReflectDeserializer::new_dynamic(®istry); let mut deserializer = ron::de::Deserializer::from_str(input)?; // OLD let output: DynamicStruct = reflect_deserializer.deserialize(&mut deserializer)?.take()?; // NEW let output: SomeStruct = reflect_deserializer.deserialize(&mut deserializer)?.take()?; ``` Alternatively, if this behavior isn't desired, use the `TypedReflectDeserializer::new_dynamic` and `UntypedReflectDeserializer::new_dynamic` methods instead: ```rust // OLD let reflect_deserializer = UntypedReflectDeserializer::new(®istry); // NEW let reflect_deserializer = UntypedReflectDeserializer::new_dynamic(®istry); ```
--------- Co-authored-by: Carter Anderson --- crates/bevy_animation/src/lib.rs | 10 +- crates/bevy_asset/src/handle.rs | 24 +--- crates/bevy_asset/src/path.rs | 38 +----- crates/bevy_asset/src/reflect.rs | 4 +- crates/bevy_core/src/name.rs | 8 +- .../bevy_core_pipeline/src/bloom/settings.rs | 5 +- crates/bevy_core_pipeline/src/clear_color.rs | 12 +- .../src/core_2d/camera_2d.rs | 6 +- .../src/core_3d/camera_3d.rs | 15 +-- crates/bevy_core_pipeline/src/fxaa/mod.rs | 12 +- crates/bevy_core_pipeline/src/prepass/mod.rs | 11 +- .../bevy_core_pipeline/src/tonemapping/mod.rs | 30 +---- crates/bevy_ecs/src/reflect/mod.rs | 6 +- crates/bevy_gizmos/src/lib.rs | 8 +- crates/bevy_gltf/src/lib.rs | 6 +- .../bevy_hierarchy/src/components/children.rs | 6 +- .../bevy_hierarchy/src/components/parent.rs | 6 +- crates/bevy_input/src/gamepad.rs | 63 +++++---- crates/bevy_input/src/input.rs | 6 +- crates/bevy_input/src/keyboard.rs | 14 +- crates/bevy_input/src/lib.rs | 6 +- crates/bevy_input/src/mouse.rs | 22 ++-- crates/bevy_input/src/touch.rs | 14 +- crates/bevy_input/src/touchpad.rs | 10 +- crates/bevy_pbr/src/alpha.rs | 6 +- crates/bevy_pbr/src/bundle.rs | 10 +- crates/bevy_pbr/src/fog.rs | 9 +- crates/bevy_pbr/src/light.rs | 53 ++++---- crates/bevy_pbr/src/parallax.rs | 4 +- crates/bevy_pbr/src/pbr_material.rs | 8 +- crates/bevy_pbr/src/wireframe.rs | 10 +- crates/bevy_reflect/README.md | 2 +- .../src/container_attributes.rs | 80 +++++++++++- .../bevy_reflect_derive/src/derive_data.rs | 56 +++----- .../bevy_reflect_derive/src/documentation.rs | 2 +- .../src/field_attributes.rs | 4 +- .../bevy_reflect_derive/src/from_reflect.rs | 82 +++++++----- .../bevy_reflect_derive/src/impls/enums.rs | 7 +- .../bevy_reflect_derive/src/impls/structs.rs | 7 +- .../src/impls/tuple_structs.rs | 7 +- .../bevy_reflect_derive/src/impls/values.rs | 9 +- .../bevy_reflect_derive/src/lib.rs | 102 ++++++++++++--- .../bevy_reflect_derive/src/registration.rs | 16 ++- .../bevy_reflect_derive/src/utility.rs | 123 ++++++++++++++---- crates/bevy_reflect/src/enums/mod.rs | 4 +- crates/bevy_reflect/src/from_reflect.rs | 7 +- crates/bevy_reflect/src/impls/glam.rs | 5 +- crates/bevy_reflect/src/impls/smol_str.rs | 3 +- crates/bevy_reflect/src/impls/std.rs | 57 +------- crates/bevy_reflect/src/impls/uuid.rs | 4 +- crates/bevy_reflect/src/lib.rs | 36 ++--- crates/bevy_reflect/src/path.rs | 4 +- crates/bevy_reflect/src/serde/de.rs | 24 ++-- crates/bevy_reflect/src/serde/ser.rs | 14 +- .../tests/reflect_derive/bounds.pass.rs | 36 ++--- .../tests/reflect_derive/from_reflect.fail.rs | 25 ++++ .../reflect_derive/from_reflect.fail.stderr | 21 +++ .../tests/reflect_derive/from_reflect.pass.rs | 23 ++++ .../tests/reflect_derive/generics.fail.rs | 1 + .../tests/reflect_derive/generics.fail.stderr | 11 +- .../reflect_derive/generics_structs.pass.rs | 26 +++- crates/bevy_render/src/camera/camera.rs | 8 +- .../src/camera/manual_texture_view.rs | 16 +-- crates/bevy_render/src/camera/projection.rs | 13 +- crates/bevy_render/src/color/mod.rs | 4 +- crates/bevy_render/src/mesh/mesh/skinning.rs | 6 +- crates/bevy_render/src/primitives/mod.rs | 16 +-- crates/bevy_render/src/texture/image.rs | 4 +- crates/bevy_render/src/view/visibility/mod.rs | 15 +-- crates/bevy_scene/src/serde.rs | 4 +- .../bevy_sprite/src/mesh2d/color_material.rs | 2 +- crates/bevy_sprite/src/mesh2d/mesh.rs | 6 +- crates/bevy_sprite/src/sprite.rs | 6 +- crates/bevy_sprite/src/texture_atlas.rs | 6 +- crates/bevy_text/src/text.rs | 6 +- crates/bevy_text/src/text2d.rs | 6 +- crates/bevy_time/src/stopwatch.rs | 2 +- crates/bevy_time/src/time.rs | 6 +- crates/bevy_time/src/timer.rs | 4 +- .../src/components/global_transform.rs | 6 +- .../src/components/transform.rs | 4 +- crates/bevy_ui/src/camera_config.rs | 6 +- crates/bevy_ui/src/focus.rs | 19 +-- crates/bevy_ui/src/geometry.rs | 6 +- crates/bevy_ui/src/measurement.rs | 6 +- crates/bevy_ui/src/ui_node.rs | 115 ++++++++-------- crates/bevy_ui/src/widget/button.rs | 6 +- crates/bevy_ui/src/widget/image.rs | 6 +- crates/bevy_ui/src/widget/label.rs | 6 +- crates/bevy_ui/src/widget/text.rs | 6 +- crates/bevy_window/src/cursor.rs | 6 +- crates/bevy_window/src/event.rs | 66 +++++----- crates/bevy_window/src/window.rs | 64 +++++---- examples/reflection/reflection.rs | 9 ++ 94 files changed, 922 insertions(+), 779 deletions(-) create mode 100644 crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/from_reflect.fail.rs create mode 100644 crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/from_reflect.fail.stderr create mode 100644 crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/from_reflect.pass.rs diff --git a/crates/bevy_animation/src/lib.rs b/crates/bevy_animation/src/lib.rs index bdf814b8b525f..cd02bee00045e 100644 --- a/crates/bevy_animation/src/lib.rs +++ b/crates/bevy_animation/src/lib.rs @@ -12,7 +12,7 @@ use bevy_core::Name; use bevy_ecs::prelude::*; use bevy_hierarchy::{Children, Parent}; use bevy_math::{Quat, Vec3}; -use bevy_reflect::{FromReflect, Reflect, TypeUuid}; +use bevy_reflect::{Reflect, TypeUuid}; use bevy_render::mesh::morph::MorphWeights; use bevy_time::Time; use bevy_transform::{prelude::Transform, TransformSystem}; @@ -27,7 +27,7 @@ pub mod prelude { } /// List of keyframes for one of the attribute of a [`Transform`]. -#[derive(Reflect, FromReflect, Clone, Debug)] +#[derive(Reflect, Clone, Debug)] pub enum Keyframes { /// Keyframes for rotation. Rotation(Vec), @@ -49,7 +49,7 @@ pub enum Keyframes { /// Describes how an attribute of a [`Transform`] or [`MorphWeights`] should be animated. /// /// `keyframe_timestamps` and `keyframes` should have the same length. -#[derive(Reflect, FromReflect, Clone, Debug)] +#[derive(Reflect, Clone, Debug)] pub struct VariableCurve { /// Timestamp for each of the keyframes. pub keyframe_timestamps: Vec, @@ -58,14 +58,14 @@ pub struct VariableCurve { } /// Path to an entity, with [`Name`]s. Each entity in a path must have a name. -#[derive(Reflect, FromReflect, Clone, Debug, Hash, PartialEq, Eq, Default)] +#[derive(Reflect, Clone, Debug, Hash, PartialEq, Eq, Default)] pub struct EntityPath { /// Parts of the path pub parts: Vec, } /// A list of [`VariableCurve`], and the [`EntityPath`] to which they apply. -#[derive(Reflect, FromReflect, Clone, TypeUuid, Debug, Default)] +#[derive(Reflect, Clone, TypeUuid, Debug, Default)] #[uuid = "d81b7179-0448-4eb0-89fe-c067222725bf"] pub struct AnimationClip { curves: Vec>, diff --git a/crates/bevy_asset/src/handle.rs b/crates/bevy_asset/src/handle.rs index e5ae0bd023ae6..035885862d722 100644 --- a/crates/bevy_asset/src/handle.rs +++ b/crates/bevy_asset/src/handle.rs @@ -10,28 +10,14 @@ use crate::{ Asset, Assets, }; use bevy_ecs::{component::Component, reflect::ReflectComponent}; -use bevy_reflect::{ - std_traits::ReflectDefault, FromReflect, Reflect, ReflectDeserialize, ReflectFromReflect, - ReflectSerialize, -}; +use bevy_reflect::{std_traits::ReflectDefault, Reflect, ReflectDeserialize, ReflectSerialize}; use bevy_utils::Uuid; use crossbeam_channel::{Receiver, Sender}; use serde::{Deserialize, Serialize}; /// A unique, stable asset id. #[derive( - Debug, - Clone, - Copy, - Eq, - PartialEq, - Hash, - Ord, - PartialOrd, - Serialize, - Deserialize, - Reflect, - FromReflect, + Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize, Reflect, )] #[reflect_value(Serialize, Deserialize, PartialEq, Hash)] pub enum HandleId { @@ -103,8 +89,8 @@ impl HandleId { /// handle to the unloaded asset, but it will not be able to retrieve the image data, resulting in /// collisions no longer being detected for that entity. /// -#[derive(Component, Reflect, FromReflect)] -#[reflect(Component, Default, FromReflect)] +#[derive(Component, Reflect)] +#[reflect(Component, Default)] pub struct Handle where T: Asset, @@ -117,7 +103,9 @@ where marker: PhantomData T>, } +#[derive(Default)] enum HandleType { + #[default] Weak, Strong(Sender), } diff --git a/crates/bevy_asset/src/path.rs b/crates/bevy_asset/src/path.rs index 43f248384f2bf..85ca220a357da 100644 --- a/crates/bevy_asset/src/path.rs +++ b/crates/bevy_asset/src/path.rs @@ -1,6 +1,4 @@ -use bevy_reflect::{ - FromReflect, Reflect, ReflectDeserialize, ReflectFromReflect, ReflectSerialize, -}; +use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize}; use bevy_utils::{AHasher, RandomState}; use serde::{Deserialize, Serialize}; use std::{ @@ -10,8 +8,8 @@ use std::{ }; /// Represents a path to an asset in the file system. -#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, Hash, Serialize, Deserialize, FromReflect)] +#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize, Reflect)] +#[reflect(Debug, PartialEq, Hash, Serialize, Deserialize)] pub struct AssetPath<'a> { path: Cow<'a, Path>, label: Option>, @@ -69,38 +67,16 @@ impl<'a> AssetPath<'a> { /// An unique identifier to an asset path. #[derive( - Debug, - Clone, - Copy, - Eq, - PartialEq, - Hash, - Ord, - PartialOrd, - Serialize, - Deserialize, - Reflect, - FromReflect, + Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize, Reflect, )] -#[reflect_value(PartialEq, Hash, Serialize, Deserialize, FromReflect)] +#[reflect_value(PartialEq, Hash, Serialize, Deserialize)] pub struct AssetPathId(SourcePathId, LabelId); /// An unique identifier to the source path of an asset. #[derive( - Debug, - Clone, - Copy, - Eq, - PartialEq, - Hash, - Ord, - PartialOrd, - Serialize, - Deserialize, - Reflect, - FromReflect, + Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize, Reflect, )] -#[reflect_value(PartialEq, Hash, Serialize, Deserialize, FromReflect)] +#[reflect_value(PartialEq, Hash, Serialize, Deserialize)] pub struct SourcePathId(u64); /// An unique identifier to a sub-asset label. diff --git a/crates/bevy_asset/src/reflect.rs b/crates/bevy_asset/src/reflect.rs index cade543c20b48..98c54c69a8e9f 100644 --- a/crates/bevy_asset/src/reflect.rs +++ b/crates/bevy_asset/src/reflect.rs @@ -255,11 +255,11 @@ mod tests { use bevy_app::App; use bevy_ecs::reflect::AppTypeRegistry; - use bevy_reflect::{FromReflect, Reflect, ReflectMut, TypeUuid}; + use bevy_reflect::{Reflect, ReflectMut, TypeUuid}; use crate::{AddAsset, AssetPlugin, HandleUntyped, ReflectAsset}; - #[derive(Reflect, FromReflect, TypeUuid)] + #[derive(Reflect, TypeUuid)] #[uuid = "09191350-1238-4736-9a89-46f04bda6966"] struct AssetType { field: String, diff --git a/crates/bevy_core/src/name.rs b/crates/bevy_core/src/name.rs index 59e507055f824..9ab3f2ab16fd0 100644 --- a/crates/bevy_core/src/name.rs +++ b/crates/bevy_core/src/name.rs @@ -1,8 +1,8 @@ use bevy_ecs::{ component::Component, entity::Entity, query::WorldQuery, reflect::ReflectComponent, }; -use bevy_reflect::{std_traits::ReflectDefault, FromReflect}; -use bevy_reflect::{Reflect, ReflectFromReflect}; +use bevy_reflect::std_traits::ReflectDefault; +use bevy_reflect::Reflect; use bevy_utils::AHasher; use std::{ borrow::Cow, @@ -17,8 +17,8 @@ use std::{ /// [`Name`] should not be treated as a globally unique identifier for entities, /// as multiple entities can have the same name. [`bevy_ecs::entity::Entity`] should be /// used instead as the default unique identifier. -#[derive(Reflect, FromReflect, Component, Clone)] -#[reflect(Component, Default, Debug, FromReflect)] +#[derive(Reflect, Component, Clone)] +#[reflect(Component, Default, Debug)] pub struct Name { hash: u64, // TODO: Shouldn't be serialized name: Cow<'static, str>, diff --git a/crates/bevy_core_pipeline/src/bloom/settings.rs b/crates/bevy_core_pipeline/src/bloom/settings.rs index 43422869a67d6..553fa75c6cc0c 100644 --- a/crates/bevy_core_pipeline/src/bloom/settings.rs +++ b/crates/bevy_core_pipeline/src/bloom/settings.rs @@ -1,7 +1,7 @@ use super::downsampling_pipeline::BloomUniforms; use bevy_ecs::{prelude::Component, query::QueryItem, reflect::ReflectComponent}; use bevy_math::{UVec4, Vec4}; -use bevy_reflect::{std_traits::ReflectDefault, FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::{extract_component::ExtractComponent, prelude::Camera}; /// Applies a bloom effect to an HDR-enabled 2d or 3d camera. @@ -160,8 +160,7 @@ impl Default for BloomSettings { /// * Changing these settings creates a physically inaccurate image /// * Changing these settings makes it easy to make the final result look worse /// * Non-default prefilter settings should be used in conjuction with [`BloomCompositeMode::Additive`] -#[derive(Default, Clone, Reflect, FromReflect)] -#[reflect(FromReflect)] +#[derive(Default, Clone, Reflect)] pub struct BloomPrefilterSettings { /// Baseline of the quadratic threshold curve (default: 0.0). /// diff --git a/crates/bevy_core_pipeline/src/clear_color.rs b/crates/bevy_core_pipeline/src/clear_color.rs index d0315073357e8..50861e1bebb1f 100644 --- a/crates/bevy_core_pipeline/src/clear_color.rs +++ b/crates/bevy_core_pipeline/src/clear_color.rs @@ -1,13 +1,11 @@ use bevy_derive::{Deref, DerefMut}; use bevy_ecs::prelude::*; -use bevy_reflect::{ - FromReflect, Reflect, ReflectDeserialize, ReflectFromReflect, ReflectSerialize, -}; +use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize}; use bevy_render::{color::Color, extract_resource::ExtractResource}; use serde::{Deserialize, Serialize}; -#[derive(Reflect, FromReflect, Serialize, Deserialize, Clone, Debug, Default)] -#[reflect(Serialize, Deserialize, FromReflect)] +#[derive(Reflect, Serialize, Deserialize, Clone, Debug, Default)] +#[reflect(Serialize, Deserialize)] pub enum ClearColorConfig { #[default] Default, @@ -19,8 +17,8 @@ pub enum ClearColorConfig { /// /// This color appears as the "background" color for simple apps, /// when there are portions of the screen with nothing rendered. -#[derive(Resource, Clone, Debug, Deref, DerefMut, ExtractResource, Reflect, FromReflect)] -#[reflect(Resource, FromReflect)] +#[derive(Resource, Clone, Debug, Deref, DerefMut, ExtractResource, Reflect)] +#[reflect(Resource)] pub struct ClearColor(pub Color); impl Default for ClearColor { diff --git a/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs b/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs index f79e3ffaf92e7..36765180a15ad 100644 --- a/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs +++ b/crates/bevy_core_pipeline/src/core_2d/camera_2d.rs @@ -3,7 +3,7 @@ use crate::{ tonemapping::{DebandDither, Tonemapping}, }; use bevy_ecs::prelude::*; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; use bevy_render::{ camera::{Camera, CameraProjection, CameraRenderGraph, OrthographicProjection}, extract_component::ExtractComponent, @@ -12,9 +12,9 @@ use bevy_render::{ }; use bevy_transform::prelude::{GlobalTransform, Transform}; -#[derive(Component, Default, Reflect, FromReflect, Clone, ExtractComponent)] +#[derive(Component, Default, Reflect, Clone, ExtractComponent)] #[extract_component_filter(With)] -#[reflect(Component, FromReflect)] +#[reflect(Component)] pub struct Camera2d { pub clear_color: ClearColorConfig, } diff --git a/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs b/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs index d28ee5bc63dea..f8f01286cc84f 100644 --- a/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs +++ b/crates/bevy_core_pipeline/src/core_3d/camera_3d.rs @@ -3,9 +3,7 @@ use crate::{ tonemapping::{DebandDither, Tonemapping}, }; use bevy_ecs::prelude::*; -use bevy_reflect::{ - FromReflect, Reflect, ReflectDeserialize, ReflectFromReflect, ReflectSerialize, -}; +use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize}; use bevy_render::{ camera::{Camera, CameraRenderGraph, Projection}, extract_component::ExtractComponent, @@ -17,9 +15,9 @@ use bevy_transform::prelude::{GlobalTransform, Transform}; use serde::{Deserialize, Serialize}; /// Configuration for the "main 3d render graph". -#[derive(Component, Reflect, FromReflect, Clone, ExtractComponent)] +#[derive(Component, Reflect, Clone, ExtractComponent)] #[extract_component_filter(With)] -#[reflect(Component, FromReflect)] +#[reflect(Component)] pub struct Camera3d { /// The clear color operation to perform for the main 3d pass. pub clear_color: ClearColorConfig, @@ -39,8 +37,7 @@ impl Default for Camera3d { } } -#[derive(Clone, Copy, Reflect, FromReflect)] -#[reflect(FromReflect)] +#[derive(Clone, Copy, Reflect)] pub struct Camera3dDepthTextureUsage(u32); impl From for Camera3dDepthTextureUsage { @@ -55,8 +52,8 @@ impl From for TextureUsages { } /// The depth clear operation to perform for the main 3d pass. -#[derive(Reflect, FromReflect, Serialize, Deserialize, Clone, Debug)] -#[reflect(Serialize, Deserialize, FromReflect)] +#[derive(Reflect, Serialize, Deserialize, Clone, Debug)] +#[reflect(Serialize, Deserialize)] pub enum Camera3dDepthLoadOp { /// Clear with a specified value. /// Note that 0.0 is the far plane due to bevy's use of reverse-z projections. diff --git a/crates/bevy_core_pipeline/src/fxaa/mod.rs b/crates/bevy_core_pipeline/src/fxaa/mod.rs index e153a77b623b0..8b0c0433d96fb 100644 --- a/crates/bevy_core_pipeline/src/fxaa/mod.rs +++ b/crates/bevy_core_pipeline/src/fxaa/mod.rs @@ -7,9 +7,7 @@ use bevy_app::prelude::*; use bevy_asset::{load_internal_asset, HandleUntyped}; use bevy_derive::Deref; use bevy_ecs::prelude::*; -use bevy_reflect::{ - std_traits::ReflectDefault, FromReflect, Reflect, ReflectFromReflect, TypeUuid, -}; +use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypeUuid}; use bevy_render::{ extract_component::{ExtractComponent, ExtractComponentPlugin}, prelude::Camera, @@ -26,8 +24,8 @@ mod node; pub use node::FxaaNode; -#[derive(Reflect, FromReflect, Eq, PartialEq, Hash, Clone, Copy)] -#[reflect(FromReflect, PartialEq, Hash)] +#[derive(Reflect, Eq, PartialEq, Hash, Clone, Copy)] +#[reflect(PartialEq, Hash)] pub enum Sensitivity { Low, Medium, @@ -48,8 +46,8 @@ impl Sensitivity { } } -#[derive(Reflect, FromReflect, Component, Clone, ExtractComponent)] -#[reflect(Component, FromReflect, Default)] +#[derive(Reflect, Component, Clone, ExtractComponent)] +#[reflect(Component, Default)] #[extract_component_filter(With)] pub struct Fxaa { /// Enable render passes for FXAA. diff --git a/crates/bevy_core_pipeline/src/prepass/mod.rs b/crates/bevy_core_pipeline/src/prepass/mod.rs index 4aa098eae3362..93bcebe0318c3 100644 --- a/crates/bevy_core_pipeline/src/prepass/mod.rs +++ b/crates/bevy_core_pipeline/src/prepass/mod.rs @@ -30,7 +30,7 @@ pub mod node; use std::cmp::Reverse; use bevy_ecs::prelude::*; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; use bevy_render::{ render_phase::{CachedRenderPipelinePhaseItem, DrawFunctionId, PhaseItem}, render_resource::{CachedRenderPipelineId, Extent3d, TextureFormat}, @@ -43,19 +43,16 @@ pub const NORMAL_PREPASS_FORMAT: TextureFormat = TextureFormat::Rgb10a2Unorm; pub const MOTION_VECTOR_PREPASS_FORMAT: TextureFormat = TextureFormat::Rg16Float; /// If added to a [`crate::prelude::Camera3d`] then depth values will be copied to a separate texture available to the main pass. -#[derive(Component, Default, Reflect, FromReflect)] -#[reflect(FromReflect)] +#[derive(Component, Default, Reflect)] pub struct DepthPrepass; /// If added to a [`crate::prelude::Camera3d`] then vertex world normals will be copied to a separate texture available to the main pass. /// Normals will have normal map textures already applied. -#[derive(Component, Default, Reflect, FromReflect)] -#[reflect(FromReflect)] +#[derive(Component, Default, Reflect)] pub struct NormalPrepass; /// If added to a [`crate::prelude::Camera3d`] then screen space motion vectors will be copied to a separate texture available to the main pass. -#[derive(Component, Default, Reflect, FromReflect)] -#[reflect(FromReflect)] +#[derive(Component, Default, Reflect)] pub struct MotionVectorPrepass; /// Textures that are written to by the prepass. diff --git a/crates/bevy_core_pipeline/src/tonemapping/mod.rs b/crates/bevy_core_pipeline/src/tonemapping/mod.rs index 0896c37f3ec9b..c7a049604f8fd 100644 --- a/crates/bevy_core_pipeline/src/tonemapping/mod.rs +++ b/crates/bevy_core_pipeline/src/tonemapping/mod.rs @@ -2,7 +2,7 @@ use crate::fullscreen_vertex_shader::fullscreen_shader_vertex_state; use bevy_app::prelude::*; use bevy_asset::{load_internal_asset, Assets, Handle, HandleUntyped}; use bevy_ecs::prelude::*; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect, TypeUuid}; +use bevy_reflect::{Reflect, TypeUuid}; use bevy_render::camera::Camera; use bevy_render::extract_component::{ExtractComponent, ExtractComponentPlugin}; use bevy_render::extract_resource::{ExtractResource, ExtractResourcePlugin}; @@ -116,20 +116,10 @@ pub struct TonemappingPipeline { /// Optionally enables a tonemapping shader that attempts to map linear input stimulus into a perceptually uniform image for a given [`Camera`] entity. #[derive( - Component, - Debug, - Hash, - Clone, - Copy, - Reflect, - Default, - ExtractComponent, - PartialEq, - Eq, - FromReflect, + Component, Debug, Hash, Clone, Copy, Reflect, Default, ExtractComponent, PartialEq, Eq, )] #[extract_component_filter(With)] -#[reflect(Component, FromReflect)] +#[reflect(Component)] pub enum Tonemapping { /// Bypass tonemapping. None, @@ -303,20 +293,10 @@ pub fn queue_view_tonemapping_pipelines( } /// Enables a debanding shader that applies dithering to mitigate color banding in the final image for a given [`Camera`] entity. #[derive( - Component, - Debug, - Hash, - Clone, - Copy, - Reflect, - Default, - ExtractComponent, - PartialEq, - Eq, - FromReflect, + Component, Debug, Hash, Clone, Copy, Reflect, Default, ExtractComponent, PartialEq, Eq, )] #[extract_component_filter(With)] -#[reflect(Component, FromReflect)] +#[reflect(Component)] pub enum DebandDither { #[default] Disabled, diff --git a/crates/bevy_ecs/src/reflect/mod.rs b/crates/bevy_ecs/src/reflect/mod.rs index 54d0bc8812664..bcfb1770b770a 100644 --- a/crates/bevy_ecs/src/reflect/mod.rs +++ b/crates/bevy_ecs/src/reflect/mod.rs @@ -4,10 +4,7 @@ use std::ops::{Deref, DerefMut}; use crate as bevy_ecs; use crate::{entity::Entity, system::Resource}; -use bevy_reflect::{ - impl_from_reflect_value, impl_reflect_value, ReflectDeserialize, ReflectSerialize, - TypeRegistryArc, -}; +use bevy_reflect::{impl_reflect_value, ReflectDeserialize, ReflectSerialize, TypeRegistryArc}; mod component; mod map_entities; @@ -39,4 +36,3 @@ impl DerefMut for AppTypeRegistry { } impl_reflect_value!((in bevy_ecs) Entity(Hash, PartialEq, Serialize, Deserialize)); -impl_from_reflect_value!(Entity); diff --git a/crates/bevy_gizmos/src/lib.rs b/crates/bevy_gizmos/src/lib.rs index 7ef99e2568a51..89b265e19e19d 100644 --- a/crates/bevy_gizmos/src/lib.rs +++ b/crates/bevy_gizmos/src/lib.rs @@ -34,9 +34,7 @@ use bevy_ecs::{ Commands, Query, Res, ResMut, Resource, SystemParamItem, }, }; -use bevy_reflect::{ - std_traits::ReflectDefault, FromReflect, Reflect, ReflectFromReflect, TypePath, TypeUuid, -}; +use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypePath, TypeUuid}; use bevy_render::{ color::Color, extract_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin}, @@ -199,8 +197,8 @@ pub struct AabbGizmoConfig { } /// Add this [`Component`] to an entity to draw its [`Aabb`] component. -#[derive(Component, Reflect, FromReflect, Default, Debug)] -#[reflect(Component, FromReflect, Default)] +#[derive(Component, Reflect, Default, Debug)] +#[reflect(Component, Default)] pub struct AabbGizmo { /// The color of the box. /// diff --git a/crates/bevy_gltf/src/lib.rs b/crates/bevy_gltf/src/lib.rs index 74ca9455066ed..7277a906269f5 100644 --- a/crates/bevy_gltf/src/lib.rs +++ b/crates/bevy_gltf/src/lib.rs @@ -12,7 +12,7 @@ use bevy_app::prelude::*; use bevy_asset::{AddAsset, Handle}; use bevy_ecs::{prelude::Component, reflect::ReflectComponent}; use bevy_pbr::StandardMaterial; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect, TypePath, TypeUuid}; +use bevy_reflect::{Reflect, TypePath, TypeUuid}; use bevy_render::{ mesh::{Mesh, MeshVertexAttribute}, renderer::RenderDevice, @@ -106,8 +106,8 @@ pub struct GltfPrimitive { pub material_extras: Option, } -#[derive(Clone, Debug, Reflect, FromReflect, Default, Component)] -#[reflect(Component, FromReflect)] +#[derive(Clone, Debug, Reflect, Default, Component)] +#[reflect(Component)] pub struct GltfExtras { pub value: String, } diff --git a/crates/bevy_hierarchy/src/components/children.rs b/crates/bevy_hierarchy/src/components/children.rs index 816b8e518cfb4..02d9e0e388329 100644 --- a/crates/bevy_hierarchy/src/components/children.rs +++ b/crates/bevy_hierarchy/src/components/children.rs @@ -5,7 +5,7 @@ use bevy_ecs::{ reflect::{ReflectComponent, ReflectMapEntities}, world::World, }; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; use core::slice; use smallvec::SmallVec; use std::ops::Deref; @@ -16,8 +16,8 @@ use std::ops::Deref; /// /// [`HierarchyQueryExt`]: crate::query_extension::HierarchyQueryExt /// [`Query`]: bevy_ecs::system::Query -#[derive(Component, Debug, Reflect, FromReflect)] -#[reflect(Component, MapEntities, FromReflect)] +#[derive(Component, Debug, Reflect)] +#[reflect(Component, MapEntities)] pub struct Children(pub(crate) SmallVec<[Entity; 8]>); impl MapEntities for Children { diff --git a/crates/bevy_hierarchy/src/components/parent.rs b/crates/bevy_hierarchy/src/components/parent.rs index 5c44789dbcfb6..7bccf33ed6e1e 100644 --- a/crates/bevy_hierarchy/src/components/parent.rs +++ b/crates/bevy_hierarchy/src/components/parent.rs @@ -4,7 +4,7 @@ use bevy_ecs::{ reflect::{ReflectComponent, ReflectMapEntities}, world::{FromWorld, World}, }; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; use std::ops::Deref; /// Holds a reference to the parent entity of this entity. @@ -14,8 +14,8 @@ use std::ops::Deref; /// /// [`HierarchyQueryExt`]: crate::query_extension::HierarchyQueryExt /// [`Query`]: bevy_ecs::system::Query -#[derive(Component, Debug, Eq, PartialEq, Reflect, FromReflect)] -#[reflect(Component, MapEntities, PartialEq, FromReflect)] +#[derive(Component, Debug, Eq, PartialEq, Reflect)] +#[reflect(Component, MapEntities, PartialEq)] pub struct Parent(pub(crate) Entity); impl Parent { diff --git a/crates/bevy_input/src/gamepad.rs b/crates/bevy_input/src/gamepad.rs index 153ef8d807ef1..e81c075b759a9 100644 --- a/crates/bevy_input/src/gamepad.rs +++ b/crates/bevy_input/src/gamepad.rs @@ -4,8 +4,7 @@ use bevy_ecs::{ change_detection::DetectChangesMut, system::{Res, ResMut, Resource}, }; -use bevy_reflect::ReflectFromReflect; -use bevy_reflect::{std_traits::ReflectDefault, FromReflect, Reflect}; +use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_utils::Duration; use bevy_utils::{tracing::info, HashMap}; use thiserror::Error; @@ -73,8 +72,8 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; /// ## Note /// /// The `ID` of a gamepad is fixed until the gamepad disconnects or the app is restarted. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Reflect, FromReflect)] -#[reflect(Debug, Hash, PartialEq, FromReflect)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Reflect)] +#[reflect(Debug, Hash, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -93,8 +92,8 @@ impl Gamepad { } /// Metadata associated with a [`Gamepad`]. -#[derive(Debug, Clone, PartialEq, Eq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Debug, Clone, PartialEq, Eq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -154,8 +153,8 @@ impl Gamepads { /// [`GamepadButtonChangedEvent`]. It is also used in the [`GamepadButton`] /// which in turn is used to create the [`Input`] or /// [`Axis`] `bevy` resources. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Reflect, FromReflect)] -#[reflect(Debug, Hash, PartialEq, FromReflect)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Reflect)] +#[reflect(Debug, Hash, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -219,8 +218,8 @@ pub enum GamepadButtonType { /// ## Updating /// /// The gamepad button resources are updated inside of the [`gamepad_button_event_system`]. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Reflect, FromReflect)] -#[reflect(Debug, Hash, PartialEq, FromReflect)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Reflect)] +#[reflect(Debug, Hash, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -261,8 +260,8 @@ impl GamepadButton { /// This is used to determine which axis has changed its value when receiving a /// [`GamepadAxisChangedEvent`]. It is also used in the [`GamepadAxis`] /// which in turn is used to create the [`Axis`] `bevy` resource. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Reflect, FromReflect)] -#[reflect(Debug, Hash, PartialEq, FromReflect)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Reflect)] +#[reflect(Debug, Hash, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -297,8 +296,8 @@ pub enum GamepadAxisType { /// ## Updating /// /// The gamepad axes resources are updated inside of the [`gamepad_axis_event_system`]. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Reflect, FromReflect)] -#[reflect(Debug, Hash, PartialEq, FromReflect)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Reflect)] +#[reflect(Debug, Hash, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -342,8 +341,8 @@ impl GamepadAxis { /// The [`GamepadSettings`] are used inside of `bevy_gilrs` to determine when raw gamepad events from `gilrs`, /// should register as a [`GamepadEvent`]. Events that don't meet the change thresholds defined in [`GamepadSettings`] /// will not register. To modify these settings, mutate the corresponding resource. -#[derive(Resource, Default, Debug, Reflect, FromReflect)] -#[reflect(Debug, Default, FromReflect)] +#[derive(Resource, Default, Debug, Reflect)] +#[reflect(Debug, Default)] pub struct GamepadSettings { /// The default button settings. pub default_button_settings: ButtonSettings, @@ -425,8 +424,8 @@ impl GamepadSettings { /// value is surpassed and released if the `release_threshold` value is undercut. /// /// Allowed values: `0.0 <= ``release_threshold`` <= ``press_threshold`` <= 1.0` -#[derive(Debug, Clone, Reflect, FromReflect)] -#[reflect(Debug, Default, FromReflect)] +#[derive(Debug, Clone, Reflect)] +#[reflect(Debug, Default)] pub struct ButtonSettings { press_threshold: f32, release_threshold: f32, @@ -585,8 +584,8 @@ impl ButtonSettings { /// Otherwise, values will not be rounded. /// /// The valid range is `[-1.0, 1.0]`. -#[derive(Debug, Clone, Reflect, FromReflect, PartialEq)] -#[reflect(Debug, Default, FromReflect)] +#[derive(Debug, Clone, Reflect, PartialEq)] +#[reflect(Debug, Default)] pub struct AxisSettings { /// Values that are higher than `livezone_upperbound` will be rounded up to 1.0. livezone_upperbound: f32, @@ -917,8 +916,8 @@ impl AxisSettings { /// ## Updating /// /// The current value of a button is received through the [`GamepadButtonChangedEvent`]. -#[derive(Debug, Clone, Reflect, FromReflect)] -#[reflect(Debug, Default, FromReflect)] +#[derive(Debug, Clone, Reflect)] +#[reflect(Debug, Default)] pub struct ButtonAxisSettings { /// The high value at which to apply rounding. pub high: f32, @@ -1026,8 +1025,8 @@ pub fn gamepad_connection_system( } } -#[derive(Debug, Clone, PartialEq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Debug, Clone, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -1040,8 +1039,8 @@ pub enum GamepadConnection { /// A Gamepad connection event. Created when a connection to a gamepad /// is established and when a gamepad is disconnected. -#[derive(Event, Debug, Clone, PartialEq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -1071,8 +1070,8 @@ impl GamepadConnectionEvent { } } -#[derive(Event, Debug, Clone, PartialEq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -1096,8 +1095,8 @@ impl GamepadAxisChangedEvent { /// Gamepad event for when the "value" (amount of pressure) on the button /// changes by an amount larger than the threshold defined in [`GamepadSettings`]. -#[derive(Event, Debug, Clone, PartialEq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -1159,8 +1158,8 @@ pub fn gamepad_button_event_system( /// This event type is used over the [`GamepadConnectionEvent`], /// [`GamepadButtonChangedEvent`] and [`GamepadAxisChangedEvent`] when /// the in-frame relative ordering of events is important. -#[derive(Event, Debug, Clone, PartialEq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), diff --git a/crates/bevy_input/src/input.rs b/crates/bevy_input/src/input.rs index a395a3d8dbba5..3758840fecd65 100644 --- a/crates/bevy_input/src/input.rs +++ b/crates/bevy_input/src/input.rs @@ -1,5 +1,5 @@ use bevy_ecs::system::Resource; -use bevy_reflect::{std_traits::ReflectDefault, FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_utils::HashSet; use std::hash::Hash; @@ -41,8 +41,8 @@ use bevy_ecs::schedule::State; /// ///[`ResMut`]: bevy_ecs::system::ResMut ///[`DetectChangesMut::bypass_change_detection`]: bevy_ecs::change_detection::DetectChangesMut::bypass_change_detection -#[derive(Debug, Clone, Resource, Reflect, FromReflect)] -#[reflect(Default, FromReflect)] +#[derive(Debug, Clone, Resource, Reflect)] +#[reflect(Default)] pub struct Input { /// A collection of every button that is currently being pressed. pressed: HashSet, diff --git a/crates/bevy_input/src/keyboard.rs b/crates/bevy_input/src/keyboard.rs index dd32ba8d827f5..edf291b6320d9 100644 --- a/crates/bevy_input/src/keyboard.rs +++ b/crates/bevy_input/src/keyboard.rs @@ -5,7 +5,7 @@ use bevy_ecs::{ event::{Event, EventReader}, system::ResMut, }; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; #[cfg(feature = "serialize")] use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; @@ -19,8 +19,8 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; /// /// The event is consumed inside of the [`keyboard_input_system`](crate::keyboard::keyboard_input_system) /// to update the [`Input`](crate::Input) resource. -#[derive(Event, Debug, Clone, Copy, PartialEq, Eq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, Copy, PartialEq, Eq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -78,8 +78,8 @@ pub fn keyboard_input_system( /// ## Updating /// /// The resource is updated inside of the [`keyboard_input_system`](crate::keyboard::keyboard_input_system). -#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy, Reflect, FromReflect)] -#[reflect(Debug, Hash, PartialEq, FromReflect)] +#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy, Reflect)] +#[reflect(Debug, Hash, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -451,8 +451,8 @@ pub enum KeyCode { /// ## Updating /// /// The resource is updated inside of the [`keyboard_input_system`](crate::keyboard::keyboard_input_system). -#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy, Reflect, FromReflect)] -#[reflect(Debug, Hash, PartialEq, FromReflect)] +#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy, Reflect)] +#[reflect(Debug, Hash, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), diff --git a/crates/bevy_input/src/lib.rs b/crates/bevy_input/src/lib.rs index 4f343ece0dbf2..ab5b445bf5529 100644 --- a/crates/bevy_input/src/lib.rs +++ b/crates/bevy_input/src/lib.rs @@ -28,7 +28,7 @@ pub mod prelude { use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; use keyboard::{keyboard_input_system, KeyCode, KeyboardInput, ScanCode}; use mouse::{ mouse_button_input_system, MouseButton, MouseButtonInput, MouseMotion, MouseScrollUnit, @@ -140,8 +140,8 @@ impl Plugin for InputPlugin { } /// The current "press" state of an element -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Reflect, FromReflect)] -#[reflect(Debug, Hash, PartialEq, FromReflect)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Reflect)] +#[reflect(Debug, Hash, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), diff --git a/crates/bevy_input/src/mouse.rs b/crates/bevy_input/src/mouse.rs index 53dbff777fbcd..deb8b8c4a03a1 100644 --- a/crates/bevy_input/src/mouse.rs +++ b/crates/bevy_input/src/mouse.rs @@ -6,7 +6,7 @@ use bevy_ecs::{ system::ResMut, }; use bevy_math::Vec2; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; #[cfg(feature = "serialize")] use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; @@ -19,8 +19,8 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; /// /// The event is read inside of the [`mouse_button_input_system`](crate::mouse::mouse_button_input_system) /// to update the [`Input`](crate::Input) resource. -#[derive(Event, Debug, Clone, Copy, PartialEq, Eq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, Copy, PartialEq, Eq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -45,8 +45,8 @@ pub struct MouseButtonInput { /// ## Updating /// /// The resource is updated inside of the [`mouse_button_input_system`](crate::mouse::mouse_button_input_system). -#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy, Reflect, FromReflect)] -#[reflect(Debug, Hash, PartialEq, FromReflect)] +#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy, Reflect)] +#[reflect(Debug, Hash, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -72,8 +72,8 @@ pub enum MouseButton { /// However, the event data does not make it possible to distinguish which device it is referring to. /// /// [`DeviceEvent::MouseMotion`]: https://docs.rs/winit/latest/winit/event/enum.DeviceEvent.html#variant.MouseMotion -#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -90,8 +90,8 @@ pub struct MouseMotion { /// /// The value of the event can either be interpreted as the amount of lines or the amount of pixels /// to scroll. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Debug, Clone, Copy, Eq, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -113,8 +113,8 @@ pub enum MouseScrollUnit { /// A mouse wheel event. /// /// This event is the translated version of the `WindowEvent::MouseWheel` from the `winit` crate. -#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), diff --git a/crates/bevy_input/src/touch.rs b/crates/bevy_input/src/touch.rs index a17853b88f8fa..64293b9d22426 100644 --- a/crates/bevy_input/src/touch.rs +++ b/crates/bevy_input/src/touch.rs @@ -1,7 +1,7 @@ use bevy_ecs::event::{Event, EventReader}; use bevy_ecs::system::{ResMut, Resource}; use bevy_math::Vec2; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; use bevy_utils::HashMap; #[cfg(feature = "serialize")] @@ -30,8 +30,8 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; /// /// This event is the translated version of the `WindowEvent::Touch` from the `winit` crate. /// It is available to the end user and can be used for game logic. -#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -52,8 +52,8 @@ pub struct TouchInput { } /// A force description of a [`Touch`](crate::touch::Touch) input. -#[derive(Debug, Clone, Copy, PartialEq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Debug, Clone, Copy, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -98,8 +98,8 @@ pub enum ForceTouch { /// This includes a phase that indicates that a touch input has started or ended, /// or that a finger has moved. There is also a canceled phase that indicates that /// the system canceled the tracking of the finger. -#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy, Reflect, FromReflect)] -#[reflect(Debug, Hash, PartialEq, FromReflect)] +#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy, Reflect)] +#[reflect(Debug, Hash, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), diff --git a/crates/bevy_input/src/touchpad.rs b/crates/bevy_input/src/touchpad.rs index bc70267716028..358c44585edbd 100644 --- a/crates/bevy_input/src/touchpad.rs +++ b/crates/bevy_input/src/touchpad.rs @@ -1,5 +1,5 @@ use bevy_ecs::event::Event; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; #[cfg(feature = "serialize")] use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; @@ -12,8 +12,8 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; /// ## Platform-specific /// /// - Only available on **`macOS`**. -#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -29,8 +29,8 @@ pub struct TouchpadMagnify(pub f32); /// ## Platform-specific /// /// - Only available on **`macOS`**. -#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, Copy, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), diff --git a/crates/bevy_pbr/src/alpha.rs b/crates/bevy_pbr/src/alpha.rs index 34d10b91fe648..2dfad77ac9a60 100644 --- a/crates/bevy_pbr/src/alpha.rs +++ b/crates/bevy_pbr/src/alpha.rs @@ -1,10 +1,10 @@ use bevy_reflect::std_traits::ReflectDefault; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; // TODO: add discussion about performance. /// Sets how a material's base color alpha channel is used for transparency. -#[derive(Debug, Default, Reflect, Copy, Clone, PartialEq, FromReflect)] -#[reflect(Default, Debug, FromReflect)] +#[derive(Debug, Default, Reflect, Copy, Clone, PartialEq)] +#[reflect(Default, Debug)] pub enum AlphaMode { /// Base color alpha values are overridden to be fully opaque (1.0). #[default] diff --git a/crates/bevy_pbr/src/bundle.rs b/crates/bevy_pbr/src/bundle.rs index 704e349877a21..0590dba4abdb6 100644 --- a/crates/bevy_pbr/src/bundle.rs +++ b/crates/bevy_pbr/src/bundle.rs @@ -4,7 +4,7 @@ use crate::{ }; use bevy_asset::Handle; use bevy_ecs::{bundle::Bundle, component::Component, prelude::Entity, reflect::ReflectComponent}; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; use bevy_render::{ mesh::Mesh, primitives::{CascadesFrusta, CubemapFrusta, Frustum}, @@ -42,8 +42,8 @@ impl Default for MaterialMeshBundle { } } -#[derive(Component, Clone, Debug, Default, Reflect, FromReflect)] -#[reflect(Component, FromReflect)] +#[derive(Component, Clone, Debug, Default, Reflect)] +#[reflect(Component)] pub struct CubemapVisibleEntities { #[reflect(ignore)] data: [VisibleEntities; 6], @@ -67,8 +67,8 @@ impl CubemapVisibleEntities { } } -#[derive(Component, Clone, Debug, Default, Reflect, FromReflect)] -#[reflect(Component, FromReflect)] +#[derive(Component, Clone, Debug, Default, Reflect)] +#[reflect(Component)] pub struct CascadesVisibleEntities { /// Map of view entity to the visible entities for each cascade frustum. #[reflect(ignore)] diff --git a/crates/bevy_pbr/src/fog.rs b/crates/bevy_pbr/src/fog.rs index 0c2f054214637..c5ad092f5467a 100644 --- a/crates/bevy_pbr/src/fog.rs +++ b/crates/bevy_pbr/src/fog.rs @@ -1,7 +1,7 @@ use crate::ReflectComponent; use bevy_ecs::{prelude::*, query::QueryItem}; use bevy_math::Vec3; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; use bevy_render::{color::Color, extract_component::ExtractComponent, prelude::Camera}; /// Configures the “classic” computer graphics [distance fog](https://en.wikipedia.org/wiki/Distance_fog) effect, @@ -47,8 +47,8 @@ use bevy_render::{color::Color, extract_component::ExtractComponent, prelude::Ca /// /// Once enabled for a specific camera, the fog effect can also be disabled for individual /// [`StandardMaterial`](crate::StandardMaterial) instances via the `fog_enabled` flag. -#[derive(Debug, Clone, Component, Reflect, FromReflect)] -#[reflect(Component, FromReflect)] +#[derive(Debug, Clone, Component, Reflect)] +#[reflect(Component)] pub struct FogSettings { /// The color of the fog effect. /// @@ -94,8 +94,7 @@ pub struct FogSettings { /// - [`FogFalloff::from_visibility_colors()`] /// - [`FogFalloff::from_visibility_contrast_color()`] /// - [`FogFalloff::from_visibility_contrast_colors()`] -#[derive(Debug, Clone, Reflect, FromReflect)] -#[reflect(FromReflect)] +#[derive(Debug, Clone, Reflect)] pub enum FogFalloff { /// A linear fog falloff that grows in intensity between `start` and `end` distances. /// diff --git a/crates/bevy_pbr/src/light.rs b/crates/bevy_pbr/src/light.rs index 54c337e1ff0c3..3e8c0d45177e6 100644 --- a/crates/bevy_pbr/src/light.rs +++ b/crates/bevy_pbr/src/light.rs @@ -40,8 +40,8 @@ use crate::{ /// | 4000 | 300 | | 75-100 | 40.5 | /// /// Source: [Wikipedia](https://en.wikipedia.org/wiki/Lumen_(unit)#Lighting) -#[derive(Component, Debug, Clone, Copy, Reflect, FromReflect)] -#[reflect(Component, Default, FromReflect)] +#[derive(Component, Debug, Clone, Copy, Reflect)] +#[reflect(Component, Default)] pub struct PointLight { pub color: Color, pub intensity: f32, @@ -75,8 +75,8 @@ impl PointLight { pub const DEFAULT_SHADOW_NORMAL_BIAS: f32 = 0.6; } -#[derive(Resource, Clone, Debug, Reflect, FromReflect)] -#[reflect(Resource, FromReflect)] +#[derive(Resource, Clone, Debug, Reflect)] +#[reflect(Resource)] pub struct PointLightShadowMap { pub size: usize, } @@ -91,8 +91,8 @@ impl Default for PointLightShadowMap { /// Behaves like a point light in a perfectly absorbent housing that /// shines light only in a given direction. The direction is taken from /// the transform, and can be specified with [`Transform::looking_at`](bevy_transform::components::Transform::looking_at). -#[derive(Component, Debug, Clone, Copy, Reflect, FromReflect)] -#[reflect(Component, Default, FromReflect)] +#[derive(Component, Debug, Clone, Copy, Reflect)] +#[reflect(Component, Default)] pub struct SpotLight { pub color: Color, pub intensity: f32, @@ -187,8 +187,8 @@ impl Default for SpotLight { /// App::new() /// .insert_resource(DirectionalLightShadowMap { size: 2048 }); /// ``` -#[derive(Component, Debug, Clone, Reflect, FromReflect)] -#[reflect(Component, Default, FromReflect)] +#[derive(Component, Debug, Clone, Reflect)] +#[reflect(Component, Default)] pub struct DirectionalLight { pub color: Color, /// Illuminance in lux @@ -218,8 +218,8 @@ impl DirectionalLight { } /// Controls the resolution of [`DirectionalLight`] shadow maps. -#[derive(Resource, Clone, Debug, Reflect, FromReflect)] -#[reflect(Resource, FromReflect)] +#[derive(Resource, Clone, Debug, Reflect)] +#[reflect(Resource)] pub struct DirectionalLightShadowMap { pub size: usize, } @@ -243,8 +243,8 @@ impl Default for DirectionalLightShadowMap { /// ..default() /// }.into(); /// ``` -#[derive(Component, Clone, Debug, Reflect, FromReflect)] -#[reflect(Component, FromReflect)] +#[derive(Component, Clone, Debug, Reflect)] +#[reflect(Component)] pub struct CascadeShadowConfig { /// The (positive) distance to the far boundary of each cascade. pub bounds: Vec, @@ -380,15 +380,14 @@ impl From for CascadeShadowConfig { } } -#[derive(Component, Clone, Debug, Default, Reflect, FromReflect)] -#[reflect(Component, FromReflect)] +#[derive(Component, Clone, Debug, Default, Reflect)] +#[reflect(Component)] pub struct Cascades { /// Map from a view to the configuration of each of its [`Cascade`]s. pub(crate) cascades: HashMap>, } -#[derive(Clone, Debug, Default, Reflect, FromReflect)] -#[reflect(FromReflect)] +#[derive(Clone, Debug, Default, Reflect)] pub struct Cascade { /// The transform of the light, i.e. the view to world matrix. pub(crate) view_transform: Mat4, @@ -581,8 +580,8 @@ fn calculate_cascade( } /// An ambient light, which lights the entire scene equally. -#[derive(Resource, Clone, Debug, ExtractResource, Reflect, FromReflect)] -#[reflect(Resource, FromReflect)] +#[derive(Resource, Clone, Debug, ExtractResource, Reflect)] +#[reflect(Resource)] pub struct AmbientLight { pub color: Color, /// A direct scale factor multiplied with `color` before being passed to the shader. @@ -599,12 +598,12 @@ impl Default for AmbientLight { } /// Add this component to make a [`Mesh`](bevy_render::mesh::Mesh) not cast shadows. -#[derive(Component, Reflect, FromReflect, Default)] -#[reflect(Component, Default, FromReflect)] +#[derive(Component, Reflect, Default)] +#[reflect(Component, Default)] pub struct NotShadowCaster; /// Add this component to make a [`Mesh`](bevy_render::mesh::Mesh) not receive shadows. -#[derive(Component, Reflect, FromReflect, Default)] -#[reflect(Component, Default, FromReflect)] +#[derive(Component, Reflect, Default)] +#[reflect(Component, Default)] pub struct NotShadowReceiver; #[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)] @@ -628,7 +627,7 @@ pub enum SimulationLightSystems { /// Configure the far z-plane mode used for the furthest depth slice for clustered forward /// rendering -#[derive(Debug, Copy, Clone, Reflect, FromReflect)] +#[derive(Debug, Copy, Clone, Reflect)] pub enum ClusterFarZMode { /// Calculate the required maximum z-depth based on currently visible lights. /// Makes better use of available clusters, speeding up GPU lighting operations @@ -640,8 +639,8 @@ pub enum ClusterFarZMode { } /// Configure the depth-slicing strategy for clustered forward rendering -#[derive(Debug, Copy, Clone, Reflect, FromReflect)] -#[reflect(Default, FromReflect)] +#[derive(Debug, Copy, Clone, Reflect)] +#[reflect(Default)] pub struct ClusterZConfig { /// Far `Z` plane of the first depth slice pub first_slice_depth: f32, @@ -659,8 +658,8 @@ impl Default for ClusterZConfig { } /// Configuration of the clustering strategy for clustered forward rendering -#[derive(Debug, Copy, Clone, Component, Reflect, FromReflect)] -#[reflect(Component, FromReflect)] +#[derive(Debug, Copy, Clone, Component, Reflect)] +#[reflect(Component)] pub enum ClusterConfig { /// Disable light cluster calculations for this view None, diff --git a/crates/bevy_pbr/src/parallax.rs b/crates/bevy_pbr/src/parallax.rs index b9e9389040786..e458f88146701 100644 --- a/crates/bevy_pbr/src/parallax.rs +++ b/crates/bevy_pbr/src/parallax.rs @@ -1,4 +1,4 @@ -use bevy_reflect::{FromReflect, Reflect}; +use bevy_reflect::Reflect; /// The [parallax mapping] method to use to compute depth based on the /// material's [`depth_map`]. @@ -11,7 +11,7 @@ use bevy_reflect::{FromReflect, Reflect}; /// /// [`depth_map`]: crate::StandardMaterial::depth_map /// [parallax mapping]: https://en.wikipedia.org/wiki/Parallax_mapping -#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, Reflect, FromReflect)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, Reflect)] pub enum ParallaxMappingMethod { /// A simple linear interpolation, using a single texture sample. /// diff --git a/crates/bevy_pbr/src/pbr_material.rs b/crates/bevy_pbr/src/pbr_material.rs index e5b8cb6c01125..8e3520160d1f1 100644 --- a/crates/bevy_pbr/src/pbr_material.rs +++ b/crates/bevy_pbr/src/pbr_material.rs @@ -4,9 +4,7 @@ use crate::{ }; use bevy_asset::Handle; use bevy_math::Vec4; -use bevy_reflect::{ - std_traits::ReflectDefault, FromReflect, Reflect, ReflectFromReflect, TypeUuid, -}; +use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypeUuid}; use bevy_render::{ color::Color, mesh::MeshVertexBufferLayout, render_asset::RenderAssets, render_resource::*, texture::Image, @@ -17,11 +15,11 @@ use bevy_render::{ /// . /// /// May be created directly from a [`Color`] or an [`Image`]. -#[derive(AsBindGroup, Reflect, FromReflect, Debug, Clone, TypeUuid)] +#[derive(AsBindGroup, Reflect, Debug, Clone, TypeUuid)] #[uuid = "7494888b-c082-457b-aacf-517228cc0c22"] #[bind_group_data(StandardMaterialKey)] #[uniform(0, StandardMaterialUniform)] -#[reflect(Default, Debug, FromReflect)] +#[reflect(Default, Debug)] pub struct StandardMaterial { /// The color of the surface of the material before lighting. /// diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index 21988ecc94267..07898068fcd24 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -5,7 +5,7 @@ use bevy_asset::{load_internal_asset, Handle, HandleUntyped}; use bevy_core_pipeline::core_3d::Opaque3d; use bevy_ecs::{prelude::*, reflect::ReflectComponent}; use bevy_reflect::std_traits::ReflectDefault; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect, TypeUuid}; +use bevy_reflect::{Reflect, TypeUuid}; use bevy_render::extract_component::{ExtractComponent, ExtractComponentPlugin}; use bevy_render::Render; use bevy_render::{ @@ -61,12 +61,12 @@ impl Plugin for WireframePlugin { } /// Controls whether an entity should rendered in wireframe-mode if the [`WireframePlugin`] is enabled -#[derive(Component, Debug, Clone, Default, ExtractComponent, Reflect, FromReflect)] -#[reflect(Component, Default, FromReflect)] +#[derive(Component, Debug, Clone, Default, ExtractComponent, Reflect)] +#[reflect(Component, Default)] pub struct Wireframe; -#[derive(Resource, Debug, Clone, Default, ExtractResource, Reflect, FromReflect)] -#[reflect(Resource, FromReflect)] +#[derive(Resource, Debug, Clone, Default, ExtractResource, Reflect)] +#[reflect(Resource)] pub struct WireframeConfig { /// Whether to show wireframes for all meshes. If `false`, only meshes with a [Wireframe] component will be rendered. pub global: bool, diff --git a/crates/bevy_reflect/README.md b/crates/bevy_reflect/README.md index 23344dedc2322..dba4b0f2430f8 100644 --- a/crates/bevy_reflect/README.md +++ b/crates/bevy_reflect/README.md @@ -28,7 +28,7 @@ struct Foo { #[derive(Reflect)] struct Bar(String); -#[derive(Reflect, FromReflect)] +#[derive(Reflect)] struct Baz { value: f32, } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs index 101bf0334efb1..a7acbb2748d90 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs @@ -13,7 +13,7 @@ use syn::parse::{Parse, ParseStream}; use syn::punctuated::Punctuated; use syn::spanned::Spanned; use syn::token::Comma; -use syn::{Meta, Path}; +use syn::{LitBool, Meta, Path}; // The "special" trait idents that are used internally for reflection. // Received via attributes like `#[reflect(PartialEq, Hash, ...)]` @@ -25,6 +25,9 @@ const HASH_ATTR: &str = "Hash"; // but useful to know exist nonetheless pub(crate) const REFLECT_DEFAULT: &str = "ReflectDefault"; +// Attributes for `FromReflect` implementation +const FROM_REFLECT_ATTR: &str = "from_reflect"; + // The error message to show when a trait/type is specified multiple times const CONFLICTING_TYPE_DATA_MESSAGE: &str = "conflicting type data registration"; @@ -62,6 +65,40 @@ impl TraitImpl { } } +/// A collection of attributes used for deriving `FromReflect`. +#[derive(Clone, Default)] +pub(crate) struct FromReflectAttrs { + auto_derive: Option, +} + +impl FromReflectAttrs { + /// Returns true if `FromReflect` should be automatically derived as part of the `Reflect` derive. + pub fn should_auto_derive(&self) -> bool { + self.auto_derive + .as_ref() + .map(|lit| lit.value()) + .unwrap_or(true) + } + + /// Merges this [`FromReflectAttrs`] with another. + pub fn merge(&mut self, other: FromReflectAttrs) -> Result<(), syn::Error> { + if let Some(new) = other.auto_derive { + if let Some(existing) = &self.auto_derive { + if existing.value() != new.value() { + return Err(syn::Error::new( + new.span(), + format!("`from_reflect` already set to {}", existing.value()), + )); + } + } else { + self.auto_derive = Some(new); + } + } + + Ok(()) + } +} + /// A collection of traits that have been registered for a reflected type. /// /// This keeps track of a few traits that are utilized internally for reflection @@ -128,11 +165,15 @@ pub(crate) struct ReflectTraits { debug: TraitImpl, hash: TraitImpl, partial_eq: TraitImpl, + from_reflect: FromReflectAttrs, idents: Vec, } impl ReflectTraits { - pub fn from_metas(metas: Punctuated) -> Result { + pub fn from_metas( + metas: Punctuated, + is_from_reflect_derive: bool, + ) -> Result { let mut traits = ReflectTraits::default(); for meta in &metas { match meta { @@ -201,7 +242,31 @@ impl ReflectTraits { Ok(()) })?; } - _ => {} + Meta::NameValue(pair) => { + if pair.path.is_ident(FROM_REFLECT_ATTR) { + traits.from_reflect.auto_derive = match &pair.value { + syn::Expr::Lit(syn::ExprLit { + lit: syn::Lit::Bool(lit), + .. + }) => { + // Overrride `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 + .then(|| LitBool::new(true, Span::call_site())) + .or_else(|| Some(lit.clone())) + } + _ => { + return Err(syn::Error::new( + pair.value.span(), + "Expected a boolean value", + )) + } + }; + } else { + return Err(syn::Error::new(pair.path.span(), "Unknown attribute")); + } + } } } @@ -219,6 +284,12 @@ impl ReflectTraits { &self.idents } + /// The `FromReflect` attributes on this type. + #[allow(clippy::wrong_self_convention)] + pub fn from_reflect(&self) -> &FromReflectAttrs { + &self.from_reflect + } + /// Returns the implementation of `Reflect::reflect_hash` as a `TokenStream`. /// /// If `Hash` was not registered, returns `None`. @@ -295,6 +366,7 @@ impl ReflectTraits { self.debug.merge(other.debug)?; self.hash.merge(other.hash)?; self.partial_eq.merge(other.partial_eq)?; + self.from_reflect.merge(other.from_reflect)?; for ident in other.idents { add_unique_ident(&mut self.idents, ident)?; } @@ -304,7 +376,7 @@ impl ReflectTraits { impl Parse for ReflectTraits { fn parse(input: ParseStream) -> syn::Result { - ReflectTraits::from_metas(Punctuated::::parse_terminated(input)?) + ReflectTraits::from_metas(Punctuated::::parse_terminated(input)?, false) } } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs b/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs index 3dc9db462d707..0bf42461deb70 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs @@ -1,6 +1,5 @@ -use crate::container_attributes::ReflectTraits; +use crate::container_attributes::{FromReflectAttrs, ReflectTraits}; use crate::field_attributes::{parse_field_attrs, ReflectFieldAttr}; -use crate::fq_std::{FQAny, FQDefault, FQSend, FQSync}; use crate::type_path::parse_path_no_leading_colon; use crate::utility::{members_to_serialization_denylist, StringExpr, WhereClauseOptions}; use bit_set::BitSet; @@ -89,6 +88,7 @@ pub(crate) struct ReflectEnum<'a> { } /// Represents a field on a struct or tuple struct. +#[derive(Clone)] pub(crate) struct StructField<'a> { /// The raw field. pub data: &'a Field, @@ -134,7 +134,10 @@ enum ReflectMode { } impl<'a> ReflectDerive<'a> { - pub fn from_input(input: &'a DeriveInput) -> Result { + pub fn from_input( + input: &'a DeriveInput, + is_from_reflect_derive: bool, + ) -> Result { let mut traits = ReflectTraits::default(); // Should indicate whether `#[reflect_value]` was used. let mut reflect_mode = None; @@ -159,6 +162,7 @@ impl<'a> ReflectDerive<'a> { reflect_mode = Some(ReflectMode::Normal); let new_traits = ReflectTraits::from_metas( meta_list.parse_args_with(Punctuated::::parse_terminated)?, + is_from_reflect_derive, )?; traits.merge(new_traits)?; } @@ -173,6 +177,7 @@ impl<'a> ReflectDerive<'a> { reflect_mode = Some(ReflectMode::Value); let new_traits = ReflectTraits::from_metas( meta_list.parse_args_with(Punctuated::::parse_terminated)?, + is_from_reflect_derive, )?; traits.merge(new_traits)?; } @@ -376,6 +381,12 @@ impl<'a> ReflectMeta<'a> { &self.traits } + /// The `FromReflect` attributes on this type. + #[allow(clippy::wrong_self_convention)] + pub fn from_reflect(&self) -> &FromReflectAttrs { + self.traits.from_reflect() + } + /// The name of this struct. pub fn type_path(&self) -> &ReflectTypePath<'a> { &self.type_path @@ -443,13 +454,6 @@ impl<'a> ReflectStruct<'a> { .filter(|field| field.attrs.ignore.is_active()) } - /// Get a collection of types which are ignored by the reflection API - pub fn ignored_types(&self) -> Vec { - self.ignored_fields() - .map(|field| field.data.ty.clone()) - .collect() - } - /// Get an iterator of fields which are ignored by the reflection API pub fn ignored_fields(&self) -> impl Iterator> { self.fields @@ -464,14 +468,7 @@ impl<'a> ReflectStruct<'a> { } pub fn where_clause_options(&self) -> WhereClauseOptions { - let bevy_reflect_path = &self.meta().bevy_reflect_path; - WhereClauseOptions { - active_types: self.active_types().into(), - active_trait_bounds: quote! { #bevy_reflect_path::Reflect }, - ignored_types: self.ignored_types().into(), - ignored_trait_bounds: quote! { #FQAny + #FQSend + #FQSync }, - ..WhereClauseOptions::type_path_bounds(self.meta()) - } + WhereClauseOptions::new(self.meta(), self.active_fields(), self.ignored_fields()) } } @@ -501,13 +498,6 @@ impl<'a> ReflectEnum<'a> { .flat_map(|variant| variant.active_fields()) } - /// Get a collection of types which are exposed to the reflection API - pub fn active_types(&self) -> Vec { - self.active_fields() - .map(|field| field.data.ty.clone()) - .collect() - } - /// Get an iterator of fields which are ignored by the reflection API pub fn ignored_fields(&self) -> impl Iterator> { self.variants() @@ -515,22 +505,8 @@ impl<'a> ReflectEnum<'a> { .flat_map(|variant| variant.ignored_fields()) } - /// Get a collection of types which are ignored to the reflection API - pub fn ignored_types(&self) -> Vec { - self.ignored_fields() - .map(|field| field.data.ty.clone()) - .collect() - } - pub fn where_clause_options(&self) -> WhereClauseOptions { - let bevy_reflect_path = &self.meta().bevy_reflect_path; - WhereClauseOptions { - active_types: self.active_types().into(), - active_trait_bounds: quote! { #bevy_reflect_path::FromReflect }, - ignored_types: self.ignored_types().into(), - ignored_trait_bounds: quote! { #FQAny + #FQSend + #FQSync + #FQDefault }, - ..WhereClauseOptions::type_path_bounds(self.meta()) - } + WhereClauseOptions::new(self.meta(), self.active_fields(), self.ignored_fields()) } } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/documentation.rs b/crates/bevy_reflect/bevy_reflect_derive/src/documentation.rs index f3f8e3cfb9599..a19245d85486e 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/documentation.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/documentation.rs @@ -9,7 +9,7 @@ use syn::{Attribute, Expr, ExprLit, Lit, Meta}; /// /// When converted to a [`TokenStream`], this will output an `Option` /// containing the collection of doc comments. -#[derive(Default)] +#[derive(Default, Clone)] pub(crate) struct Documentation { docs: Vec, } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs b/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs index f4b81f08f5259..e3da50088d26d 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/field_attributes.rs @@ -46,7 +46,7 @@ impl ReflectIgnoreBehavior { } /// A container for attributes defined on a reflected type's field. -#[derive(Default)] +#[derive(Default, Clone)] pub(crate) struct ReflectFieldAttr { /// Determines how this field should be ignored if at all. pub ignore: ReflectIgnoreBehavior, @@ -55,7 +55,7 @@ pub(crate) struct ReflectFieldAttr { } /// Controls how the default value is determined for a field. -#[derive(Default)] +#[derive(Default, Clone)] pub(crate) enum DefaultBehavior { /// Field is required. #[default] diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/from_reflect.rs b/crates/bevy_reflect/bevy_reflect_derive/src/from_reflect.rs index 2473dd356f7a6..00ae55339f805 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/from_reflect.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/from_reflect.rs @@ -5,37 +5,37 @@ use crate::field_attributes::DefaultBehavior; use crate::fq_std::{FQAny, FQClone, FQDefault, FQOption}; use crate::utility::{extend_where_clause, ident_or_index, WhereClauseOptions}; use crate::{ReflectMeta, ReflectStruct}; -use proc_macro::TokenStream; use proc_macro2::Span; use quote::{quote, ToTokens}; use syn::{Field, Ident, Lit, LitInt, LitStr, Member}; /// Implements `FromReflect` for the given struct -pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> TokenStream { +pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> proc_macro2::TokenStream { impl_struct_internal(reflect_struct, false) } /// Implements `FromReflect` for the given tuple struct -pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> TokenStream { +pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> proc_macro2::TokenStream { impl_struct_internal(reflect_struct, true) } -/// Implements `FromReflect` for the given value type -pub(crate) fn impl_value(meta: &ReflectMeta) -> TokenStream { +pub(crate) fn impl_value(meta: &ReflectMeta) -> proc_macro2::TokenStream { let type_path = meta.type_path(); let bevy_reflect_path = meta.bevy_reflect_path(); let (impl_generics, ty_generics, where_clause) = type_path.generics().split_for_impl(); - TokenStream::from(quote! { - impl #impl_generics #bevy_reflect_path::FromReflect for #type_path #ty_generics #where_clause { + let where_from_reflect_clause = + extend_where_clause(where_clause, &WhereClauseOptions::new_value(meta)); + quote! { + impl #impl_generics #bevy_reflect_path::FromReflect for #type_path #ty_generics #where_from_reflect_clause { fn from_reflect(reflect: &dyn #bevy_reflect_path::Reflect) -> #FQOption { #FQOption::Some(#FQClone::clone(::downcast_ref::<#type_path #ty_generics>(::as_any(reflect))?)) } } - }) + } } /// Implements `FromReflect` for the given enum type -pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> TokenStream { +pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> proc_macro2::TokenStream { let fqoption = FQOption.into_token_stream(); let enum_path = reflect_enum.meta().type_path(); @@ -52,16 +52,22 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> TokenStream { // Add FromReflect bound for each active field let where_from_reflect_clause = extend_where_clause( where_clause, - &WhereClauseOptions { - active_types: reflect_enum.active_types().into_boxed_slice(), - ignored_types: reflect_enum.ignored_types().into_boxed_slice(), - active_trait_bounds: quote!(#bevy_reflect_path::FromReflect), - ignored_trait_bounds: quote!(#FQDefault), - ..WhereClauseOptions::type_path_bounds(reflect_enum.meta()) - }, + &WhereClauseOptions::new_with_bounds( + reflect_enum.meta(), + reflect_enum.active_fields(), + reflect_enum.ignored_fields(), + |field| match &field.attrs.default { + DefaultBehavior::Default => Some(quote!(#FQDefault)), + _ => None, + }, + |field| match &field.attrs.default { + DefaultBehavior::Func(_) => None, + _ => Some(quote!(#FQDefault)), + }, + ), ); - TokenStream::from(quote! { + quote! { impl #impl_generics #bevy_reflect_path::FromReflect for #enum_path #ty_generics #where_from_reflect_clause { fn from_reflect(#ref_value: &dyn #bevy_reflect_path::Reflect) -> #FQOption { if let #bevy_reflect_path::ReflectRef::Enum(#ref_value) = #bevy_reflect_path::Reflect::reflect_ref(#ref_value) { @@ -74,7 +80,7 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> TokenStream { } } } - }) + } } /// Container for a struct's members (field name or index) and their @@ -87,7 +93,10 @@ impl MemberValuePair { } } -fn impl_struct_internal(reflect_struct: &ReflectStruct, is_tuple: bool) -> TokenStream { +fn impl_struct_internal( + reflect_struct: &ReflectStruct, + is_tuple: bool, +) -> proc_macro2::TokenStream { let fqoption = FQOption.into_token_stream(); let struct_path = reflect_struct.meta().type_path(); @@ -137,22 +146,29 @@ fn impl_struct_internal(reflect_struct: &ReflectStruct, is_tuple: bool) -> Token // Add FromReflect bound for each active field let where_from_reflect_clause = extend_where_clause( where_clause, - &WhereClauseOptions { - active_types: reflect_struct.active_types().into_boxed_slice(), - ignored_types: reflect_struct.ignored_types().into_boxed_slice(), - active_trait_bounds: quote!(#bevy_reflect_path::FromReflect), - ignored_trait_bounds: if is_defaultable { - quote!() - } else { - quote!(#FQDefault) + &WhereClauseOptions::new_with_bounds( + reflect_struct.meta(), + reflect_struct.active_fields(), + reflect_struct.ignored_fields(), + |field| match &field.attrs.default { + DefaultBehavior::Default => Some(quote!(#FQDefault)), + _ => None, }, - ..WhereClauseOptions::type_path_bounds(reflect_struct.meta()) - }, + |field| { + if is_defaultable { + None + } else { + match &field.attrs.default { + DefaultBehavior::Func(_) => None, + _ => Some(quote!(#FQDefault)), + } + } + }, + ), ); - TokenStream::from(quote! { - impl #impl_generics #bevy_reflect_path::FromReflect for #struct_path #ty_generics #where_from_reflect_clause - { + quote! { + impl #impl_generics #bevy_reflect_path::FromReflect for #struct_path #ty_generics #where_from_reflect_clause { fn from_reflect(reflect: &dyn #bevy_reflect_path::Reflect) -> #FQOption { if let #bevy_reflect_path::ReflectRef::#ref_struct_type(#ref_struct) = #bevy_reflect_path::Reflect::reflect_ref(reflect) { #constructor @@ -161,7 +177,7 @@ fn impl_struct_internal(reflect_struct: &ReflectStruct, is_tuple: bool) -> Token } } } - }) + } } /// Get the collection of ignored field definitions diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs index 1a41f8e11530a..41a47c2552c15 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs @@ -3,12 +3,11 @@ use crate::enum_utility::{get_variant_constructors, EnumVariantConstructors}; use crate::fq_std::{FQAny, FQBox, FQOption, FQResult}; use crate::impls::{impl_type_path, impl_typed}; use crate::utility::extend_where_clause; -use proc_macro::TokenStream; use proc_macro2::{Ident, Span}; use quote::quote; use syn::Fields; -pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> TokenStream { +pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> proc_macro2::TokenStream { let bevy_reflect_path = reflect_enum.meta().bevy_reflect_path(); let enum_path = reflect_enum.meta().type_path(); @@ -97,7 +96,7 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> TokenStream { let where_reflect_clause = extend_where_clause(where_clause, &where_clause_options); - TokenStream::from(quote! { + quote! { #get_type_registration_impl #typed_impl @@ -291,7 +290,7 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> TokenStream { #debug_fn } - }) + } } struct EnumImpls { diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs index 17180c16b15f8..40ca5e3bd503b 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs @@ -2,11 +2,10 @@ use crate::fq_std::{FQAny, FQBox, FQDefault, FQOption, FQResult}; use crate::impls::{impl_type_path, impl_typed}; use crate::utility::{extend_where_clause, ident_or_index}; use crate::ReflectStruct; -use proc_macro::TokenStream; use quote::{quote, ToTokens}; /// Implements `Struct`, `GetTypeRegistration`, and `Reflect` for the given derive data. -pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> TokenStream { +pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> proc_macro2::TokenStream { let fqoption = FQOption.into_token_stream(); let bevy_reflect_path = reflect_struct.meta().bevy_reflect_path(); @@ -104,7 +103,7 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> TokenStream { let where_reflect_clause = extend_where_clause(where_clause, &where_clause_options); - TokenStream::from(quote! { + quote! { #get_type_registration_impl #typed_impl @@ -245,5 +244,5 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> TokenStream { #debug_fn } - }) + } } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs index 0a5cbd8343d13..37984fc1f08d7 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs @@ -2,12 +2,11 @@ use crate::fq_std::{FQAny, FQBox, FQDefault, FQOption, FQResult}; use crate::impls::{impl_type_path, impl_typed}; use crate::utility::extend_where_clause; use crate::ReflectStruct; -use proc_macro::TokenStream; use quote::{quote, ToTokens}; use syn::{Index, Member}; /// Implements `TupleStruct`, `GetTypeRegistration`, and `Reflect` for the given derive data. -pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> TokenStream { +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(); @@ -95,7 +94,7 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> TokenStream { let where_reflect_clause = extend_where_clause(where_clause, &where_clause_options); - TokenStream::from(quote! { + quote! { #get_type_registration_impl #typed_impl @@ -214,5 +213,5 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> TokenStream { #debug_fn } - }) + } } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs index 5fc4fa8deedc9..e92383a746343 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs @@ -2,11 +2,10 @@ use crate::fq_std::{FQAny, FQBox, FQClone, FQOption, FQResult}; use crate::impls::{impl_type_path, impl_typed}; use crate::utility::{extend_where_clause, WhereClauseOptions}; use crate::ReflectMeta; -use proc_macro::TokenStream; use quote::quote; /// Implements `GetTypeRegistration` and `Reflect` for the given type data. -pub(crate) fn impl_value(meta: &ReflectMeta) -> TokenStream { +pub(crate) fn impl_value(meta: &ReflectMeta) -> proc_macro2::TokenStream { let bevy_reflect_path = meta.bevy_reflect_path(); let type_path = meta.type_path(); @@ -22,7 +21,7 @@ pub(crate) fn impl_value(meta: &ReflectMeta) -> TokenStream { #[cfg(not(feature = "documentation"))] let with_docs: Option = None; - let where_clause_options = WhereClauseOptions::type_path_bounds(meta); + let where_clause_options = WhereClauseOptions::new_value(meta); let typed_impl = impl_typed( meta, &where_clause_options, @@ -38,7 +37,7 @@ pub(crate) fn impl_value(meta: &ReflectMeta) -> TokenStream { let where_reflect_clause = extend_where_clause(where_clause, &where_clause_options); let get_type_registration_impl = meta.get_type_registration(&where_clause_options); - TokenStream::from(quote! { + quote! { #get_type_registration_impl #type_path_impl @@ -125,5 +124,5 @@ pub(crate) fn impl_value(meta: &ReflectMeta) -> TokenStream { #debug_fn } - }) + } } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs index 0956fe785ecaf..2061782115988 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs @@ -51,9 +51,11 @@ pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name"; /// 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). -/// It will automatically generate the implementations for `Reflect`, `Typed`, and `GetTypeRegistration`. +/// It will automatically generate implementations for `Reflect`, `Typed`, `GetTypeRegistration`, and `FromReflect`. /// And, depending on the item's structure, will either implement `Struct`, `TupleStruct`, or `Enum`. /// +/// See the [`FromReflect`] derive macro for more information on how to customize the `FromReflect` implementation. +/// /// # Container Attributes /// /// This macro comes with some helper attributes that can be added to the container item @@ -73,6 +75,14 @@ pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name"; /// This is often used with traits that have been marked by the [`#[reflect_trait]`](macro@reflect_trait) /// macro in order to register the type's implementation of that trait. /// +/// ### Default Registrations +/// +/// The following types are automatically registered when deriving `Reflect`: +/// +/// * `ReflectFromReflect` (unless opting out of `FromReflect`) +/// * `SerializationData` +/// * `ReflectFromPtr` +/// /// ### Special Identifiers /// /// There are a few "special" identifiers that work a bit differently: @@ -109,6 +119,15 @@ pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name"; /// If planning to serialize this type using the reflection serializers, /// then the `Serialize` and `Deserialize` traits will need to be implemented and registered as well. /// +/// ## `#[reflect(from_reflect = false)]` +/// +/// This attribute will opt-out of the default `FromReflect` implementation. +/// +/// This is useful for when a type can't or shouldn't implement `FromReflect`, +/// or if a manual implementation is desired. +/// +/// Note that in the latter case, `ReflectFromReflect` will no longer be automatically registered. +/// /// # Field Attributes /// /// Along with the container attributes, this macro comes with some attributes that may be applied @@ -137,19 +156,50 @@ pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "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) { + let derive_data = match ReflectDerive::from_input(&ast, false) { Ok(data) => data, Err(err) => return err.into_compile_error().into(), }; - match derive_data { - ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => { - impls::impl_struct(&struct_data) - } - ReflectDerive::TupleStruct(struct_data) => impls::impl_tuple_struct(&struct_data), - ReflectDerive::Enum(meta) => impls::impl_enum(&meta), - ReflectDerive::Value(meta) => impls::impl_value(&meta), - } + 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! { + #reflect_impls + #from_reflect_impl + }) } /// Derives the `FromReflect` trait. @@ -182,7 +232,7 @@ 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) { + let derive_data = match ReflectDerive::from_input(&ast, true) { Ok(data) => data, Err(err) => return err.into_compile_error().into(), }; @@ -195,6 +245,7 @@ pub fn derive_from_reflect(input: TokenStream) -> TokenStream { ReflectDerive::Enum(meta) => from_reflect::impl_enum(&meta), ReflectDerive::Value(meta) => from_reflect::impl_value(&meta), } + .into() } /// Derives the `TypePath` trait, providing a stable alternative to [`std::any::type_name`]. @@ -215,14 +266,15 @@ 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) { + let derive_data = match ReflectDerive::from_input(&ast, false) { Ok(data) => data, Err(err) => return err.into_compile_error().into(), }; impls::impl_type_path( derive_data.meta(), - &WhereClauseOptions::type_path_bounds(derive_data.meta()), + // Use `WhereClauseOptions::new_value` here so we don't enforce reflection bounds + &WhereClauseOptions::new_value(derive_data.meta()), ) .into() } @@ -338,7 +390,13 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream { #[cfg(feature = "documentation")] let meta = meta.with_docs(documentation::Documentation::from_attributes(&def.attrs)); - impls::impl_value(&meta) + let reflect_impls = impls::impl_value(&meta); + let from_reflect_impl = from_reflect::impl_value(&meta); + + TokenStream::from(quote! { + #reflect_impls + #from_reflect_impl + }) } /// A replacement for `#[derive(Reflect)]` to be used with foreign types which @@ -376,7 +434,7 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream { #[proc_macro] pub fn impl_reflect_struct(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); - let derive_data = match ReflectDerive::from_input(&ast) { + let derive_data = match ReflectDerive::from_input(&ast, false) { Ok(data) => data, Err(err) => return err.into_compile_error().into(), }; @@ -392,13 +450,11 @@ pub fn impl_reflect_struct(input: TokenStream) -> TokenStream { .into(); } - let impl_struct: proc_macro2::TokenStream = impls::impl_struct(&struct_data).into(); - let impl_from_struct: proc_macro2::TokenStream = - from_reflect::impl_struct(&struct_data).into(); + let impl_struct = impls::impl_struct(&struct_data); + let impl_from_struct = from_reflect::impl_struct(&struct_data); TokenStream::from(quote! { #impl_struct - #impl_from_struct }) } @@ -428,6 +484,10 @@ pub fn impl_reflect_struct(input: TokenStream) -> TokenStream { /// The only reason this macro exists is so that `bevy_reflect` can easily implement `FromReflect` on /// primitives and other Rust types internally. /// +/// Please note that this macro will not work with any type that [derives `Reflect`] normally +/// or makes use of the [`impl_reflect_value!`] macro, as those macros also implement `FromReflect` +/// by default. +/// /// # Examples /// /// ```ignore @@ -454,7 +514,7 @@ pub fn impl_from_reflect_value(input: TokenStream) -> TokenStream { } }; - from_reflect::impl_value(&ReflectMeta::new(type_path, def.traits.unwrap_or_default())) + from_reflect::impl_value(&ReflectMeta::new(type_path, def.traits.unwrap_or_default())).into() } /// A replacement for [deriving `TypePath`] for use on foreign types. @@ -516,7 +576,7 @@ pub fn impl_type_path(input: TokenStream) -> TokenStream { let meta = ReflectMeta::new(type_path, ReflectTraits::default()); - impls::impl_type_path(&meta, &WhereClauseOptions::type_path_bounds(&meta)).into() + impls::impl_type_path(&meta, &WhereClauseOptions::new_value(&meta)).into() } /// Derives `TypeUuid` for the given type. This is used internally to implement `TypeUuid` on foreign types, such as those in the std. This macro should be used in the format of `<[Generic Params]> [Type (Path)], [Uuid (String Literal)]`. diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/registration.rs b/crates/bevy_reflect/bevy_reflect_derive/src/registration.rs index 09bc88518dae0..0b0a31e0a38fd 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/registration.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/registration.rs @@ -1,11 +1,10 @@ //! Contains code related specifically to Bevy's type registration. +use crate::derive_data::ReflectMeta; use crate::utility::{extend_where_clause, WhereClauseOptions}; use bit_set::BitSet; use quote::quote; -use crate::derive_data::ReflectMeta; - /// Creates the `GetTypeRegistration` impl for the given type data. #[allow(clippy::too_many_arguments)] pub(crate) fn impl_get_type_registration( @@ -17,6 +16,16 @@ pub(crate) fn impl_get_type_registration( let bevy_reflect_path = meta.bevy_reflect_path(); let registration_data = meta.traits().idents(); let (impl_generics, ty_generics, where_clause) = type_path.generics().split_for_impl(); + let where_reflect_clause = extend_where_clause(where_clause, where_clause_options); + + let from_reflect_data = if meta.from_reflect().should_auto_derive() { + Some(quote! { + registration.insert::<#bevy_reflect_path::ReflectFromReflect>(#bevy_reflect_path::FromType::::from_type()); + }) + } else { + None + }; + let serialization_data = serialization_denylist.map(|denylist| { let denylist = denylist.into_iter(); quote! { @@ -25,14 +34,13 @@ pub(crate) fn impl_get_type_registration( } }); - let where_reflect_clause = extend_where_clause(where_clause, where_clause_options); - quote! { #[allow(unused_mut)] impl #impl_generics #bevy_reflect_path::GetTypeRegistration for #type_path #ty_generics #where_reflect_clause { fn get_type_registration() -> #bevy_reflect_path::TypeRegistration { let mut registration = #bevy_reflect_path::TypeRegistration::of::(); registration.insert::<#bevy_reflect_path::ReflectFromPtr>(#bevy_reflect_path::FromType::::from_type()); + #from_reflect_data #serialization_data #(registration.insert::<#registration_data>(#bevy_reflect_path::FromType::::from_type());)* registration diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/utility.rs b/crates/bevy_reflect/bevy_reflect_derive/src/utility.rs index 32549bd4af8e3..0e43b9b4e6cde 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/utility.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/utility.rs @@ -1,6 +1,8 @@ //! General-purpose utility functions for internal usage within this crate. -use crate::{derive_data::ReflectMeta, field_attributes::ReflectIgnoreBehavior, fq_std::FQOption}; +use crate::derive_data::{ReflectMeta, StructField}; +use crate::field_attributes::ReflectIgnoreBehavior; +use crate::fq_std::{FQAny, FQOption, FQSend, FQSync}; use bevy_macro_utils::BevyManifest; use bit_set::BitSet; use proc_macro2::{Ident, Span}; @@ -61,34 +63,17 @@ pub(crate) fn ident_or_index(ident: Option<&Ident>, index: usize) -> Member { /// Options defining how to extend the `where` clause in reflection with any additional bounds needed. pub(crate) struct WhereClauseOptions { /// Type parameters that need extra trait bounds. - pub(crate) parameter_types: Box<[Ident]>, + parameter_types: Box<[Ident]>, /// Trait bounds to add to the type parameters. - pub(crate) parameter_trait_bounds: proc_macro2::TokenStream, + parameter_trait_bounds: Box<[proc_macro2::TokenStream]>, /// Any types that will be reflected and need an extra trait bound - pub(crate) active_types: Box<[Type]>, + active_types: Box<[Type]>, /// Trait bounds to add to the active types - pub(crate) active_trait_bounds: proc_macro2::TokenStream, + active_trait_bounds: Box<[proc_macro2::TokenStream]>, /// Any types that won't be reflected and need an extra trait bound - pub(crate) ignored_types: Box<[Type]>, + ignored_types: Box<[Type]>, /// Trait bounds to add to the ignored types - pub(crate) ignored_trait_bounds: proc_macro2::TokenStream, -} - -impl WhereClauseOptions { - /// Extends a where clause, adding a `TypePath` bound to each type parameter. - pub fn type_path_bounds(meta: &ReflectMeta) -> Self { - let bevy_reflect_path = meta.bevy_reflect_path(); - Self { - parameter_types: meta - .type_path() - .generics() - .type_params() - .map(|ty| ty.ident.clone()) - .collect(), - parameter_trait_bounds: quote! { #bevy_reflect_path::TypePath }, - ..Default::default() - } - } + ignored_trait_bounds: Box<[proc_macro2::TokenStream]>, } impl Default for WhereClauseOptions { @@ -98,9 +83,93 @@ impl Default for WhereClauseOptions { parameter_types: Box::new([]), active_types: Box::new([]), ignored_types: Box::new([]), - parameter_trait_bounds: quote! {}, - active_trait_bounds: quote! {}, - ignored_trait_bounds: quote! {}, + active_trait_bounds: Box::new([]), + ignored_trait_bounds: Box::new([]), + parameter_trait_bounds: Box::new([]), + } + } +} + +impl WhereClauseOptions { + /// Create [`WhereClauseOptions`] for a struct or enum type. + pub fn new<'a: 'b, 'b>( + meta: &ReflectMeta, + active_fields: impl Iterator>, + ignored_fields: impl Iterator>, + ) -> Self { + Self::new_with_bounds(meta, active_fields, ignored_fields, |_| None, |_| None) + } + + /// Create [`WhereClauseOptions`] for a simple value type. + pub fn new_value(meta: &ReflectMeta) -> Self { + Self::new_with_bounds( + meta, + std::iter::empty(), + std::iter::empty(), + |_| None, + |_| None, + ) + } + + /// Create [`WhereClauseOptions`] for a struct or enum type. + /// + /// Compared to [`WhereClauseOptions::new`], this version allows you to specify + /// custom trait bounds for each field. + pub fn new_with_bounds<'a: 'b, 'b>( + meta: &ReflectMeta, + active_fields: impl Iterator>, + ignored_fields: impl Iterator>, + active_bounds: impl Fn(&StructField<'a>) -> Option, + ignored_bounds: impl Fn(&StructField<'a>) -> Option, + ) -> Self { + let bevy_reflect_path = meta.bevy_reflect_path(); + let is_from_reflect = meta.from_reflect().should_auto_derive(); + + let (active_types, active_trait_bounds): (Vec<_>, Vec<_>) = active_fields + .map(|field| { + let ty = field.data.ty.clone(); + + let custom_bounds = active_bounds(field).map(|bounds| quote!(+ #bounds)); + + let bounds = if is_from_reflect { + quote!(#bevy_reflect_path::FromReflect #custom_bounds) + } else { + quote!(#bevy_reflect_path::Reflect #custom_bounds) + }; + + (ty, bounds) + }) + .unzip(); + + let (ignored_types, ignored_trait_bounds): (Vec<_>, Vec<_>) = ignored_fields + .map(|field| { + let ty = field.data.ty.clone(); + + let custom_bounds = ignored_bounds(field).map(|bounds| quote!(+ #bounds)); + let bounds = quote!(#FQAny + #FQSend + #FQSync #custom_bounds); + + (ty, bounds) + }) + .unzip(); + + let (parameter_types, parameter_trait_bounds): (Vec<_>, Vec<_>) = meta + .type_path() + .generics() + .type_params() + .map(|param| { + let ident = param.ident.clone(); + let bounds = quote!(#bevy_reflect_path::TypePath); + (ident, bounds) + }) + .unzip(); + + Self { + active_types: active_types.into_boxed_slice(), + active_trait_bounds: active_trait_bounds.into_boxed_slice(), + ignored_types: ignored_types.into_boxed_slice(), + ignored_trait_bounds: ignored_trait_bounds.into_boxed_slice(), + parameter_types: parameter_types.into_boxed_slice(), + parameter_trait_bounds: parameter_trait_bounds.into_boxed_slice(), } } } diff --git a/crates/bevy_reflect/src/enums/mod.rs b/crates/bevy_reflect/src/enums/mod.rs index 7693bf9794acc..a7f62de51807b 100644 --- a/crates/bevy_reflect/src/enums/mod.rs +++ b/crates/bevy_reflect/src/enums/mod.rs @@ -363,7 +363,7 @@ mod tests { C { value: TestStruct }, } - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] struct TestStruct(usize); let mut value = TestEnum::A; @@ -397,7 +397,7 @@ mod tests { C { value: OtherEnum }, } - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] enum OtherEnum { A, B(usize), diff --git a/crates/bevy_reflect/src/from_reflect.rs b/crates/bevy_reflect/src/from_reflect.rs index f4abb65d7e0f6..ba13fbf13bf1d 100644 --- a/crates/bevy_reflect/src/from_reflect.rs +++ b/crates/bevy_reflect/src/from_reflect.rs @@ -56,7 +56,7 @@ pub trait FromReflect: Reflect + Sized { /// /// ``` /// # use bevy_reflect::{DynamicTupleStruct, FromReflect, Reflect}; -/// #[derive(Reflect, FromReflect, PartialEq, Eq, Debug)] +/// #[derive(Reflect, PartialEq, Eq, Debug)] /// struct Foo(#[reflect(default = "default_value")] usize); /// /// fn default_value() -> usize { 123 } @@ -75,9 +75,8 @@ pub trait FromReflect: Reflect + Sized { /// # Example /// /// ``` -/// # use bevy_reflect::{DynamicTupleStruct, FromReflect, Reflect, ReflectFromReflect, Typed, TypeRegistry}; -/// # #[derive(Reflect, FromReflect, PartialEq, Eq, Debug)] -/// # #[reflect(FromReflect)] +/// # use bevy_reflect::{DynamicTupleStruct, Reflect, ReflectFromReflect, Typed, TypeRegistry}; +/// # #[derive(Reflect, PartialEq, Eq, Debug)] /// # struct Foo(#[reflect(default = "default_value")] usize); /// # fn default_value() -> usize { 123 } /// # let mut registry = TypeRegistry::new(); diff --git a/crates/bevy_reflect/src/impls/glam.rs b/crates/bevy_reflect/src/impls/glam.rs index 4a3f50cc62b6f..e5f481e71c537 100644 --- a/crates/bevy_reflect/src/impls/glam.rs +++ b/crates/bevy_reflect/src/impls/glam.rs @@ -1,7 +1,7 @@ use crate as bevy_reflect; use crate::prelude::ReflectDefault; use crate::{ReflectDeserialize, ReflectSerialize}; -use bevy_reflect_derive::{impl_from_reflect_value, impl_reflect_struct, impl_reflect_value}; +use bevy_reflect_derive::{impl_reflect_struct, impl_reflect_value}; use glam::*; impl_reflect_struct!( @@ -270,9 +270,6 @@ impl_reflect_value!(::glam::DQuat( Default )); -impl_from_reflect_value!(Quat); -impl_from_reflect_value!(DQuat); - impl_reflect_value!(::glam::EulerRot(Debug, Default)); impl_reflect_value!(::glam::BVec3A(Debug, Default)); impl_reflect_value!(::glam::BVec4A(Debug, Default)); diff --git a/crates/bevy_reflect/src/impls/smol_str.rs b/crates/bevy_reflect/src/impls/smol_str.rs index 3dd617a06c711..0375c1544f238 100644 --- a/crates/bevy_reflect/src/impls/smol_str.rs +++ b/crates/bevy_reflect/src/impls/smol_str.rs @@ -1,9 +1,8 @@ use crate::std_traits::ReflectDefault; use crate::{self as bevy_reflect}; -use bevy_reflect_derive::{impl_from_reflect_value, impl_reflect_value}; +use bevy_reflect_derive::impl_reflect_value; impl_reflect_value!(::smol_str::SmolStr(Debug, Hash, PartialEq, Default)); -impl_from_reflect_value!(::smol_str::SmolStr); #[cfg(test)] mod tests { diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index b3a1c1d43ad2b..ab8b482c18df0 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -11,22 +11,14 @@ use crate::{ use crate::utility::{ reflect_hasher, GenericTypeInfoCell, GenericTypePathCell, NonGenericTypeInfoCell, }; -use bevy_reflect_derive::{impl_from_reflect_value, impl_reflect_value}; -use bevy_utils::HashSet; -use bevy_utils::{Duration, Instant}; +use bevy_reflect_derive::impl_reflect_value; use std::fmt; use std::{ any::Any, borrow::Cow, collections::VecDeque, - ffi::OsString, hash::{BuildHasher, Hash, Hasher}, - num::{ - NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128, - NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, - }, - ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive}, - path::{Path, PathBuf}, + path::Path, }; impl_reflect_value!(bool( @@ -221,47 +213,6 @@ impl_reflect_value!(::std::ffi::OsString( #[cfg(not(any(unix, windows)))] impl_reflect_value!(::std::ffi::OsString(Debug, Hash, PartialEq)); -impl_from_reflect_value!(bool); -impl_from_reflect_value!(char); -impl_from_reflect_value!(u8); -impl_from_reflect_value!(u16); -impl_from_reflect_value!(u32); -impl_from_reflect_value!(u64); -impl_from_reflect_value!(u128); -impl_from_reflect_value!(usize); -impl_from_reflect_value!(i8); -impl_from_reflect_value!(i16); -impl_from_reflect_value!(i32); -impl_from_reflect_value!(i64); -impl_from_reflect_value!(i128); -impl_from_reflect_value!(isize); -impl_from_reflect_value!(f32); -impl_from_reflect_value!(f64); -impl_from_reflect_value!(String); -impl_from_reflect_value!(PathBuf); -impl_from_reflect_value!(OsString); -impl_from_reflect_value!(HashSet); -impl_from_reflect_value!(Range); -impl_from_reflect_value!(RangeInclusive); -impl_from_reflect_value!(RangeFrom); -impl_from_reflect_value!(RangeTo); -impl_from_reflect_value!(RangeToInclusive); -impl_from_reflect_value!(RangeFull); -impl_from_reflect_value!(Duration); -impl_from_reflect_value!(Instant); -impl_from_reflect_value!(NonZeroI128); -impl_from_reflect_value!(NonZeroU128); -impl_from_reflect_value!(NonZeroIsize); -impl_from_reflect_value!(NonZeroUsize); -impl_from_reflect_value!(NonZeroI64); -impl_from_reflect_value!(NonZeroU64); -impl_from_reflect_value!(NonZeroU32); -impl_from_reflect_value!(NonZeroI32); -impl_from_reflect_value!(NonZeroI16); -impl_from_reflect_value!(NonZeroU16); -impl_from_reflect_value!(NonZeroU8); -impl_from_reflect_value!(NonZeroI8); - macro_rules! impl_reflect_for_veclike { ($ty:path, $insert:expr, $remove:expr, $push:expr, $pop:expr, $sub:ty) => { impl List for $ty { @@ -1737,7 +1688,7 @@ mod tests { #[test] fn option_should_from_reflect() { - #[derive(Reflect, FromReflect, PartialEq, Debug)] + #[derive(Reflect, PartialEq, Debug)] struct Foo(usize); let expected = Some(Foo(123)); @@ -1748,7 +1699,7 @@ mod tests { #[test] fn option_should_apply() { - #[derive(Reflect, FromReflect, PartialEq, Debug)] + #[derive(Reflect, PartialEq, Debug)] struct Foo(usize); // === None on None === // diff --git a/crates/bevy_reflect/src/impls/uuid.rs b/crates/bevy_reflect/src/impls/uuid.rs index 4bd1df67e12d6..27a1af41a4fc3 100644 --- a/crates/bevy_reflect/src/impls/uuid.rs +++ b/crates/bevy_reflect/src/impls/uuid.rs @@ -1,8 +1,7 @@ use crate as bevy_reflect; use crate::{std_traits::ReflectDefault, ReflectDeserialize, ReflectSerialize}; -use bevy_reflect_derive::{impl_from_reflect_value, impl_reflect_value}; -use bevy_utils::Uuid; +use bevy_reflect_derive::impl_reflect_value; impl_reflect_value!(::bevy_utils::Uuid( Serialize, @@ -12,4 +11,3 @@ impl_reflect_value!(::bevy_utils::Uuid( PartialEq, Hash )); -impl_from_reflect_value!(Uuid); diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index d0045416fa45f..9a70da803f215 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -197,16 +197,17 @@ //! To resolve this issue, we'll need to convert the dynamic type to the concrete one. //! This is where [`FromReflect`] comes in. //! -//! `FromReflect` is a derivable trait that allows an instance of a type to be generated from a +//! `FromReflect` is a trait that allows an instance of a type to be generated from a //! dynamic representation— even partial ones. //! And since the [`FromReflect::from_reflect`] method takes the data by reference, //! this can be used to effectively clone data (to an extent). //! -//! This trait can be derived on any type whose fields and sub-elements also implement `FromReflect`. +//! It is automatically implemented when [deriving `Reflect`] on a type unless opted out of +//! using `#[reflect(from_reflect = false)]` on the item. //! //! ``` //! # use bevy_reflect::{Reflect, FromReflect}; -//! #[derive(Reflect, FromReflect)] +//! #[derive(Reflect)] //! struct MyStruct { //! foo: i32 //! } @@ -218,8 +219,12 @@ //! let value = ::from_reflect(&*cloned).unwrap(); // OK! //! ``` //! -//! With the derive macro, fields can be ignored or given default values for when a field is missing -//! in the passed value. +//! When deriving, all active fields and sub-elements must also implement `FromReflect`. +//! +//! Fields can be given default values for when a field is missing in the passed value or even ignored. +//! Ignored fields must either implement [`Default`] or have a default function specified +//! using `#[reflect(default = "path::to::function")]`. +//! //! See the [derive macro documentation](derive@crate::FromReflect) for details. //! //! All primitives and simple types implement `FromReflect` by relying on their [`Default`] implementation. @@ -324,7 +329,7 @@ //! # serde::{ReflectSerializer, UntypedReflectDeserializer}, //! # Reflect, FromReflect, TypeRegistry //! # }; -//! #[derive(Reflect, FromReflect, PartialEq, Debug)] +//! #[derive(Reflect, PartialEq, Debug)] //! struct MyStruct { //! foo: i32 //! } @@ -417,6 +422,7 @@ //! [derive macro]: derive@crate::Reflect //! [`'static` lifetime]: https://doc.rust-lang.org/rust-by-example/scope/lifetime/static_lifetime.html#trait-bound //! [derive macro documentation]: derive@crate::Reflect +//! [deriving `Reflect`]: derive@crate::Reflect //! [type data]: TypeData //! [`ReflectDefault`]: std_traits::ReflectDefault //! [object-safe]: https://doc.rust-lang.org/reference/items/traits.html#object-safety @@ -700,8 +706,7 @@ mod tests { #[test] fn should_call_from_reflect_dynamically() { - #[derive(Reflect, FromReflect)] - #[reflect(FromReflect)] + #[derive(Reflect)] struct MyStruct { foo: usize, } @@ -736,7 +741,7 @@ mod tests { #[test] fn from_reflect_should_use_default_field_attributes() { - #[derive(Reflect, FromReflect, Eq, PartialEq, Debug)] + #[derive(Reflect, Eq, PartialEq, Debug)] struct MyStruct { // Use `Default::default()` // Note that this isn't an ignored field @@ -766,7 +771,7 @@ mod tests { #[test] fn from_reflect_should_use_default_variant_field_attributes() { - #[derive(Reflect, FromReflect, Eq, PartialEq, Debug)] + #[derive(Reflect, Eq, PartialEq, Debug)] enum MyEnum { Foo(#[reflect(default)] String), Bar { @@ -799,7 +804,7 @@ mod tests { #[test] fn from_reflect_should_use_default_container_attribute() { - #[derive(Reflect, FromReflect, Eq, PartialEq, Debug)] + #[derive(Reflect, Eq, PartialEq, Debug)] #[reflect(Default)] struct MyStruct { foo: String, @@ -829,7 +834,7 @@ mod tests { #[test] fn reflect_complex_patch() { - #[derive(Reflect, Eq, PartialEq, Debug, FromReflect)] + #[derive(Reflect, Eq, PartialEq, Debug)] #[reflect(PartialEq)] struct Foo { a: u32, @@ -843,13 +848,13 @@ mod tests { h: [u32; 2], } - #[derive(Reflect, Eq, PartialEq, Clone, Debug, FromReflect)] + #[derive(Reflect, Eq, PartialEq, Clone, Debug)] #[reflect(PartialEq)] struct Bar { x: u32, } - #[derive(Reflect, Eq, PartialEq, Debug, FromReflect)] + #[derive(Reflect, Eq, PartialEq, Debug)] struct Baz(String); let mut hash_map = HashMap::default(); @@ -1280,7 +1285,7 @@ mod tests { // Struct (generic) #[derive(Reflect)] - struct MyGenericStruct { + struct MyGenericStruct { foo: T, bar: usize, } @@ -1474,6 +1479,7 @@ mod tests { #[test] fn should_permit_higher_ranked_lifetimes() { #[derive(Reflect)] + #[reflect(from_reflect = false)] struct TestStruct { #[reflect(ignore)] _hrl: for<'a> fn(&'a str) -> &'a str, diff --git a/crates/bevy_reflect/src/path.rs b/crates/bevy_reflect/src/path.rs index 8876581312447..a9fd7ffe2febe 100644 --- a/crates/bevy_reflect/src/path.rs +++ b/crates/bevy_reflect/src/path.rs @@ -838,7 +838,7 @@ mod tests { bar: C, } - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] struct C { baz: f32, } @@ -849,7 +849,7 @@ mod tests { #[derive(Reflect)] struct E(f32, usize); - #[derive(Reflect, FromReflect, PartialEq, Debug)] + #[derive(Reflect, PartialEq, Debug)] enum F { Unit, Tuple(u32, u32), diff --git a/crates/bevy_reflect/src/serde/de.rs b/crates/bevy_reflect/src/serde/de.rs index 9fe3cd02881ad..49fbbb5fa1bdb 100644 --- a/crates/bevy_reflect/src/serde/de.rs +++ b/crates/bevy_reflect/src/serde/de.rs @@ -1098,7 +1098,7 @@ mod tests { use crate::serde::{TypedReflectDeserializer, UntypedReflectDeserializer}; use crate::{DynamicEnum, FromReflect, Reflect, ReflectDeserialize, TypeRegistry}; - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] struct MyStruct { primitive_value: i8, option_value: Option, @@ -1121,27 +1121,27 @@ mod tests { custom_deserialize: CustomDeserialize, } - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] struct SomeStruct { foo: i64, } - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] struct SomeTupleStruct(String); - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] struct SomeUnitStruct; - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] struct SomeIgnoredStruct { #[reflect(ignore)] ignored: i32, } - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] struct SomeIgnoredTupleStruct(#[reflect(ignore)] i32); - #[derive(Reflect, FromReflect, Debug, PartialEq, Deserialize)] + #[derive(Reflect, Debug, PartialEq, Deserialize)] struct SomeDeserializableStruct { foo: i64, } @@ -1149,7 +1149,7 @@ mod tests { /// Implements a custom deserialize using `#[reflect(Deserialize)]`. /// /// For testing purposes, this is just the auto-generated one from deriving. - #[derive(Reflect, FromReflect, Debug, PartialEq, Deserialize)] + #[derive(Reflect, Debug, PartialEq, Deserialize)] #[reflect(Deserialize)] struct CustomDeserialize { value: usize, @@ -1157,7 +1157,7 @@ mod tests { inner_struct: SomeDeserializableStruct, } - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] enum SomeEnum { Unit, NewType(usize), @@ -1165,7 +1165,7 @@ mod tests { Struct { foo: String }, } - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] enum SomeIgnoredEnum { Tuple(#[reflect(ignore)] f32, #[reflect(ignore)] f32), Struct { @@ -1311,7 +1311,7 @@ mod tests { #[test] fn should_deserialized_typed() { - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] struct Foo { bar: i32, } @@ -1337,7 +1337,7 @@ mod tests { #[test] fn should_deserialize_option() { - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] struct OptionTest { none: Option<()>, simple: Option, diff --git a/crates/bevy_reflect/src/serde/ser.rs b/crates/bevy_reflect/src/serde/ser.rs index 38d4529a3a40b..033e1fb105f28 100644 --- a/crates/bevy_reflect/src/serde/ser.rs +++ b/crates/bevy_reflect/src/serde/ser.rs @@ -453,7 +453,7 @@ impl<'a> Serialize for ArraySerializer<'a> { mod tests { use crate as bevy_reflect; use crate::serde::ReflectSerializer; - use crate::{FromReflect, Reflect, ReflectSerialize, TypeRegistry}; + use crate::{Reflect, ReflectSerialize, TypeRegistry}; use bevy_utils::HashMap; use ron::extensions::Extensions; use ron::ser::PrettyConfig; @@ -483,7 +483,7 @@ mod tests { custom_serialize: CustomSerialize, } - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] struct SomeStruct { foo: i64, } @@ -491,16 +491,16 @@ mod tests { #[derive(Reflect, Debug, PartialEq)] struct SomeTupleStruct(String); - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] struct SomeUnitStruct; - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] struct SomeIgnoredStruct { #[reflect(ignore)] ignored: i32, } - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] struct SomeIgnoredTupleStruct(#[reflect(ignore)] i32); #[derive(Reflect, Debug, PartialEq)] @@ -511,7 +511,7 @@ mod tests { Struct { foo: String }, } - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] enum SomeIgnoredEnum { Tuple(#[reflect(ignore)] f32, #[reflect(ignore)] f32), Struct { @@ -644,7 +644,7 @@ mod tests { #[test] fn should_serialize_option() { - #[derive(Reflect, FromReflect, Debug, PartialEq)] + #[derive(Reflect, Debug, PartialEq)] struct OptionTest { none: Option<()>, simple: Option, diff --git a/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/bounds.pass.rs b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/bounds.pass.rs index 2f7b3883b07f2..ea807d05fa673 100644 --- a/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/bounds.pass.rs +++ b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/bounds.pass.rs @@ -17,14 +17,14 @@ mod structs { _ignored: NonReflect, } - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] struct FromReflectGeneric { foo: T, #[reflect(ignore)] _ignored: NonReflect, } - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] #[reflect(Default)] struct DefaultGeneric { foo: Option, @@ -48,14 +48,14 @@ mod structs { _ignored: NonReflect, } - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] struct FromReflectBoundGeneric { foo: T, #[reflect(ignore)] _ignored: NonReflect, } - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] #[reflect(Default)] struct DefaultBoundGeneric { foo: Option, @@ -82,7 +82,7 @@ mod structs { _ignored: NonReflect, } - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] struct FromReflectGenericWithWhere where T: Clone, @@ -92,7 +92,7 @@ mod structs { _ignored: NonReflect, } - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] #[reflect(Default)] struct DefaultGenericWithWhere where @@ -126,7 +126,7 @@ mod structs { _ignored: NonReflect, } - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] #[rustfmt::skip] struct FromReflectGenericWithWhereNoTrailingComma where @@ -137,7 +137,7 @@ mod structs { _ignored: NonReflect, } - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] #[reflect(Default)] #[rustfmt::skip] struct DefaultGenericWithWhereNoTrailingComma @@ -168,10 +168,10 @@ mod tuple_structs { #[derive(Reflect)] struct ReflectGeneric(T, #[reflect(ignore)] NonReflect); - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] struct FromReflectGeneric(T, #[reflect(ignore)] NonReflect); - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] #[reflect(Default)] struct DefaultGeneric(Option, #[reflect(ignore)] NonReflectNonDefault); @@ -184,10 +184,10 @@ mod tuple_structs { #[derive(Reflect)] struct ReflectBoundGeneric(T, #[reflect(ignore)] NonReflect); - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] struct FromReflectBoundGeneric(T, #[reflect(ignore)] NonReflect); - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] #[reflect(Default)] struct DefaultBoundGeneric(Option, #[reflect(ignore)] NonReflectNonDefault); @@ -202,12 +202,12 @@ mod tuple_structs { where T: Clone; - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] struct FromReflectGenericWithWhere(T, #[reflect(ignore)] NonReflect) where T: Clone; - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] #[reflect(Default)] struct DefaultGenericWithWhere(Option, #[reflect(ignore)] NonReflectNonDefault) where @@ -231,7 +231,7 @@ mod enums { Foo(T, #[reflect(ignore)] NonReflect), } - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] enum FromReflectGeneric { Foo(T, #[reflect(ignore)] NonReflect), } @@ -241,7 +241,7 @@ mod enums { Foo(T, #[reflect(ignore)] NonReflect), } - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] enum FromReflectBoundGeneric { Foo(T, #[reflect(ignore)] NonReflect), } @@ -254,7 +254,7 @@ mod enums { Foo(T, #[reflect(ignore)] NonReflect), } - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] enum FromReflectGenericWithWhere where T: Clone, @@ -271,7 +271,7 @@ mod enums { Foo(T, #[reflect(ignore)] NonReflect), } - #[derive(Reflect, FromReflect)] + #[derive(Reflect)] #[rustfmt::skip] enum FromReflectGenericWithWhereNoTrailingComma where diff --git a/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/from_reflect.fail.rs b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/from_reflect.fail.rs new file mode 100644 index 0000000000000..bd75c761d5011 --- /dev/null +++ b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/from_reflect.fail.rs @@ -0,0 +1,25 @@ +use bevy_reflect::{FromReflect, Reflect}; + +// Reason: Cannot have conflicting `from_reflect` attributes +#[derive(Reflect)] +#[reflect(from_reflect = false)] +#[reflect(from_reflect = true)] +struct Foo { + value: String, +} + +// Reason: Cannot have conflicting `from_reflect` attributes +#[derive(Reflect)] +#[reflect(from_reflect = true)] +#[reflect(from_reflect = false)] +struct Bar { + value: String, +} + +// Reason: Conflicting `FromReflect` implementations +#[derive(Reflect, FromReflect)] +struct Baz { + value: String, +} + +fn main() {} diff --git a/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/from_reflect.fail.stderr b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/from_reflect.fail.stderr new file mode 100644 index 0000000000000..ce088970f3991 --- /dev/null +++ b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/from_reflect.fail.stderr @@ -0,0 +1,21 @@ +error: `from_reflect` already set to false + --> tests/reflect_derive/from_reflect.fail.rs:6:26 + | +6 | #[reflect(from_reflect = true)] + | ^^^^ + +error: `from_reflect` already set to true + --> tests/reflect_derive/from_reflect.fail.rs:14:26 + | +14 | #[reflect(from_reflect = false)] + | ^^^^^ + +error[E0119]: conflicting implementations of trait `FromReflect` for type `Baz` + --> tests/reflect_derive/from_reflect.fail.rs:20:19 + | +20 | #[derive(Reflect, FromReflect)] + | ------- ^^^^^^^^^^^ conflicting implementation for `Baz` + | | + | first implementation here + | + = note: this error originates in the derive macro `FromReflect` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/from_reflect.pass.rs b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/from_reflect.pass.rs new file mode 100644 index 0000000000000..4d8343e353bff --- /dev/null +++ b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/from_reflect.pass.rs @@ -0,0 +1,23 @@ +use bevy_reflect::{FromReflect, Reflect}; + +#[derive(Reflect)] +#[reflect(from_reflect = false)] +#[reflect(from_reflect = false)] +struct Foo { + value: String, +} + +#[derive(Reflect)] +#[reflect(from_reflect = true)] +#[reflect(from_reflect = true)] +struct Bar { + value: String, +} + +#[derive(Reflect, FromReflect)] +#[reflect(from_reflect = false)] +struct Baz { + value: String, +} + +fn main() {} diff --git a/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/generics.fail.rs b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/generics.fail.rs index 1ed92883b1033..c3693d06310db 100644 --- a/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/generics.fail.rs +++ b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/generics.fail.rs @@ -1,6 +1,7 @@ use bevy_reflect::{Reflect, TypePath}; #[derive(Reflect)] +#[reflect(from_reflect = false)] struct Foo { a: T, } diff --git a/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/generics.fail.stderr b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/generics.fail.stderr index 043dcc16665da..4e0b99529567d 100644 --- a/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/generics.fail.stderr +++ b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/generics.fail.stderr @@ -1,13 +1,13 @@ error[E0599]: no method named `get_field` found for struct `Box<(dyn Reflect + 'static)>` in the current scope - --> tests/reflect_derive/generics.fail.rs:15:9 + --> tests/reflect_derive/generics.fail.rs:16:9 | -15 | foo.get_field::("a").unwrap(); +16 | foo.get_field::("a").unwrap(); | ^^^^^^^^^ method not found in `Box` error[E0277]: the trait bound `NoReflect: Reflect` is not satisfied - --> tests/reflect_derive/generics.fail.rs:13:37 + --> tests/reflect_derive/generics.fail.rs:14:37 | -13 | let mut foo: Box = Box::new(Foo:: { a: NoReflect(42.0) }); +14 | let mut foo: Box = Box::new(Foo:: { a: NoReflect(42.0) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Reflect` is not implemented for `NoReflect` | = help: the following other types implement trait `Reflect`: @@ -25,7 +25,8 @@ note: required for `Foo` to implement `Reflect` | 3 | #[derive(Reflect)] | ^^^^^^^ unsatisfied trait bound introduced in this `derive` macro -4 | struct Foo { +4 | #[reflect(from_reflect = false)] +5 | struct Foo { | ^^^^^^ = note: required for the cast from `Foo` to the object type `dyn Reflect` = note: this error originates in the derive macro `Reflect` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/generics_structs.pass.rs b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/generics_structs.pass.rs index 505cf6dabd9d5..22902b2ce8c72 100644 --- a/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/generics_structs.pass.rs +++ b/crates/bevy_reflect_compile_fail_tests/tests/reflect_derive/generics_structs.pass.rs @@ -1,6 +1,7 @@ -use bevy_reflect::{Reflect, GetField}; +use bevy_reflect::{GetField, Reflect}; #[derive(Reflect)] +#[reflect(from_reflect = false)] struct Foo { a: T, #[reflect(ignore)] @@ -15,6 +16,17 @@ struct Foo { _e: S, } +// check that we use the proper bounds when auto-deriving `FromReflect` +#[derive(Reflect)] +struct Bar { + a: T, + #[reflect(ignore)] + _b: U, + _c: T, + _d: U, + #[reflect(ignore)] + _e: S, +} fn main() { let foo = Foo:: { @@ -26,4 +38,14 @@ fn main() { }; let _ = *foo.get_field::("a").unwrap(); -} \ No newline at end of file + + let bar = Bar:: { + a: 1, + _b: 2, + _c: 3, + _d: 4, + _e: 5.0, + }; + + let _ = *bar.get_field::("a").unwrap(); +} diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index 0017bec82a82f..9c174169605de 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -21,7 +21,6 @@ use bevy_ecs::{ use bevy_log::warn; use bevy_math::{Mat4, Ray, Rect, UVec2, UVec4, Vec2, Vec3}; use bevy_reflect::prelude::*; -use bevy_reflect::FromReflect; use bevy_transform::components::GlobalTransform; use bevy_utils::{HashMap, HashSet}; use bevy_window::{ @@ -35,7 +34,7 @@ use wgpu::{BlendState, Extent3d, LoadOp, TextureFormat}; /// The viewport defines the area on the render target to which the camera renders its image. /// You can overlay multiple cameras in a single window using viewports to create effects like /// split screen, minimaps, and character viewers. -#[derive(Reflect, FromReflect, Debug, Clone)] +#[derive(Reflect, Debug, Clone)] #[reflect(Default)] pub struct Viewport { /// The physical position to render this viewport to within the [`RenderTarget`] of this [`Camera`]. @@ -86,7 +85,7 @@ pub struct ComputedCameraValues { /// /// Adding a camera is typically done by adding a bundle, either the `Camera2dBundle` or the /// `Camera3dBundle`. -#[derive(Component, Debug, Reflect, FromReflect, Clone)] +#[derive(Component, Debug, Reflect, Clone)] #[reflect(Component)] pub struct Camera { /// If set, this camera will render to the given [`Viewport`] rectangle within the configured [`RenderTarget`]. @@ -377,8 +376,7 @@ impl CameraRenderGraph { /// The "target" that a [`Camera`] will render to. For example, this could be a [`Window`](bevy_window::Window) /// swapchain or an [`Image`]. -#[derive(Debug, Clone, Reflect, FromReflect)] -#[reflect(FromReflect)] +#[derive(Debug, Clone, Reflect)] pub enum RenderTarget { /// Window to which the camera's view is rendered. Window(WindowRef), diff --git a/crates/bevy_render/src/camera/manual_texture_view.rs b/crates/bevy_render/src/camera/manual_texture_view.rs index ca35c14b87842..b843f0ecafd4f 100644 --- a/crates/bevy_render/src/camera/manual_texture_view.rs +++ b/crates/bevy_render/src/camera/manual_texture_view.rs @@ -5,25 +5,11 @@ use bevy_ecs::system::Resource; use bevy_ecs::{prelude::Component, reflect::ReflectComponent}; use bevy_math::UVec2; use bevy_reflect::prelude::*; -use bevy_reflect::FromReflect; use bevy_utils::HashMap; use wgpu::TextureFormat; /// A unique id that corresponds to a specific [`ManualTextureView`] in the [`ManualTextureViews`] collection. -#[derive( - Default, - Debug, - Clone, - Copy, - PartialEq, - Eq, - Hash, - PartialOrd, - Ord, - Component, - Reflect, - FromReflect, -)] +#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Component, Reflect)] #[reflect(Component, Default)] pub struct ManualTextureViewHandle(pub u32); diff --git a/crates/bevy_render/src/camera/projection.rs b/crates/bevy_render/src/camera/projection.rs index e134df9b4257e..73e3d6a431f65 100644 --- a/crates/bevy_render/src/camera/projection.rs +++ b/crates/bevy_render/src/camera/projection.rs @@ -4,8 +4,7 @@ use bevy_app::{App, Plugin, PostStartup, PostUpdate}; use bevy_ecs::{prelude::*, reflect::ReflectComponent}; use bevy_math::{Mat4, Rect, Vec2}; use bevy_reflect::{ - std_traits::ReflectDefault, FromReflect, GetTypeRegistration, Reflect, ReflectDeserialize, - ReflectFromReflect, ReflectSerialize, + std_traits::ReflectDefault, GetTypeRegistration, Reflect, ReflectDeserialize, ReflectSerialize, }; use serde::{Deserialize, Serialize}; @@ -62,8 +61,8 @@ pub trait CameraProjection { } /// A configurable [`CameraProjection`] that can select its projection type at runtime. -#[derive(Component, Debug, Clone, Reflect, FromReflect)] -#[reflect(Component, Default, FromReflect)] +#[derive(Component, Debug, Clone, Reflect)] +#[reflect(Component, Default)] pub enum Projection { Perspective(PerspectiveProjection), Orthographic(OrthographicProjection), @@ -111,7 +110,7 @@ impl Default for Projection { } /// A 3D camera projection in which distant objects appear smaller than close objects. -#[derive(Component, Debug, Clone, Reflect, FromReflect)] +#[derive(Component, Debug, Clone, Reflect)] #[reflect(Component, Default)] pub struct PerspectiveProjection { /// The vertical field of view (FOV) in radians. @@ -167,7 +166,7 @@ impl Default for PerspectiveProjection { } } -#[derive(Debug, Clone, Reflect, FromReflect, Serialize, Deserialize)] +#[derive(Debug, Clone, Reflect, Serialize, Deserialize)] #[reflect(Serialize, Deserialize)] pub enum ScalingMode { /// Manually specify the projection's size, ignoring window resizing. The image will stretch. @@ -198,7 +197,7 @@ pub enum ScalingMode { /// /// Note that the scale of the projection and the apparent size of objects are inversely proportional. /// As the size of the projection increases, the size of objects decreases. -#[derive(Component, Debug, Clone, Reflect, FromReflect)] +#[derive(Component, Debug, Clone, Reflect)] #[reflect(Component, Default)] pub struct OrthographicProjection { /// The distance of the near clipping plane in world units. diff --git a/crates/bevy_render/src/color/mod.rs b/crates/bevy_render/src/color/mod.rs index b5f1fb91988dd..795ba48e3e0fc 100644 --- a/crates/bevy_render/src/color/mod.rs +++ b/crates/bevy_render/src/color/mod.rs @@ -3,12 +3,12 @@ mod colorspace; pub use colorspace::*; use bevy_math::{Vec3, Vec4}; -use bevy_reflect::{FromReflect, Reflect, ReflectDeserialize, ReflectSerialize}; +use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize}; use serde::{Deserialize, Serialize}; use std::ops::{Add, AddAssign, Mul, MulAssign}; use thiserror::Error; -#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect, FromReflect)] +#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)] #[reflect(PartialEq, Serialize, Deserialize)] pub enum Color { /// sRGBA color diff --git a/crates/bevy_render/src/mesh/mesh/skinning.rs b/crates/bevy_render/src/mesh/mesh/skinning.rs index f91cb45f8e30a..20df623c5a899 100644 --- a/crates/bevy_render/src/mesh/mesh/skinning.rs +++ b/crates/bevy_render/src/mesh/mesh/skinning.rs @@ -6,11 +6,11 @@ use bevy_ecs::{ reflect::ReflectMapEntities, }; use bevy_math::Mat4; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect, TypePath, TypeUuid}; +use bevy_reflect::{Reflect, TypePath, TypeUuid}; use std::ops::Deref; -#[derive(Component, Debug, Default, Clone, Reflect, FromReflect)] -#[reflect(Component, MapEntities, FromReflect)] +#[derive(Component, Debug, Default, Clone, Reflect)] +#[reflect(Component, MapEntities)] pub struct SkinnedMesh { pub inverse_bindposes: Handle, pub joints: Vec, diff --git a/crates/bevy_render/src/primitives/mod.rs b/crates/bevy_render/src/primitives/mod.rs index 75fdd88d6d4c0..fc447a90cf8da 100644 --- a/crates/bevy_render/src/primitives/mod.rs +++ b/crates/bevy_render/src/primitives/mod.rs @@ -1,10 +1,10 @@ use bevy_ecs::{component::Component, prelude::Entity, reflect::ReflectComponent}; use bevy_math::{Mat4, Vec3, Vec3A, Vec4, Vec4Swizzles}; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; use bevy_utils::HashMap; /// An axis-aligned bounding box. -#[derive(Component, Clone, Copy, Debug, Default, Reflect, FromReflect)] +#[derive(Component, Clone, Copy, Debug, Default, Reflect)] #[reflect(Component)] pub struct Aabb { pub center: Vec3A, @@ -126,8 +126,8 @@ impl HalfSpace { /// A frustum made up of the 6 defining half spaces. /// Half spaces are ordered left, right, top, bottom, near, far. /// The normal vectors of the half spaces point towards the interior of the frustum. -#[derive(Component, Clone, Copy, Debug, Default, Reflect, FromReflect)] -#[reflect(Component, FromReflect)] +#[derive(Component, Clone, Copy, Debug, Default, Reflect)] +#[reflect(Component)] pub struct Frustum { #[reflect(ignore)] pub half_spaces: [HalfSpace; 6], @@ -223,8 +223,8 @@ impl Frustum { } } -#[derive(Component, Debug, Default, Reflect, FromReflect)] -#[reflect(Component, FromReflect)] +#[derive(Component, Debug, Default, Reflect)] +#[reflect(Component)] pub struct CubemapFrusta { #[reflect(ignore)] pub frusta: [Frustum; 6], @@ -239,8 +239,8 @@ impl CubemapFrusta { } } -#[derive(Component, Debug, Default, Reflect, FromReflect)] -#[reflect(Component, FromReflect)] +#[derive(Component, Debug, Default, Reflect)] +#[reflect(Component)] pub struct CascadesFrusta { #[reflect(ignore)] pub frusta: HashMap>, diff --git a/crates/bevy_render/src/texture/image.rs b/crates/bevy_render/src/texture/image.rs index 03cc6d7402b9e..488f80dfdc4bd 100644 --- a/crates/bevy_render/src/texture/image.rs +++ b/crates/bevy_render/src/texture/image.rs @@ -15,7 +15,7 @@ use bevy_asset::HandleUntyped; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::system::{lifetimeless::SRes, Resource, SystemParamItem}; use bevy_math::Vec2; -use bevy_reflect::{FromReflect, Reflect, TypeUuid}; +use bevy_reflect::{Reflect, TypeUuid}; use std::hash::Hash; use thiserror::Error; @@ -103,7 +103,7 @@ impl ImageFormat { } } -#[derive(Reflect, FromReflect, Debug, Clone, TypeUuid)] +#[derive(Reflect, Debug, Clone, TypeUuid)] #[uuid = "6ea26da6-6cf8-4ea2-9986-1d7bf6c17d6f"] #[reflect_value] pub struct Image { diff --git a/crates/bevy_render/src/view/visibility/mod.rs b/crates/bevy_render/src/view/visibility/mod.rs index 4c72a5abb5f05..5938fe2f95b69 100644 --- a/crates/bevy_render/src/view/visibility/mod.rs +++ b/crates/bevy_render/src/view/visibility/mod.rs @@ -6,7 +6,7 @@ use bevy_app::{Plugin, PostUpdate}; use bevy_asset::{Assets, Handle}; use bevy_ecs::prelude::*; use bevy_hierarchy::{Children, Parent}; -use bevy_reflect::{std_traits::ReflectDefault, FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_transform::{components::GlobalTransform, TransformSystem}; use std::cell::Cell; use thread_local::ThreadLocal; @@ -27,8 +27,8 @@ use crate::{ /// /// This is done by the `visibility_propagate_system` which uses the entity hierarchy and /// `Visibility` to set the values of each entity's [`ComputedVisibility`] component. -#[derive(Component, Clone, Copy, Reflect, FromReflect, Debug, PartialEq, Eq, Default)] -#[reflect(Component, Default, FromReflect)] +#[derive(Component, Clone, Copy, Reflect, Debug, PartialEq, Eq, Default)] +#[reflect(Component, Default)] pub enum Visibility { /// An entity with `Visibility::Inherited` will inherit the Visibility of its [`Parent`]. /// @@ -68,7 +68,6 @@ bitflags::bitflags! { } } bevy_reflect::impl_reflect_value!((in bevy_render::view) ComputedVisibilityFlags); -bevy_reflect::impl_from_reflect_value!(ComputedVisibilityFlags); /// Algorithmically-computed indication of whether an entity is visible and should be extracted for rendering #[derive(Component, Clone, Reflect, Debug, Eq, PartialEq)] @@ -155,8 +154,8 @@ pub struct VisibilityBundle { } /// Use this component to opt-out of built-in frustum culling for Mesh entities -#[derive(Component, Default, Reflect, FromReflect)] -#[reflect(Component, Default, FromReflect)] +#[derive(Component, Default, Reflect)] +#[reflect(Component, Default)] pub struct NoFrustumCulling; /// Collection of entities visible from the current view. @@ -171,8 +170,8 @@ pub struct NoFrustumCulling; /// /// Currently this component is ignored by the sprite renderer, so sprite rendering /// is not optimized per view. -#[derive(Clone, Component, Default, Debug, Reflect, FromReflect)] -#[reflect(Component, FromReflect)] +#[derive(Clone, Component, Default, Debug, Reflect)] +#[reflect(Component)] pub struct VisibleEntities { #[reflect(ignore)] pub entities: Vec, diff --git a/crates/bevy_scene/src/serde.rs b/crates/bevy_scene/src/serde.rs index b686bf9566950..a16a8d8957543 100644 --- a/crates/bevy_scene/src/serde.rs +++ b/crates/bevy_scene/src/serde.rs @@ -429,7 +429,7 @@ mod tests { use bevy_ecs::query::{With, Without}; use bevy_ecs::reflect::{AppTypeRegistry, ReflectMapEntities}; use bevy_ecs::world::FromWorld; - use bevy_reflect::{FromReflect, Reflect, ReflectSerialize}; + use bevy_reflect::{Reflect, ReflectSerialize}; use bincode::Options; use serde::de::DeserializeSeed; use serde::Serialize; @@ -453,7 +453,7 @@ mod tests { baz: MyEnum, } - #[derive(Reflect, FromReflect, Default)] + #[derive(Reflect, Default)] enum MyEnum { #[default] Unit, diff --git a/crates/bevy_sprite/src/mesh2d/color_material.rs b/crates/bevy_sprite/src/mesh2d/color_material.rs index 75ba440beb5a6..6258d437d31b4 100644 --- a/crates/bevy_sprite/src/mesh2d/color_material.rs +++ b/crates/bevy_sprite/src/mesh2d/color_material.rs @@ -39,7 +39,7 @@ impl Plugin for ColorMaterialPlugin { } /// A [2d material](Material2d) that renders [2d meshes](crate::Mesh2dHandle) with a texture tinted by a uniform color -#[derive(AsBindGroup, Reflect, FromReflect, Debug, Clone, TypeUuid)] +#[derive(AsBindGroup, Reflect, Debug, Clone, TypeUuid)] #[reflect(Default, Debug)] #[uuid = "e228a544-e3ca-4e1e-bb9d-4d8bc1ad8c19"] #[uniform(0, ColorMaterialUniform)] diff --git a/crates/bevy_sprite/src/mesh2d/mesh.rs b/crates/bevy_sprite/src/mesh2d/mesh.rs index 137f412c38473..3e6c4ce068bca 100644 --- a/crates/bevy_sprite/src/mesh2d/mesh.rs +++ b/crates/bevy_sprite/src/mesh2d/mesh.rs @@ -7,7 +7,7 @@ use bevy_ecs::{ system::{lifetimeless::*, SystemParamItem, SystemState}, }; use bevy_math::{Mat4, Vec2}; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect, TypeUuid}; +use bevy_reflect::{Reflect, TypeUuid}; use bevy_render::{ extract_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin}, globals::{GlobalsBuffer, GlobalsUniform}, @@ -29,8 +29,8 @@ use bevy_transform::components::GlobalTransform; /// Component for rendering with meshes in the 2d pipeline, usually with a [2d material](crate::Material2d) such as [`ColorMaterial`](crate::ColorMaterial). /// /// It wraps a [`Handle`] to differentiate from the 3d pipelines which use the handles directly as components -#[derive(Default, Clone, Component, Debug, Reflect, FromReflect)] -#[reflect(Component, FromReflect)] +#[derive(Default, Clone, Component, Debug, Reflect)] +#[reflect(Component)] pub struct Mesh2dHandle(pub Handle); impl From> for Mesh2dHandle { diff --git a/crates/bevy_sprite/src/sprite.rs b/crates/bevy_sprite/src/sprite.rs index ad216c58fcb61..cde4983ff73ec 100644 --- a/crates/bevy_sprite/src/sprite.rs +++ b/crates/bevy_sprite/src/sprite.rs @@ -1,9 +1,9 @@ use bevy_ecs::{component::Component, reflect::ReflectComponent}; use bevy_math::{Rect, Vec2}; -use bevy_reflect::{std_traits::ReflectDefault, FromReflect, Reflect}; +use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::color::Color; -#[derive(Component, Debug, Default, Clone, Reflect, FromReflect)] +#[derive(Component, Debug, Default, Clone, Reflect)] #[reflect(Component, Default)] #[repr(C)] pub struct Sprite { @@ -25,7 +25,7 @@ pub struct Sprite { /// How a sprite is positioned relative to its [`Transform`](bevy_transform::components::Transform). /// It defaults to `Anchor::Center`. -#[derive(Component, Debug, Clone, Default, Reflect, FromReflect)] +#[derive(Component, Debug, Clone, Default, Reflect)] #[doc(alias = "pivot")] pub enum Anchor { #[default] diff --git a/crates/bevy_sprite/src/texture_atlas.rs b/crates/bevy_sprite/src/texture_atlas.rs index eaa60cb107554..ddd2bab648385 100644 --- a/crates/bevy_sprite/src/texture_atlas.rs +++ b/crates/bevy_sprite/src/texture_atlas.rs @@ -2,14 +2,14 @@ use crate::Anchor; use bevy_asset::Handle; use bevy_ecs::{component::Component, reflect::ReflectComponent}; use bevy_math::{Rect, Vec2}; -use bevy_reflect::{FromReflect, Reflect, TypeUuid}; +use bevy_reflect::{Reflect, TypeUuid}; use bevy_render::{color::Color, texture::Image}; use bevy_utils::HashMap; /// An atlas containing multiple textures (like a spritesheet or a tilemap). /// [Example usage animating sprite.](https://github.com/bevyengine/bevy/blob/latest/examples/2d/sprite_sheet.rs) /// [Example usage loading sprite sheet.](https://github.com/bevyengine/bevy/blob/latest/examples/2d/texture_atlas.rs) -#[derive(Reflect, FromReflect, Debug, Clone, TypeUuid)] +#[derive(Reflect, Debug, Clone, TypeUuid)] #[uuid = "7233c597-ccfa-411f-bd59-9af349432ada"] #[reflect(Debug)] pub struct TextureAtlas { @@ -23,7 +23,7 @@ pub struct TextureAtlas { pub texture_handles: Option, usize>>, } -#[derive(Component, Debug, Clone, Reflect, FromReflect)] +#[derive(Component, Debug, Clone, Reflect)] #[reflect(Component)] pub struct TextureAtlasSprite { /// The tint color used to draw the sprite, defaulting to [`Color::WHITE`] diff --git a/crates/bevy_text/src/text.rs b/crates/bevy_text/src/text.rs index 9975d2d97e1b4..00713800bd2ca 100644 --- a/crates/bevy_text/src/text.rs +++ b/crates/bevy_text/src/text.rs @@ -1,6 +1,6 @@ use bevy_asset::Handle; use bevy_ecs::{prelude::Component, reflect::ReflectComponent}; -use bevy_reflect::{prelude::*, FromReflect}; +use bevy_reflect::prelude::*; use bevy_render::color::Color; use bevy_utils::default; use serde::{Deserialize, Serialize}; @@ -115,7 +115,7 @@ impl Text { } } -#[derive(Debug, Default, Clone, FromReflect, Reflect)] +#[derive(Debug, Default, Clone, Reflect)] pub struct TextSection { pub value: String, pub style: TextStyle, @@ -164,7 +164,7 @@ impl From for glyph_brush_layout::HorizontalAlign { } } -#[derive(Clone, Debug, Reflect, FromReflect)] +#[derive(Clone, Debug, Reflect)] pub struct TextStyle { pub font: Handle, pub font_size: f32, diff --git a/crates/bevy_text/src/text2d.rs b/crates/bevy_text/src/text2d.rs index 61f0354b591eb..a7c72c5d44f86 100644 --- a/crates/bevy_text/src/text2d.rs +++ b/crates/bevy_text/src/text2d.rs @@ -10,7 +10,7 @@ use bevy_ecs::{ system::{Local, Query, Res, ResMut}, }; use bevy_math::{Vec2, Vec3}; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; use bevy_render::{ prelude::Color, texture::Image, @@ -34,8 +34,8 @@ use crate::{ /// Note: only characters that are completely out of the bounds will be truncated, so this is not a /// reliable limit if it is necessary to contain the text strictly in the bounds. Currently this /// component is mainly useful for text wrapping only. -#[derive(Component, Copy, Clone, Debug, Reflect, FromReflect)] -#[reflect(Component, FromReflect)] +#[derive(Component, Copy, Clone, Debug, Reflect)] +#[reflect(Component)] pub struct Text2dBounds { pub size: Vec2, } diff --git a/crates/bevy_time/src/stopwatch.rs b/crates/bevy_time/src/stopwatch.rs index 829f947ae0f54..b7b4fccb008a1 100644 --- a/crates/bevy_time/src/stopwatch.rs +++ b/crates/bevy_time/src/stopwatch.rs @@ -23,7 +23,7 @@ use bevy_utils::Duration; /// assert!(stopwatch.paused()); /// assert_eq!(stopwatch.elapsed_secs(), 0.0); /// ``` -#[derive(Clone, Debug, Default, PartialEq, Eq, Reflect, FromReflect)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Reflect)] #[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))] #[reflect(Default)] pub struct Stopwatch { diff --git a/crates/bevy_time/src/time.rs b/crates/bevy_time/src/time.rs index f462296ad6aef..de2a10dbb53e0 100644 --- a/crates/bevy_time/src/time.rs +++ b/crates/bevy_time/src/time.rs @@ -1,11 +1,11 @@ use bevy_ecs::{reflect::ReflectResource, system::Resource}; -use bevy_reflect::{FromReflect, Reflect}; +use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_utils::{Duration, Instant}; /// A clock that tracks how much it has advanced (and how much real time has elapsed) since /// its previous update and since its creation. -#[derive(Resource, Reflect, FromReflect, Debug, Clone)] -#[reflect(Resource)] +#[derive(Resource, Reflect, Debug, Clone)] +#[reflect(Resource, Default)] pub struct Time { startup: Instant, first_update: Option, diff --git a/crates/bevy_time/src/timer.rs b/crates/bevy_time/src/timer.rs index d7da9e7c8ddbf..3f0503e9fd847 100644 --- a/crates/bevy_time/src/timer.rs +++ b/crates/bevy_time/src/timer.rs @@ -9,7 +9,7 @@ use bevy_utils::Duration; /// exceeded, and can still be reset at any given point. /// /// Paused timers will not have elapsed time increased. -#[derive(Clone, Debug, Default, PartialEq, Eq, Reflect, FromReflect)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Reflect)] #[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))] #[reflect(Default)] pub struct Timer { @@ -415,7 +415,7 @@ impl Timer { } /// Specifies [`Timer`] behavior. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Default, Reflect, FromReflect)] +#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Default, Reflect)] #[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))] #[reflect(Default)] pub enum TimerMode { diff --git a/crates/bevy_transform/src/components/global_transform.rs b/crates/bevy_transform/src/components/global_transform.rs index c9aa20cec576c..4e1480c44b0b5 100644 --- a/crates/bevy_transform/src/components/global_transform.rs +++ b/crates/bevy_transform/src/components/global_transform.rs @@ -3,7 +3,7 @@ use std::ops::Mul; use super::Transform; use bevy_ecs::{component::Component, reflect::ReflectComponent}; use bevy_math::{Affine3A, Mat4, Quat, Vec3, Vec3A}; -use bevy_reflect::{std_traits::ReflectDefault, FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::{std_traits::ReflectDefault, Reflect}; /// Describe the position of an entity relative to the reference frame. /// @@ -33,9 +33,9 @@ use bevy_reflect::{std_traits::ReflectDefault, FromReflect, Reflect, ReflectFrom /// - [`transform`] /// /// [`transform`]: https://github.com/bevyengine/bevy/blob/latest/examples/transforms/transform.rs -#[derive(Component, Debug, PartialEq, Clone, Copy, Reflect, FromReflect)] +#[derive(Component, Debug, PartialEq, Clone, Copy, Reflect)] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] -#[reflect(Component, Default, PartialEq, FromReflect)] +#[reflect(Component, Default, PartialEq)] pub struct GlobalTransform(Affine3A); macro_rules! impl_local_axis { diff --git a/crates/bevy_transform/src/components/transform.rs b/crates/bevy_transform/src/components/transform.rs index d7161c542778c..e02ebebbbd98d 100644 --- a/crates/bevy_transform/src/components/transform.rs +++ b/crates/bevy_transform/src/components/transform.rs @@ -35,9 +35,9 @@ use std::ops::Mul; /// [`global_vs_local_translation`]: https://github.com/bevyengine/bevy/blob/latest/examples/transforms/global_vs_local_translation.rs /// [`transform`]: https://github.com/bevyengine/bevy/blob/latest/examples/transforms/transform.rs /// [`Transform`]: super::Transform -#[derive(Component, Debug, PartialEq, Clone, Copy, Reflect, FromReflect)] +#[derive(Component, Debug, PartialEq, Clone, Copy, Reflect)] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] -#[reflect(Component, Default, PartialEq, FromReflect)] +#[reflect(Component, Default, PartialEq)] pub struct Transform { /// Position of the entity. In 2d, the last value of the `Vec3` is used for z-ordering. /// diff --git a/crates/bevy_ui/src/camera_config.rs b/crates/bevy_ui/src/camera_config.rs index 69ce17705ac2c..857bd57ebec7c 100644 --- a/crates/bevy_ui/src/camera_config.rs +++ b/crates/bevy_ui/src/camera_config.rs @@ -3,7 +3,7 @@ use bevy_ecs::component::Component; use bevy_ecs::prelude::With; use bevy_ecs::reflect::ReflectComponent; -use bevy_reflect::{std_traits::ReflectDefault, FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::camera::Camera; use bevy_render::extract_component::ExtractComponent; @@ -12,9 +12,9 @@ use bevy_render::extract_component::ExtractComponent; /// When a [`Camera`] doesn't have the [`UiCameraConfig`] component, /// it will display the UI by default. /// -#[derive(Component, Clone, ExtractComponent, Reflect, FromReflect)] +#[derive(Component, Clone, ExtractComponent, Reflect)] #[extract_component_filter(With)] -#[reflect(Component, FromReflect, Default)] +#[reflect(Component, Default)] pub struct UiCameraConfig { /// Whether to output UI to this camera view. /// diff --git a/crates/bevy_ui/src/focus.rs b/crates/bevy_ui/src/focus.rs index 729fe7f7dae2f..e3ce2ce927c7d 100644 --- a/crates/bevy_ui/src/focus.rs +++ b/crates/bevy_ui/src/focus.rs @@ -10,9 +10,7 @@ use bevy_ecs::{ }; use bevy_input::{mouse::MouseButton, touch::Touches, Input}; use bevy_math::Vec2; -use bevy_reflect::{ - FromReflect, Reflect, ReflectDeserialize, ReflectFromReflect, ReflectSerialize, -}; +use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize}; use bevy_render::{camera::NormalizedRenderTarget, prelude::Camera, view::ComputedVisibility}; use bevy_transform::components::GlobalTransform; @@ -34,10 +32,8 @@ use smallvec::SmallVec; /// /// Note that you can also control the visibility of a node using the [`Display`](crate::ui_node::Display) property, /// which fully collapses it during layout calculations. -#[derive( - Component, Copy, Clone, Eq, PartialEq, Debug, Reflect, FromReflect, Serialize, Deserialize, -)] -#[reflect(Component, FromReflect, Serialize, Deserialize, PartialEq)] +#[derive(Component, Copy, Clone, Eq, PartialEq, Debug, Reflect, Serialize, Deserialize)] +#[reflect(Component, Serialize, Deserialize, PartialEq)] pub enum Interaction { /// The node has been clicked Clicked, @@ -72,11 +68,10 @@ impl Default for Interaction { PartialEq, Debug, Reflect, - FromReflect, Serialize, Deserialize, )] -#[reflect(Component, FromReflect, Serialize, Deserialize, PartialEq)] +#[reflect(Component, Serialize, Deserialize, PartialEq)] pub struct RelativeCursorPosition { /// Cursor position relative to size and position of the Node. pub normalized: Option, @@ -92,10 +87,8 @@ impl RelativeCursorPosition { } /// Describes whether the node should block interactions with lower nodes -#[derive( - Component, Copy, Clone, Eq, PartialEq, Debug, Reflect, FromReflect, Serialize, Deserialize, -)] -#[reflect(Component, FromReflect, Serialize, Deserialize, PartialEq)] +#[derive(Component, Copy, Clone, Eq, PartialEq, Debug, Reflect, Serialize, Deserialize)] +#[reflect(Component, Serialize, Deserialize, PartialEq)] pub enum FocusPolicy { /// Blocks interaction Block, diff --git a/crates/bevy_ui/src/geometry.rs b/crates/bevy_ui/src/geometry.rs index d55b70066759d..aca0c10b016a1 100644 --- a/crates/bevy_ui/src/geometry.rs +++ b/crates/bevy_ui/src/geometry.rs @@ -1,5 +1,5 @@ use crate::Val; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; /// A type which is commonly used to define margins, paddings and borders. /// @@ -45,8 +45,8 @@ use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; /// bottom: Val::Px(40.0), /// }; /// ``` -#[derive(Copy, Clone, PartialEq, Debug, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq)] +#[derive(Copy, Clone, PartialEq, Debug, Reflect)] +#[reflect(PartialEq)] pub struct UiRect { /// The value corresponding to the left side of the UI rect. pub left: Val, diff --git a/crates/bevy_ui/src/measurement.rs b/crates/bevy_ui/src/measurement.rs index 896c9f6c05505..fd31ae9ab4f96 100644 --- a/crates/bevy_ui/src/measurement.rs +++ b/crates/bevy_ui/src/measurement.rs @@ -1,7 +1,7 @@ use bevy_ecs::prelude::Component; use bevy_ecs::reflect::ReflectComponent; use bevy_math::Vec2; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; use std::fmt::Formatter; pub use taffy::style::AvailableSpace; @@ -45,8 +45,8 @@ impl Measure for FixedMeasure { /// A node with a `ContentSize` component is a node where its size /// is based on its content. -#[derive(Component, Reflect, FromReflect)] -#[reflect(Component, FromReflect)] +#[derive(Component, Reflect)] +#[reflect(Component)] pub struct ContentSize { /// The `Measure` used to compute the intrinsic size #[reflect(ignore)] diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 8d6c26af41b8a..532007ed3b752 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -3,7 +3,6 @@ use bevy_asset::Handle; use bevy_ecs::{prelude::Component, reflect::ReflectComponent}; use bevy_math::{Rect, Vec2}; use bevy_reflect::prelude::*; -use bevy_reflect::ReflectFromReflect; use bevy_render::{ color::Color, texture::{Image, DEFAULT_IMAGE_HANDLE}, @@ -15,8 +14,8 @@ use std::ops::{Div, DivAssign, Mul, MulAssign}; use thiserror::Error; /// Describes the size of a UI node -#[derive(Component, Debug, Copy, Clone, Reflect, FromReflect)] -#[reflect(Component, Default, FromReflect)] +#[derive(Component, Debug, Copy, Clone, Reflect)] +#[reflect(Component, Default)] pub struct Node { /// The size of the node as width and height in logical pixels /// automatically calculated by [`super::layout::ui_layout_system`] @@ -78,8 +77,8 @@ impl Default for Node { /// /// This enum allows specifying values for various [`Style`] properties in different units, /// such as logical pixels, percentages, or automatically determined values. -#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] pub enum Val { /// Automatically determine the value based on the context and other [`Style`] properties. Auto, @@ -294,8 +293,8 @@ impl Val { /// - [A Complete Guide To CSS Grid](https://css-tricks.com/snippets/css/complete-guide-grid/) by CSS Tricks. This is detailed guide with illustrations and comphrehensive written explanation of the different CSS Grid properties and how they work. /// - [CSS Grid Garden](https://cssgridgarden.com/). An interactive tutorial/game that teaches the essential parts of CSS Grid in a fun engaging way. -#[derive(Component, Clone, PartialEq, Debug, Reflect, FromReflect)] -#[reflect(Component, FromReflect, Default, PartialEq)] +#[derive(Component, Clone, PartialEq, Debug, Reflect)] +#[reflect(Component, Default, PartialEq)] pub struct Style { /// Which layout algorithm to use when laying out this node's contents: /// - [`Display::Flex`]: Use the Flexbox layout algorithm @@ -628,8 +627,8 @@ impl Default for Style { } /// How items are aligned according to the cross axis -#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] pub enum AlignItems { /// The items are packed in their default position as if no alignment was applied Default, @@ -662,8 +661,8 @@ impl Default for AlignItems { } /// How items are aligned according to the cross axis -#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] pub enum JustifyItems { /// The items are packed in their default position as if no alignment was applied Default, @@ -691,8 +690,8 @@ impl Default for JustifyItems { /// How this item is aligned according to the cross axis. /// Overrides [`AlignItems`]. -#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] pub enum AlignSelf { /// Use the parent node's [`AlignItems`] value to determine how this item should be aligned. Auto, @@ -726,8 +725,8 @@ impl Default for AlignSelf { /// How this item is aligned according to the cross axis. /// Overrides [`AlignItems`]. -#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] pub enum JustifySelf { /// Use the parent node's [`AlignItems`] value to determine how this item should be aligned. Auto, @@ -756,8 +755,8 @@ impl Default for JustifySelf { /// Defines how each line is aligned within the flexbox. /// /// It only applies if [`FlexWrap::Wrap`] is present and if there are multiple lines of items. -#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] pub enum AlignContent { /// The items are packed in their default position as if no alignment was applied Default, @@ -795,8 +794,8 @@ impl Default for AlignContent { } /// Defines how items are aligned according to the main axis -#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] pub enum JustifyContent { /// The items are packed in their default position as if no alignment was applied Default, @@ -831,8 +830,8 @@ impl Default for JustifyContent { /// Defines the text direction /// /// For example English is written LTR (left-to-right) while Arabic is written RTL (right-to-left). -#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] pub enum Direction { /// Inherit from parent node. Inherit, @@ -855,8 +854,8 @@ impl Default for Direction { /// Whether to use a Flexbox layout model. /// /// Part of the [`Style`] component. -#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] pub enum Display { /// Use Flexbox layout model to determine the position of this [`Node`]. Flex, @@ -880,8 +879,8 @@ impl Default for Display { } /// Defines how flexbox items are ordered within a flexbox -#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] pub enum FlexDirection { /// Same way as text direction along the main axis. Row, @@ -904,8 +903,8 @@ impl Default for FlexDirection { } /// Whether to show or hide overflowing items -#[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect, Serialize, Deserialize, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect, Serialize, Deserialize)] +#[reflect(PartialEq, Serialize, Deserialize)] pub struct Overflow { /// Whether to show or clip overflowing items on the x axis pub x: OverflowAxis, @@ -964,8 +963,8 @@ impl Default for Overflow { } /// Whether to show or hide overflowing items -#[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect, FromReflect, Serialize, Deserialize)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect, Serialize, Deserialize)] +#[reflect(PartialEq, Serialize, Deserialize)] pub enum OverflowAxis { /// Show overflowing items. Visible, @@ -989,8 +988,8 @@ impl Default for OverflowAxis { } /// The strategy used to position this node -#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] pub enum PositionType { /// Relative to all other nodes with the [`PositionType::Relative`] value. Relative, @@ -1011,8 +1010,8 @@ impl Default for PositionType { } /// Defines if flexbox items appear on a single line or on multiple lines -#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] pub enum FlexWrap { /// Single line, will overflow if needed. NoWrap, @@ -1039,8 +1038,8 @@ impl Default for FlexWrap { /// Defaults to [`GridAutoFlow::Row`] /// /// -#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] pub enum GridAutoFlow { /// Items are placed by filling each row in turn, adding new rows as necessary Row, @@ -1062,8 +1061,8 @@ impl Default for GridAutoFlow { } } -#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect_value(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect)] +#[reflect_value(PartialEq, Serialize, Deserialize)] pub enum MinTrackSizingFunction { /// Track minimum size should be a fixed pixel value Px(f32), @@ -1077,8 +1076,8 @@ pub enum MinTrackSizingFunction { Auto, } -#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect_value(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect)] +#[reflect_value(PartialEq, Serialize, Deserialize)] pub enum MaxTrackSizingFunction { /// Track maximum size should be a fixed pixel value Px(f32), @@ -1102,8 +1101,8 @@ pub enum MaxTrackSizingFunction { /// A [`GridTrack`] is a Row or Column of a CSS Grid. This struct specifies what size the track should be. /// See below for the different "track sizing functions" you can specify. -#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] pub struct GridTrack { pub(crate) min_sizing_function: MinTrackSizingFunction, pub(crate) max_sizing_function: MaxTrackSizingFunction, @@ -1220,8 +1219,8 @@ impl Default for GridTrack { } } -#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] /// How many times to repeat a repeated grid track /// /// @@ -1270,8 +1269,8 @@ impl From for GridTrackRepetition { /// You may only use one auto-repetition per track list. And if your track list contains an auto repetition /// then all track (in and outside of the repetition) must be fixed size (px or percent). Integer repetitions are just shorthand for writing out /// N tracks longhand and are not subject to the same limitations. -#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] pub struct RepeatedGridTrack { pub(crate) repetition: GridTrackRepetition, pub(crate) tracks: SmallVec<[GridTrack; 1]>, @@ -1420,8 +1419,8 @@ impl From for Vec { } } -#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)] -#[reflect(FromReflect, PartialEq, Serialize, Deserialize)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)] +#[reflect(PartialEq, Serialize, Deserialize)] /// Represents the position of a grid item in a single axis. /// /// There are 3 fields which may be set: @@ -1543,8 +1542,8 @@ impl Default for GridPlacement { /// /// This serves as the "fill" color. /// When combined with [`UiImage`], tints the provided texture. -#[derive(Component, Copy, Clone, Debug, Reflect, FromReflect)] -#[reflect(FromReflect, Component, Default)] +#[derive(Component, Copy, Clone, Debug, Reflect)] +#[reflect(Component, Default)] pub struct BackgroundColor(pub Color); impl BackgroundColor { @@ -1564,7 +1563,7 @@ impl From for BackgroundColor { } /// The atlas sprite to be used in a UI Texture Atlas Node -#[derive(Component, Clone, Debug, Reflect, FromReflect, Default)] +#[derive(Component, Clone, Debug, Reflect, Default)] #[reflect(Component, Default)] pub struct UiTextureAtlasImage { /// Texture index in the TextureAtlas @@ -1576,8 +1575,8 @@ pub struct UiTextureAtlasImage { } /// The border color of the UI node. -#[derive(Component, Copy, Clone, Debug, Reflect, FromReflect)] -#[reflect(FromReflect, Component, Default)] +#[derive(Component, Copy, Clone, Debug, Reflect)] +#[reflect(Component, Default)] pub struct BorderColor(pub Color); impl From for BorderColor { @@ -1597,8 +1596,8 @@ impl Default for BorderColor { } /// The 2D texture displayed for this UI node -#[derive(Component, Clone, Debug, Reflect, FromReflect)] -#[reflect(Component, Default, FromReflect)] +#[derive(Component, Clone, Debug, Reflect)] +#[reflect(Component, Default)] pub struct UiImage { /// Handle to the texture pub texture: Handle, @@ -1648,8 +1647,8 @@ impl From> for UiImage { } /// The calculated clip of the node -#[derive(Component, Default, Copy, Clone, Debug, Reflect, FromReflect)] -#[reflect(FromReflect, Component)] +#[derive(Component, Default, Copy, Clone, Debug, Reflect)] +#[reflect(Component)] pub struct CalculatedClip { /// The rect of the clip pub clip: Rect, @@ -1668,8 +1667,8 @@ pub struct CalculatedClip { /// [`ZIndex::Local(n)`] and [`ZIndex::Global(n)`] for root nodes. /// /// Nodes without this component will be treated as if they had a value of [`ZIndex::Local(0)`]. -#[derive(Component, Copy, Clone, Debug, Reflect, FromReflect)] -#[reflect(Component, FromReflect)] +#[derive(Component, Copy, Clone, Debug, Reflect)] +#[reflect(Component)] pub enum ZIndex { /// Indicates the order in which this node should be rendered relative to its siblings. Local(i32), diff --git a/crates/bevy_ui/src/widget/button.rs b/crates/bevy_ui/src/widget/button.rs index 9e6bd94da82d8..6c7dced0f3bb0 100644 --- a/crates/bevy_ui/src/widget/button.rs +++ b/crates/bevy_ui/src/widget/button.rs @@ -1,9 +1,9 @@ use bevy_ecs::prelude::Component; use bevy_ecs::reflect::ReflectComponent; use bevy_reflect::std_traits::ReflectDefault; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; /// Marker struct for buttons -#[derive(Component, Debug, Default, Clone, Copy, Reflect, FromReflect)] -#[reflect(Component, FromReflect, Default)] +#[derive(Component, Debug, Default, Clone, Copy, Reflect)] +#[reflect(Component, Default)] pub struct Button; diff --git a/crates/bevy_ui/src/widget/image.rs b/crates/bevy_ui/src/widget/image.rs index 0e638c54954e9..be9df0590c09c 100644 --- a/crates/bevy_ui/src/widget/image.rs +++ b/crates/bevy_ui/src/widget/image.rs @@ -12,7 +12,7 @@ use bevy_ecs::{ system::{Local, Query, Res}, }; use bevy_math::Vec2; -use bevy_reflect::{std_traits::ReflectDefault, FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::texture::Image; use bevy_sprite::TextureAtlas; #[cfg(feature = "bevy_text")] @@ -22,8 +22,8 @@ use bevy_window::{PrimaryWindow, Window}; /// The size of the image's texture /// /// This component is updated automatically by [`update_image_content_size_system`] -#[derive(Component, Debug, Copy, Clone, Default, Reflect, FromReflect)] -#[reflect(Component, Default, FromReflect)] +#[derive(Component, Debug, Copy, Clone, Default, Reflect)] +#[reflect(Component, Default)] pub struct UiImageSize { /// The size of the image's texture /// diff --git a/crates/bevy_ui/src/widget/label.rs b/crates/bevy_ui/src/widget/label.rs index cf426d5803b20..5b4561ac34ec1 100644 --- a/crates/bevy_ui/src/widget/label.rs +++ b/crates/bevy_ui/src/widget/label.rs @@ -1,9 +1,9 @@ use bevy_ecs::prelude::Component; use bevy_ecs::reflect::ReflectComponent; use bevy_reflect::std_traits::ReflectDefault; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; /// Marker struct for labels -#[derive(Component, Debug, Default, Clone, Copy, Reflect, FromReflect)] -#[reflect(Component, FromReflect, Default)] +#[derive(Component, Debug, Default, Clone, Copy, Reflect)] +#[reflect(Component, Default)] pub struct Label; diff --git a/crates/bevy_ui/src/widget/text.rs b/crates/bevy_ui/src/widget/text.rs index 72d2bbf0b3a36..06d876eb7a684 100644 --- a/crates/bevy_ui/src/widget/text.rs +++ b/crates/bevy_ui/src/widget/text.rs @@ -8,7 +8,7 @@ use bevy_ecs::{ world::{Mut, Ref}, }; use bevy_math::Vec2; -use bevy_reflect::{std_traits::ReflectDefault, FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_render::texture::Image; use bevy_sprite::TextureAtlas; use bevy_text::{ @@ -21,8 +21,8 @@ use taffy::style::AvailableSpace; /// Text system flags /// /// Used internally by [`measure_text_system`] and [`text_system`] to schedule text for processing. -#[derive(Component, Debug, Clone, Reflect, FromReflect)] -#[reflect(Component, Default, FromReflect)] +#[derive(Component, Debug, Clone, Reflect)] +#[reflect(Component, Default)] pub struct TextFlags { /// If set a new measure function for the text node will be created needs_new_measure_func: bool, diff --git a/crates/bevy_window/src/cursor.rs b/crates/bevy_window/src/cursor.rs index 9622f2afd10b8..7867c27a30cd4 100644 --- a/crates/bevy_window/src/cursor.rs +++ b/crates/bevy_window/src/cursor.rs @@ -1,4 +1,4 @@ -use bevy_reflect::{prelude::ReflectDefault, FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::{prelude::ReflectDefault, Reflect}; #[cfg(feature = "serialize")] use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; @@ -8,13 +8,13 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; /// Examples of all of these cursors can be found [here](https://www.w3schools.com/cssref/playit.php?filename=playcss_cursor&preval=crosshair). /// This `enum` is simply a copy of a similar `enum` found in [`winit`](https://docs.rs/winit/latest/winit/window/enum.CursorIcon.html). /// `winit`, in turn, mostly copied cursor types available in the browser. -#[derive(Default, Debug, Hash, PartialEq, Eq, Clone, Copy, Reflect, FromReflect)] +#[derive(Default, Debug, Hash, PartialEq, Eq, Clone, Copy, Reflect)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -#[reflect(Debug, PartialEq, Default, FromReflect)] +#[reflect(Debug, PartialEq, Default)] pub enum CursorIcon { /// The platform-dependent default cursor. #[default] diff --git a/crates/bevy_window/src/event.rs b/crates/bevy_window/src/event.rs index ee47f34151246..bc0dc9d872d7d 100644 --- a/crates/bevy_window/src/event.rs +++ b/crates/bevy_window/src/event.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use bevy_ecs::entity::Entity; use bevy_ecs::event::Event; use bevy_math::{IVec2, Vec2}; -use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::Reflect; #[cfg(feature = "serialize")] use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; @@ -11,8 +11,8 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; use crate::WindowTheme; /// A window event that is sent whenever a window's logical size has changed. -#[derive(Event, Debug, Clone, PartialEq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -29,8 +29,8 @@ pub struct WindowResized { /// An event that indicates all of the application's windows should be redrawn, /// even if their control flow is set to `Wait` and there have been no window events. -#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -41,8 +41,8 @@ pub struct RequestRedraw; /// An event that is sent whenever a new window is created. /// /// To create a new window, spawn an entity with a [`crate::Window`] on it. -#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -63,8 +63,8 @@ pub struct WindowCreated { /// /// [`WindowPlugin`]: crate::WindowPlugin /// [`Window`]: crate::Window -#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -77,8 +77,8 @@ pub struct WindowCloseRequested { /// An event that is sent whenever a window is closed. This will be sent when /// the window entity loses its [`Window`](crate::window::Window) component or is despawned. -#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -100,8 +100,8 @@ pub struct WindowClosed { /// /// [`WindowEvent::CursorMoved`]: https://docs.rs/winit/latest/winit/event/enum.WindowEvent.html#variant.CursorMoved /// [`MouseMotion`]: bevy_input::mouse::MouseMotion -#[derive(Event, Debug, Clone, PartialEq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -115,8 +115,8 @@ pub struct CursorMoved { } /// An event that is sent whenever the user's cursor enters a window. -#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -128,8 +128,8 @@ pub struct CursorEntered { } /// An event that is sent whenever the user's cursor leaves a window. -#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -141,8 +141,8 @@ pub struct CursorLeft { } /// An event that is sent whenever a window receives a character from the OS or underlying system. -#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -160,8 +160,8 @@ pub struct ReceivedCharacter { /// This event is the translated version of the `WindowEvent::Ime` from the `winit` crate. /// /// It is only sent if IME was enabled on the window with [`Window::ime_enabled`](crate::window::Window::ime_enabled). -#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -202,8 +202,8 @@ pub enum Ime { } /// An event that indicates a window has received or lost focus. -#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -217,8 +217,8 @@ pub struct WindowFocused { } /// An event that indicates a window's scale factor has changed. -#[derive(Event, Debug, Clone, PartialEq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -232,8 +232,8 @@ pub struct WindowScaleFactorChanged { } /// An event that indicates a window's OS-reported scale factor has changed. -#[derive(Event, Debug, Clone, PartialEq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -247,8 +247,8 @@ pub struct WindowBackendScaleFactorChanged { } /// Events related to files being dragged and dropped on a window. -#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -279,8 +279,8 @@ pub enum FileDragAndDrop { } /// An event that is sent when a window is repositioned in physical pixels. -#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -297,8 +297,8 @@ pub struct WindowMoved { /// /// This event is only sent when the window is relying on the system theme to control its appearance. /// i.e. It is only sent when [`Window::window_theme`](crate::window::Window::window_theme) is `None` and the system theme changes. -#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect, FromReflect)] -#[reflect(Debug, PartialEq, FromReflect)] +#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)] +#[reflect(Debug, PartialEq)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), diff --git a/crates/bevy_window/src/window.rs b/crates/bevy_window/src/window.rs index dc2978242a2f0..b5135751845f1 100644 --- a/crates/bevy_window/src/window.rs +++ b/crates/bevy_window/src/window.rs @@ -3,7 +3,7 @@ use bevy_ecs::{ prelude::{Component, ReflectComponent}, }; use bevy_math::{DVec2, IVec2, Vec2}; -use bevy_reflect::{std_traits::ReflectDefault, FromReflect, Reflect, ReflectFromReflect}; +use bevy_reflect::{std_traits::ReflectDefault, Reflect}; #[cfg(feature = "serialize")] use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; @@ -18,16 +18,14 @@ use crate::CursorIcon; /// /// [`WindowPlugin`](crate::WindowPlugin) will spawn a window entity /// with this component if `primary_window` is `Some`. -#[derive( - Default, Debug, Component, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Reflect, FromReflect, -)] -#[reflect(Component, FromReflect)] +#[derive(Default, Debug, Component, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Reflect)] +#[reflect(Component)] pub struct PrimaryWindow; /// Reference to a [`Window`], whether it be a direct link to a specific entity or /// a more vague defaulting choice. #[repr(C)] -#[derive(Default, Copy, Clone, Debug, Reflect, FromReflect)] +#[derive(Default, Copy, Clone, Debug, Reflect)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -74,7 +72,7 @@ impl MapEntities for WindowRef { /// /// For most purposes you probably want to use the unnormalized version [`WindowRef`]. #[repr(C)] -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Reflect, FromReflect)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Reflect)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -98,13 +96,13 @@ impl NormalizedWindowRef { /// /// This component is synchronized with `winit` through `bevy_winit`: /// it will reflect the current state of the window and can be modified to change this state. -#[derive(Component, Debug, Clone, Reflect, FromReflect)] +#[derive(Component, Debug, Clone, Reflect)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -#[reflect(Component, Default, FromReflect)] +#[reflect(Component, Default)] pub struct Window { /// The cursor of this window. pub cursor: Cursor, @@ -338,13 +336,13 @@ impl Window { /// Please note that if the window is resizable, then when the window is /// maximized it may have a size outside of these limits. The functionality /// required to disable maximizing is not yet exposed by winit. -#[derive(Debug, Clone, Copy, PartialEq, Reflect, FromReflect)] +#[derive(Debug, Clone, Copy, PartialEq, Reflect)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -#[reflect(Debug, PartialEq, Default, FromReflect)] +#[reflect(Debug, PartialEq, Default)] pub struct WindowResizeConstraints { /// The minimum width the window can have. pub min_width: f32, @@ -405,13 +403,13 @@ impl WindowResizeConstraints { } /// Cursor data for a [`Window`]. -#[derive(Debug, Copy, Clone, Reflect, FromReflect)] +#[derive(Debug, Copy, Clone, Reflect)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -#[reflect(Debug, Default, FromReflect)] +#[reflect(Debug, Default)] pub struct Cursor { /// What the cursor should look like while inside the window. pub icon: CursorIcon, @@ -457,13 +455,13 @@ impl Default for Cursor { } /// Defines where a [`Window`] should be placed on the screen. -#[derive(Default, Debug, Clone, Copy, PartialEq, Reflect, FromReflect)] +#[derive(Default, Debug, Clone, Copy, PartialEq, Reflect)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -#[reflect(Debug, PartialEq, FromReflect)] +#[reflect(Debug, PartialEq)] pub enum WindowPosition { /// Position will be set by the window manager. /// Bevy will delegate this decision to the window manager and no guarantees can be made about where the window will be placed. @@ -546,13 +544,13 @@ impl WindowPosition { /// and then setting a scale factor that makes the previous requested size within /// the limits of the screen will not get back that previous requested size. -#[derive(Debug, Clone, PartialEq, Reflect, FromReflect)] +#[derive(Debug, Clone, PartialEq, Reflect)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -#[reflect(Debug, PartialEq, Default, FromReflect)] +#[reflect(Debug, PartialEq, Default)] pub struct WindowResolution { /// Width of the window in physical pixels. physical_width: u32, @@ -721,13 +719,13 @@ impl From for WindowResolution { /// - **`iOS/Android`** don't have cursors. /// /// Since `Windows` and `macOS` have different [`CursorGrabMode`] support, we first try to set the grab mode that was asked for. If it doesn't work then use the alternate grab mode. -#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Reflect, FromReflect)] +#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Reflect)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -#[reflect(Debug, PartialEq, Default, FromReflect)] +#[reflect(Debug, PartialEq, Default)] pub enum CursorGrabMode { /// The cursor can freely leave the window. #[default] @@ -739,13 +737,13 @@ pub enum CursorGrabMode { } /// Stores internal [`Window`] state that isn't directly accessible. -#[derive(Default, Debug, Copy, Clone, PartialEq, Reflect, FromReflect)] +#[derive(Default, Debug, Copy, Clone, PartialEq, Reflect)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -#[reflect(Debug, PartialEq, Default, FromReflect)] +#[reflect(Debug, PartialEq, Default)] pub struct InternalWindowState { /// If this is true then next frame we will ask to minimize the window. minimize_request: Option, @@ -770,13 +768,13 @@ impl InternalWindowState { /// References a screen monitor. /// /// Used when centering a [`Window`] on a monitor. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Reflect, FromReflect)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Reflect)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -#[reflect(Debug, PartialEq, FromReflect)] +#[reflect(Debug, PartialEq)] pub enum MonitorSelection { /// Uses the current monitor of the window. /// @@ -809,13 +807,13 @@ pub enum MonitorSelection { /// [`AutoNoVsync`]: PresentMode::AutoNoVsync /// #[repr(C)] -#[derive(Default, Copy, Clone, Debug, PartialEq, Eq, Hash, Reflect, FromReflect)] +#[derive(Default, Copy, Clone, Debug, PartialEq, Eq, Hash, Reflect)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -#[reflect(Debug, PartialEq, Hash, FromReflect)] +#[reflect(Debug, PartialEq, Hash)] #[doc(alias = "vsync")] pub enum PresentMode { /// Chooses FifoRelaxed -> Fifo based on availability. @@ -849,13 +847,13 @@ pub enum PresentMode { /// Specifies how the alpha channel of the textures should be handled during compositing, for a [`Window`]. #[repr(C)] -#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Reflect, FromReflect)] +#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Reflect)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -#[reflect(Debug, PartialEq, Hash, FromReflect)] +#[reflect(Debug, PartialEq, Hash)] pub enum CompositeAlphaMode { /// Chooses either [`Opaque`](CompositeAlphaMode::Opaque) or [`Inherit`](CompositeAlphaMode::Inherit) /// automatically, depending on the `alpha_mode` that the current surface can support. @@ -884,13 +882,13 @@ pub enum CompositeAlphaMode { } /// Defines the way a [`Window`] is displayed. -#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Reflect, FromReflect)] +#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Reflect)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -#[reflect(Debug, PartialEq, FromReflect)] +#[reflect(Debug, PartialEq)] pub enum WindowMode { /// The window should take a portion of the screen, using the window resolution size. #[default] @@ -931,13 +929,13 @@ pub enum WindowMode { /// ## Platform-specific /// /// - **iOS / Android / Web / Wayland:** Unsupported. -#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Reflect, FromReflect)] +#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Reflect)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -#[reflect(Debug, PartialEq, FromReflect)] +#[reflect(Debug, PartialEq)] pub enum WindowLevel { /// The window will always be below [`WindowLevel::Normal`] and [`WindowLevel::AlwaysOnTop`] windows. /// @@ -951,13 +949,13 @@ pub enum WindowLevel { } /// The [`Window`] theme variant to use. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Reflect, FromReflect)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Reflect)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), reflect(Serialize, Deserialize) )] -#[reflect(Debug, PartialEq, FromReflect)] +#[reflect(Debug, PartialEq)] pub enum WindowTheme { /// Use the light variant. Light, diff --git a/examples/reflection/reflection.rs b/examples/reflection/reflection.rs index bd23d5a1a838d..8f874633f8af6 100644 --- a/examples/reflection/reflection.rs +++ b/examples/reflection/reflection.rs @@ -25,7 +25,15 @@ fn main() { /// Deriving `Reflect` implements the relevant reflection traits. In this case, it implements the /// `Reflect` trait and the `Struct` trait `derive(Reflect)` assumes that all fields also implement /// Reflect. +/// +/// All fields in a reflected item will need to be `Reflect` as well. You can opt a field out of +/// reflection by using the `#[reflect(ignore)]` attribute. +/// If you choose to ignore a field, you need to let the automatically-derived `FromReflect` implementation +/// how to handle the field. +/// To do this, you can either define a `#[reflect(default = "...")]` attribute on the ignored field, or +/// opt-out of `FromReflect`'s auto-derive using the `#[reflect(from_reflect = false)]` attribute. #[derive(Reflect)] +#[reflect(from_reflect = false)] pub struct Foo { a: usize, nested: Bar, @@ -40,6 +48,7 @@ pub struct Bar { b: usize, } +#[derive(Default)] pub struct NonReflectedValue { _a: usize, }