Skip to content

Commit d2af4a5

Browse files
authored
Add FromTemplate derives to Components using Handle (#23696)
# Objective A lot of Bevy's built in types don't derive FromTemplate, which is what makes things like asset handles "templatable" in BSN: ```rust bsn! { ImageNode { image: "path_to_image.png" } } ``` ## Solution Derive `FromTemplate` for components that have handles. In cases of fields with `Option<SOME_TEMPLATED_TYPE>`, I've added the `#[template(OptionTemplate<XTemplate>)]` attribute, as these cases can't use the blanket `Default + Clone` template implementation (which doesn't do templating on the internal type). Later I'm likely to propose something like `#[template(built_in)]` for standard "collection types" to make this a little less boilerplatey.
1 parent 0b49ff7 commit d2af4a5

File tree

27 files changed

+94
-44
lines changed

27 files changed

+94
-44
lines changed

crates/bevy_animation/src/graph.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use bevy_ecs::{
1717
reflect::ReflectComponent,
1818
resource::Resource,
1919
system::{Res, ResMut},
20+
template::FromTemplate,
2021
};
2122
use bevy_platform::collections::HashMap;
2223
use bevy_reflect::{prelude::ReflectDefault, Reflect, TypePath};
@@ -130,7 +131,9 @@ pub struct AnimationGraph {
130131
}
131132

132133
/// A [`Handle`] to the [`AnimationGraph`] to be used by the [`AnimationPlayer`](crate::AnimationPlayer) on the same entity.
133-
#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq, From)]
134+
#[derive(
135+
Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq, From, FromTemplate,
136+
)]
134137
#[reflect(Component, Default, Clone)]
135138
pub struct AnimationGraphHandle(pub Handle<AnimationGraph>);
136139

crates/bevy_audio/src/audio.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ pub struct DefaultSpatialScale(pub SpatialScale);
245245
///
246246
/// Playback can be configured using the [`PlaybackSettings`] component. Note that changes to the
247247
/// [`PlaybackSettings`] component will *not* affect already-playing audio.
248-
#[derive(Component, Reflect)]
248+
#[derive(Component, Reflect, FromTemplate)]
249249
#[reflect(Component, Clone)]
250250
#[require(PlaybackSettings)]
251251
pub struct AudioPlayer<Source = AudioSource>(pub Handle<Source>)

crates/bevy_camera/src/camera.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ use super::{
66
};
77
use bevy_asset::Handle;
88
use bevy_derive::Deref;
9-
use bevy_ecs::{component::Component, entity::Entity, reflect::ReflectComponent};
9+
use bevy_ecs::{
10+
component::Component, entity::Entity, reflect::ReflectComponent, template::FromTemplate,
11+
};
1012
use bevy_image::Image;
1113
use bevy_math::{ops, Dir3, FloatOrd, Mat4, Ray3d, Rect, URect, UVec2, Vec2, Vec3, Vec3A};
1214
use bevy_reflect::prelude::*;
@@ -884,7 +886,20 @@ pub enum NormalizedRenderTarget {
884886
/// A unique id that corresponds to a specific `ManualTextureView` in the `ManualTextureViews` collection.
885887
///
886888
/// See `ManualTextureViews` in `bevy_camera` for more details.
887-
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Component, Reflect)]
889+
#[derive(
890+
Default,
891+
Debug,
892+
Clone,
893+
Copy,
894+
PartialEq,
895+
Eq,
896+
Hash,
897+
PartialOrd,
898+
Ord,
899+
Component,
900+
Reflect,
901+
FromTemplate,
902+
)]
888903
#[reflect(Component, Default, Debug, PartialEq, Hash, Clone)]
889904
pub struct ManualTextureViewHandle(pub u32);
890905

crates/bevy_gizmos/src/config.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pub use bevy_gizmos_macros::GizmoConfigGroup;
55

66
use {crate::GizmoAsset, bevy_asset::Handle, bevy_ecs::component::Component};
77

