Skip to content

Commit 5c36ecf

Browse files
authored
Re-add Out to ExtractComponent (#23334)
# Objective Fixes #22863. Fixes #22999. Fixes #23142. ## Solution 1. Re-add `Out` type to `ExtractComponent`. Rename `SyncComponent::Out` to `SyncComponent::Target`, which is used to clean up components when removing, so that the output of extraction can be different from `SyncComponent::Target`. 2. Add `#[extract_component_sync_target]` attribute for `#[derive(ExtractComponent)]` to specify `SyncComponent::Target`. ## Testing Tested `ssr` and `order_independent_transparency` examples. There may be other places where derived components need to be cleaned up, but finding them is somewhat challenging.
1 parent 61a294d commit 5c36ecf

26 files changed

Lines changed: 109 additions & 77 deletions

File tree

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
---
22
title: "`ExtractComponent` refactor"
3-
pull_requests: [22766]
3+
pull_requests: [22766, 23334]
44
---
55

6-
The `Out` type from `ExtractComponent` has been split into a separate `SyncComponent` trait.
6+
Previously, `SyncComponentPlugin`/`ExtractComponentPlugin` would despawn the render entity thus removing all the derived components if the component was removed. Now the render entity is no longer despawned and only the `Target` components of `SyncComponent` trait are removed.
77

8-
Both traits have also gotten an optional marker type that can be used to bypass orphan rules, see the docs for details.
8+
`SyncComponent` is a subtrait of `ExtractComponent` and you must implement it to clean up extracted and derived components.
99

1010
```rust,ignore
11+
impl SyncComponent for MyComponent {
12+
type Target = (Self, OtherDerivedComponents);
13+
}
14+
1115
impl ExtractComponent for MyComponent {
1216
type QueryData = ();
1317
type QueryFilter = ();
@@ -21,21 +25,12 @@ impl ExtractComponent for MyComponent {
2125
}
2226
```
2327

24-
After:
28+
You can also specify the sync target (default to `Self`) using `extract_component_sync_target` attribute in derive macros.
2529

2630
```rust,ignore
27-
impl SyncComponent for MyComponent {
28-
type Out = Self;
29-
}
30-
31-
impl ExtractComponent for MyComponent {
32-
type QueryData = ();
33-
type QueryFilter = ();
34-
35-
fn extract_component(
36-
item: QueryItem<'_, '_, Self::QueryData>,
37-
) -> Option<Self::Out> {
38-
Some(*item)
39-
}
40-
}
31+
#[derive(Component, ExtractComponent)]
32+
#[extract_component_sync_target((Self, OtherDerivedComponents))]
33+
struct MyComponent;
4134
```
35+
36+
Both `SyncComponent` and `ExtractComponent` have also gotten an optional marker type that can be used to bypass orphan rules, see the docs for details.

crates/bevy_anti_alias/src/contrast_adaptive_sharpening/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,13 @@ pub struct CasUniform {
7777
}
7878

7979
impl SyncComponent for ContrastAdaptiveSharpening {
80-
type Out = (DenoiseCas, CasUniform);
80+
type Target = (DenoiseCas, CasUniform);
8181
}
8282

8383
impl ExtractComponent for ContrastAdaptiveSharpening {
8484
type QueryData = &'static Self;
8585
type QueryFilter = With<Camera>;
86+
type Out = (DenoiseCas, CasUniform);
8687

8788
fn extract_component(item: QueryItem<Self::QueryData>) -> Option<Self::Out> {
8889
if !item.enabled || item.sharpening_strength == 0.0 {

crates/bevy_anti_alias/src/smaa/mod.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ use bevy_derive::{Deref, DerefMut};
4141
use bevy_ecs::{
4242
component::Component,
4343
entity::Entity,
44-
lifecycle::Remove,
45-
observer::On,
4644
query::With,
4745
reflect::ReflectComponent,
4846
resource::Resource,
@@ -85,6 +83,13 @@ pub struct SmaaPlugin;
8583
/// for a [`bevy_camera::Camera`].
8684
#[derive(Clone, Copy, Default, Component, Reflect, ExtractComponent)]
8785
#[reflect(Component, Default, Clone)]
86+
#[extract_component_sync_target((
87+
Self,
88+
SmaaTextures,
89+
SmaaPipelines,
90+
SmaaBindGroups,
91+
ViewSmaaPipelines,
92+
))]
8893
#[doc(alias = "SubpixelMorphologicalAntiAliasing")]
8994
pub struct Smaa {
9095
/// A predefined set of SMAA parameters: i.e. a quality level.
@@ -331,17 +336,6 @@ impl Plugin for SmaaPlugin {
331336
return;
332337
};
333338

334-
// TODO: remove this manual cleanup when ExtractComponent gets support
335-
// for cleanup of derived components
336-
render_app.add_observer(|event: On<Remove, Smaa>, mut commands: Commands| {
337-
commands.entity(event.entity).remove::<(
338-
SmaaTextures,
339-
SmaaPipelines,
340-
SmaaBindGroups,
341-
ViewSmaaPipelines,
342-
)>();
343-
});
344-
345339
render_app
346340
.insert_resource(smaa_luts)
347341
.init_resource::<SmaaSpecializedRenderPipelines>()

crates/bevy_anti_alias/src/taa/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ impl Default for TemporalAntiAliasing {
130130
}
131131

132132
impl SyncComponent for TemporalAntiAliasing {
133-
type Out = Self;
133+
type Target = Self;
134134
}
135135

136136
fn temporal_anti_alias(

crates/bevy_core_pipeline/src/oit/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use resolve::OitResolvePlugin;
2323

2424
use crate::{
2525
core_3d::main_transparent_pass_3d,
26-
oit::resolve::node::oit_resolve,
26+
oit::resolve::{node::oit_resolve, OitResolvePipelineId},
2727
schedule::{Core3d, Core3dSystems},
2828
};
2929

@@ -37,6 +37,7 @@ pub mod resolve;
3737
// This should probably be done by adding an enum to this component.
3838
// We use the same struct to pass on the settings to the drawing shader.
3939
#[derive(Clone, Copy, ExtractComponent, Reflect, ShaderType, Component)]
40+
#[extract_component_sync_target((Self, OrderIndependentTransparencySettingsOffset, OitResolvePipelineId))]
4041
#[reflect(Clone, Default)]
4142
pub struct OrderIndependentTransparencySettings {
4243
/// Controls how many fragments will be exactly sorted.

crates/bevy_core_pipeline/src/prepass/background_motion_vectors.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,13 @@ use crate::{
5656
pub struct NoBackgroundMotionVectors;
5757

5858
impl SyncComponent for NoBackgroundMotionVectors {
59-
type Out = Self;
59+
type Target = Self;
6060
}
6161

6262
impl ExtractComponent for NoBackgroundMotionVectors {
6363
type QueryData = Read<NoBackgroundMotionVectors>;
6464
type QueryFilter = ();
65+
type Out = Self;
6566

6667
fn extract_component(_item: QueryItem<'_, '_, Self::QueryData>) -> Option<Self::Out> {
6768
Some(NoBackgroundMotionVectors)

crates/bevy_pbr/src/atmosphere/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,12 +373,13 @@ impl From<AtmosphereSettings> for GpuAtmosphereSettings {
373373
}
374374

375375
impl SyncComponent for GpuAtmosphereSettings {
376-
type Out = Self;
376+
type Target = Self;
377377
}
378378

379379
impl ExtractComponent for GpuAtmosphereSettings {
380380
type QueryData = Read<AtmosphereSettings>;
381381
type QueryFilter = (With<Camera3d>, With<Atmosphere>);
382+
type Out = Self;
382383

383384
fn extract_component(item: QueryItem<'_, '_, Self::QueryData>) -> Option<Self::Out> {
384385
Some(item.clone().into())

crates/bevy_pbr/src/contact_shadows.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,13 @@ impl From<ContactShadows> for ContactShadowsUniform {
8181
}
8282

8383
impl SyncComponent for ContactShadows {
84-
type Out = Self;
84+
type Target = Self;
8585
}
8686

8787
impl ExtractComponent for ContactShadows {
8888
type QueryData = &'static ContactShadows;
8989
type QueryFilter = ();
90+
type Out = Self;
9091

9192
fn extract_component(settings: QueryItem<'_, '_, Self::QueryData>) -> Option<Self::Out> {
9293
Some(*settings)

crates/bevy_pbr/src/decal/clustered.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ impl Plugin for ClusteredDecalPlugin {
185185
}
186186

187187
impl SyncComponent<ClusteredDecalPlugin> for ClusteredDecal {
188-
type Out = Self;
188+
type Target = Self;
189189
}
190190

191191
// This is needed because of the orphan rule not allowing implementing

crates/bevy_pbr/src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -381,17 +381,17 @@ pub fn stbn_placeholder() -> Image {
381381
}
382382

383383
impl SyncComponent<PbrPlugin> for DirectionalLight {
384-
type Out = Self;
384+
type Target = Self;
385385
}
386386
impl SyncComponent<PbrPlugin> for PointLight {
387-
type Out = Self;
387+
type Target = Self;
388388
}
389389
impl SyncComponent<PbrPlugin> for SpotLight {
390-
type Out = Self;
390+
type Target = Self;
391391
}
392392
impl SyncComponent<PbrPlugin> for AmbientLight {
393-
type Out = Self;
393+
type Target = Self;
394394
}
395395
impl SyncComponent<PbrPlugin> for ShadowFilteringMethod {
396-
type Out = Self;
396+
type Target = Self;
397397
}

0 commit comments

Comments
 (0)