Attempt to remove component from render world if not extracted.#15904
Attempt to remove component from render world if not extracted.#15904alice-i-cecile merged 3 commits intobevyengine:mainfrom
Conversation
alice-i-cecile
left a comment
There was a problem hiding this comment.
I like this fix! Simple and relatively robust.
|
Does this fully fix #15871? |
8f57da9 to
9ec9c7b
Compare
Only the ones that implement |
| if let Some(component) = C::extract_component(query_item) { | ||
| values.push((entity, component)); | ||
| } else { | ||
| commands.entity(entity).remove::<C>(); |
There was a problem hiding this comment.
@alice-i-cecile What is the behavior of remove() when the entity lacks the component already? No-op, or panic?
The docs don't say: https://dev-docs.bevyengine.org/bevy_ecs/system/commands/struct.EntityCommands.html#method.remove
IceSentry
left a comment
There was a problem hiding this comment.
I think this behaviour should be documented on the ExtractComponent trait
| if let Some(component) = C::extract_component(query_item) { | ||
| values.push((entity, component)); | ||
| } else { | ||
| commands.entity(entity).remove::<C>(); |
There was a problem hiding this comment.
C: ExtractComponent inserts C::Out instead of C so this might need to be remove::<C::Out>.
There was a problem hiding this comment.
Gosh duh. In many cases they're the same but good catch.
# Objective - `C: ExtractComponent` inserts `C::Out` instead of `C`, so we need to remove `C::Out`. cc #15904. ## Solution - `C` -> `C::Out` ## Testing - CAS has `<ContrastAdaptiveSharpening as ExtractComponent>::Out = (DenoiseCas, CasUniform)`. Setting its strength to zero correctly removes the effect after this change.
# Objective - Fixes #15871 (Camera is done in #15946) ## Solution - Do the same as #15904 for other extraction systems - Added missing `SyncComponentPlugin` for DOF, TAA, and SSAO (According to the [documentation](https://dev-docs.bevyengine.org/bevy/render/sync_component/struct.SyncComponentPlugin.html), this plugin "needs to be added for manual extraction implementations." We may need to check this is done.) ## Testing Modified example locally to add toggles if not exist. - [x] DOF - toggling DOF component and perspective in `depth_of_field` example - [x] TAA - toggling `Camera.is_active` and TAA component - [x] clusters - not entirely sure, toggling `Camera.is_active` in `many_lights` example (no crash/glitch even without this PR) - [x] previous_view - toggling `Camera.is_active` in `skybox` (no crash/glitch even without this PR) - [x] lights - toggling `Visibility` of `DirectionalLight` in `lighting` example - [x] SSAO - toggling `Camera.is_active` and SSAO component in `ssao` example - [x] default UI camera view - toggling `Camera.is_active` (nop without #15946 because UI defaults to some camera even if `DefaultCameraView` is not there) - [x] volumetric fog - toggling existence of volumetric light. Looks like optimization, no change in behavior/visuals
Objective
Ensure that components that are conditionally extracted do not linger in the render world when not extracted from the main world.
Solution
If the
ExtractComponentreturnsNone, we'll remove the render world component. I think this is the most sensible behavior here. In the future if there really is a use case for keeping the previous render component around, we could add aOption<Self::Out>parameter for the previous render component to the method, or something similar. I think that this follows the principle of least surprise here relative to whatNonewould suggest and the way that render nodes are typically written. The alternative would be to add anenabledfield to pretty much every camera settings component, or duplicate the extraction condition as #15856 does.Testing
transmissionno longer crashes.Migration Guide
Components that implement
ExtractComponentand returnNonewill cause the extracted component to be removed from the render world.