8-
use bevy_ecs::{reflect::ReflectResource, resource::Resource};
8+
use bevy_ecs::{reflect::ReflectResource, resource::Resource, template::FromTemplate};
99
use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypePath};
1010
use bevy_utils::TypeIdMap;
1111
use core::{
@@ -276,7 +276,7 @@ impl Default for GizmoLineConfig {
276276
}
277277

278278
/// Configuration for gizmo meshes.
279-
#[derive(Component)]
279+
#[derive(Component, FromTemplate)]
280280
pub struct GizmoMeshConfig {
281281
/// Apply perspective to gizmo lines.
282282
///

crates/bevy_gizmos/src/retained.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use core::ops::{Deref, DerefMut};
44

55
use bevy_asset::Handle;
6-
use bevy_ecs::{component::Component, reflect::ReflectComponent};
6+
use bevy_ecs::{component::Component, reflect::ReflectComponent, template::FromTemplate};
77
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
88
use bevy_transform::components::Transform;
99

@@ -61,7 +61,7 @@ impl DerefMut for GizmoAsset {
6161
/// ```
6262
///
6363
/// [`Gizmos`]: crate::gizmos::Gizmos
64-
#[derive(Component, Clone, Debug, Default, Reflect)]
64+
#[derive(Component, Clone, Debug, Default, Reflect, FromTemplate)]
6565
#[reflect(Component, Clone, Default)]
6666
#[require(Transform)]
6767
pub struct Gizmo {

crates/bevy_light/src/atmosphere.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use bevy_ecs::{
88
lifecycle::HookContext,
99
message::MessageReader,
1010
system::{Res, ResMut},
11+
template::FromTemplate,
1112
world::DeferredWorld,
1213
};
1314
use bevy_image::Image;
@@ -28,8 +29,8 @@ use wgpu_types::TextureFormat;
2829
///
2930
/// The scale on [`GlobalTransform`] rescales the planet in world space. Tune it with the radius offset
3031
/// when your scene uses other units, like kilometer-sized scenes.
31-
#[derive(Clone, Component)]
32-
#[require(GlobalTransform::default())]
32+
#[derive(Clone, Component, FromTemplate)]
33+
#[require(GlobalTransform)]
3334
#[component(on_add = set_default_transform)]
3435
pub struct Atmosphere {
3536
/// Radius of the planet

crates/bevy_light/src/directional_light.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ impl DirectionalLight {
170170
/// Add to a [`DirectionalLight`] to add a light texture effect.
171171
/// A texture mask is applied to the light source to modulate its intensity,
172172
/// simulating patterns like window shadows, gobo/cookie effects, or soft falloffs.
173-
#[derive(Clone, Component, Debug, Reflect)]
173+
#[derive(Clone, Component, Debug, Reflect, FromTemplate)]
174174
#[reflect(Component, Debug)]
175175
#[require(DirectionalLight)]
176176
pub struct DirectionalLightTexture {

crates/bevy_light/src/point_light.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ impl PointLight {
156156
/// Add to a [`PointLight`] to add a light texture effect.
157157
/// A texture mask is applied to the light source to modulate its intensity,
158158
/// simulating patterns like window shadows, gobo/cookie effects, or soft falloffs.
159-
#[derive(Clone, Component, Debug, Reflect)]
159+
#[derive(Clone, Component, Debug, Reflect, FromTemplate)]
160160
#[reflect(Component, Debug)]
161161
#[require(PointLight)]
162162
pub struct PointLightTexture {

crates/bevy_light/src/probe.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ impl LightProbe {
101101
/// area in space.
102102
///
103103
/// See `bevy_pbr::environment_map` for detailed information.
104-
#[derive(Clone, Component, Reflect)]
104+
#[derive(Clone, Component, Reflect, FromTemplate)]
105105
#[reflect(Component, Default, Clone)]
106106
pub struct EnvironmentMapLight {
107107
/// The blurry image that represents diffuse radiance surrounding a region.
@@ -220,7 +220,7 @@ impl Default for EnvironmentMapLight {
220220
/// To do so, use [`EnvironmentMapLight`] alongside this component.
221221
///
222222
/// See also <https://en.wikipedia.org/wiki/Skybox_(video_games)>.
223-
#[derive(Component, Clone, Reflect)]
223+
#[derive(Component, Clone, Reflect, FromTemplate)]
224224
#[reflect(Component, Default, Clone)]
225225
pub struct Skybox {
226226
/// The cubemap to use.
@@ -249,7 +249,7 @@ impl Default for Skybox {
249249
/// A generated environment map that is filtered at runtime.
250250
///
251251
/// See `bevy_pbr::light_probe::generate` for detailed information.
252-
#[derive(Clone, Component, Reflect)]
252+
#[derive(Clone, Component, Reflect, FromTemplate)]
253253
#[reflect(Component, Default, Clone)]
254254
pub struct GeneratedEnvironmentMapLight {
255255
/// Source cubemap to be filtered on the GPU, size must be a power of two.
@@ -317,7 +317,7 @@ impl Default for AtmosphereEnvironmentMapLight {
317317
///
318318
/// This component requires the [`LightProbe`] component, and is typically used with
319319
/// [`bevy_transform::components::Transform`] to place the volume appropriately.
320-
#[derive(Clone, Reflect, Component, Debug)]
320+
#[derive(Clone, Reflect, Component, Debug, FromTemplate)]
321321
#[reflect(Component, Default, Debug, Clone)]
322322
#[require(LightProbe)]
323323
pub struct IrradianceVolume {

crates/bevy_light/src/spot_light.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ pub fn spot_light_clip_from_view(angle: f32, near_z: f32) -> Mat4 {
201201
/// Add to a [`SpotLight`] to add a light texture effect.
202202
/// A texture mask is applied to the light source to modulate its intensity,
203203
/// simulating patterns like window shadows, gobo/cookie effects, or soft falloffs.
204-
#[derive(Clone, Component, Debug, Reflect)]
204+
#[derive(Clone, Component, Debug, Reflect, FromTemplate)]
205205
#[reflect(Component, Debug)]
206206
#[require(SpotLight)]
207207
pub struct SpotLightTexture {

0 commit comments

Comments
 (0)