Resolve most remaining execution-order ambiguities (#6341)
# Objective Bevy's internal plugins have lots of execution-order ambiguities, which makes the ambiguity detection tool very noisy for our users. ## Solution Silence every last ambiguity that can currently be resolved. Each time an ambiguity is silenced, it is accompanied by a comment describing why it is correct. This description should be based on the public API of the respective systems. Thus, I have added documentation to some systems describing how they use some resources. # Future work Some ambiguities remain, due to issues out of scope for this PR. * The ambiguity checker does not respect `Without<>` filters, leading to false positives. * Ambiguities between `bevy_ui` and `bevy_animation` cannot be resolved, since neither crate knows that the other exists. We will need a general solution to this problem.
This commit is contained in:
parent
0934abc6bb
commit
456971381c
@ -160,7 +160,11 @@ impl Plugin for PbrPlugin {
|
|||||||
.label(SimulationLightSystems::UpdateLightFrusta)
|
.label(SimulationLightSystems::UpdateLightFrusta)
|
||||||
// This must run after CheckVisibility because it relies on ComputedVisibility::is_visible()
|
// This must run after CheckVisibility because it relies on ComputedVisibility::is_visible()
|
||||||
.after(VisibilitySystems::CheckVisibility)
|
.after(VisibilitySystems::CheckVisibility)
|
||||||
.after(TransformSystem::TransformPropagate),
|
.after(TransformSystem::TransformPropagate)
|
||||||
|
// We assume that no entity will be both a directional light and a spot light,
|
||||||
|
// so these systems will run indepdently of one another.
|
||||||
|
// FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
|
||||||
|
.ambiguous_with(update_spot_light_frusta),
|
||||||
)
|
)
|
||||||
.add_system_to_stage(
|
.add_system_to_stage(
|
||||||
CoreStage::PostUpdate,
|
CoreStage::PostUpdate,
|
||||||
|
|||||||
@ -1416,7 +1416,11 @@ pub fn update_directional_light_frusta(
|
|||||||
&mut Frustum,
|
&mut Frustum,
|
||||||
&ComputedVisibility,
|
&ComputedVisibility,
|
||||||
),
|
),
|
||||||
Or<(Changed<GlobalTransform>, Changed<DirectionalLight>)>,
|
(
|
||||||
|
Or<(Changed<GlobalTransform>, Changed<DirectionalLight>)>,
|
||||||
|
// Prevents this query from conflicting with camera queries.
|
||||||
|
Without<Camera>,
|
||||||
|
),
|
||||||
>,
|
>,
|
||||||
) {
|
) {
|
||||||
for (transform, directional_light, mut frustum, visibility) in &mut views {
|
for (transform, directional_light, mut frustum, visibility) in &mut views {
|
||||||
|
|||||||
@ -389,6 +389,11 @@ impl RenderTarget {
|
|||||||
/// the app, as well as the runtime-selected [`Projection`]. The system runs during the
|
/// the app, as well as the runtime-selected [`Projection`]. The system runs during the
|
||||||
/// [`CoreStage::PostUpdate`] stage.
|
/// [`CoreStage::PostUpdate`] stage.
|
||||||
///
|
///
|
||||||
|
/// ## World Resources
|
||||||
|
///
|
||||||
|
/// [`Res<Assets<Image>>`](Assets<Image>) -- For cameras that render to an image, this resource is used to
|
||||||
|
/// inspect information about the render target. This system will not access any other image assets.
|
||||||
|
///
|
||||||
/// [`OrthographicProjection`]: crate::camera::OrthographicProjection
|
/// [`OrthographicProjection`]: crate::camera::OrthographicProjection
|
||||||
/// [`PerspectiveProjection`]: crate::camera::PerspectiveProjection
|
/// [`PerspectiveProjection`]: crate::camera::PerspectiveProjection
|
||||||
/// [`Projection`]: crate::camera::Projection
|
/// [`Projection`]: crate::camera::Projection
|
||||||
|
|||||||
@ -19,6 +19,9 @@ impl<T: CameraProjection> Default for CameraProjectionPlugin<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Label for [`camera_system<T>`], shared accross all `T`.
|
||||||
|
///
|
||||||
|
/// [`camera_system<T>`]: crate::camera::camera_system
|
||||||
#[derive(SystemLabel, Clone, Eq, PartialEq, Hash, Debug)]
|
#[derive(SystemLabel, Clone, Eq, PartialEq, Hash, Debug)]
|
||||||
pub struct CameraUpdateSystem;
|
pub struct CameraUpdateSystem;
|
||||||
|
|
||||||
@ -27,13 +30,22 @@ impl<T: CameraProjection + Component + GetTypeRegistration> Plugin for CameraPro
|
|||||||
app.register_type::<T>()
|
app.register_type::<T>()
|
||||||
.add_startup_system_to_stage(
|
.add_startup_system_to_stage(
|
||||||
StartupStage::PostStartup,
|
StartupStage::PostStartup,
|
||||||
crate::camera::camera_system::<T>,
|
crate::camera::camera_system::<T>
|
||||||
|
.label(CameraUpdateSystem)
|
||||||
|
// We assume that each camera will only have one projection,
|
||||||
|
// so we can ignore ambiguities with all other monomorphizations.
|
||||||
|
// FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
|
||||||
|
.ambiguous_with(CameraUpdateSystem),
|
||||||
)
|
)
|
||||||
.add_system_to_stage(
|
.add_system_to_stage(
|
||||||
CoreStage::PostUpdate,
|
CoreStage::PostUpdate,
|
||||||
crate::camera::camera_system::<T>
|
crate::camera::camera_system::<T>
|
||||||
.label(CameraUpdateSystem)
|
.label(CameraUpdateSystem)
|
||||||
.after(ModifiesWindows),
|
.after(ModifiesWindows)
|
||||||
|
// We assume that each camera will only have one projection,
|
||||||
|
// so we can ignore ambiguities with all other monomorphizations.
|
||||||
|
// FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
|
||||||
|
.ambiguous_with(CameraUpdateSystem),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -194,14 +194,23 @@ impl Plugin for VisibilityPlugin {
|
|||||||
update_frusta::<OrthographicProjection>
|
update_frusta::<OrthographicProjection>
|
||||||
.label(UpdateOrthographicFrusta)
|
.label(UpdateOrthographicFrusta)
|
||||||
.after(camera_system::<OrthographicProjection>)
|
.after(camera_system::<OrthographicProjection>)
|
||||||
.after(TransformSystem::TransformPropagate),
|
.after(TransformSystem::TransformPropagate)
|
||||||
|
// We assume that no camera will have more than one projection component,
|
||||||
|
// so these systems will run independently of one another.
|
||||||
|
// FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
|
||||||
|
.ambiguous_with(update_frusta::<PerspectiveProjection>)
|
||||||
|
.ambiguous_with(update_frusta::<Projection>),
|
||||||
)
|
)
|
||||||
.add_system_to_stage(
|
.add_system_to_stage(
|
||||||
CoreStage::PostUpdate,
|
CoreStage::PostUpdate,
|
||||||
update_frusta::<PerspectiveProjection>
|
update_frusta::<PerspectiveProjection>
|
||||||
.label(UpdatePerspectiveFrusta)
|
.label(UpdatePerspectiveFrusta)
|
||||||
.after(camera_system::<PerspectiveProjection>)
|
.after(camera_system::<PerspectiveProjection>)
|
||||||
.after(TransformSystem::TransformPropagate),
|
.after(TransformSystem::TransformPropagate)
|
||||||
|
// We assume that no camera will have more than one projection component,
|
||||||
|
// so these systems will run independently of one another.
|
||||||
|
// FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
|
||||||
|
.ambiguous_with(update_frusta::<Projection>),
|
||||||
)
|
)
|
||||||
.add_system_to_stage(
|
.add_system_to_stage(
|
||||||
CoreStage::PostUpdate,
|
CoreStage::PostUpdate,
|
||||||
|
|||||||
@ -29,7 +29,7 @@ pub mod prelude {
|
|||||||
use bevy_app::prelude::*;
|
use bevy_app::prelude::*;
|
||||||
use bevy_asset::AddAsset;
|
use bevy_asset::AddAsset;
|
||||||
use bevy_ecs::{schedule::IntoSystemDescriptor, system::Resource};
|
use bevy_ecs::{schedule::IntoSystemDescriptor, system::Resource};
|
||||||
use bevy_render::{RenderApp, RenderStage};
|
use bevy_render::{camera::CameraUpdateSystem, RenderApp, RenderStage};
|
||||||
use bevy_sprite::SpriteSystem;
|
use bevy_sprite::SpriteSystem;
|
||||||
use bevy_window::ModifiesWindows;
|
use bevy_window::ModifiesWindows;
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
@ -80,7 +80,13 @@ impl Plugin for TextPlugin {
|
|||||||
.insert_resource(TextPipeline::default())
|
.insert_resource(TextPipeline::default())
|
||||||
.add_system_to_stage(
|
.add_system_to_stage(
|
||||||
CoreStage::PostUpdate,
|
CoreStage::PostUpdate,
|
||||||
update_text2d_layout.after(ModifiesWindows),
|
update_text2d_layout
|
||||||
|
.after(ModifiesWindows)
|
||||||
|
// Potential conflict: `Assets<Image>`
|
||||||
|
// In practice, they run independently since `bevy_render::camera_update_system`
|
||||||
|
// will only ever observe its own render target, and `update_text2d_layout`
|
||||||
|
// will never modify a pre-existing `Image` asset.
|
||||||
|
.ambiguous_with(CameraUpdateSystem),
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
|
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
|
||||||
|
|||||||
@ -145,6 +145,11 @@ pub fn extract_text2d_sprite(
|
|||||||
|
|
||||||
/// Updates the layout and size information whenever the text or style is changed.
|
/// Updates the layout and size information whenever the text or style is changed.
|
||||||
/// This information is computed by the `TextPipeline` on insertion, then stored.
|
/// This information is computed by the `TextPipeline` on insertion, then stored.
|
||||||
|
///
|
||||||
|
/// ## World Resources
|
||||||
|
///
|
||||||
|
/// [`ResMut<Assets<Image>>`](Assets<Image>) -- This system only adds new [`Image`] assets.
|
||||||
|
/// It does not modify or observe existing ones.
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn update_text2d_layout(
|
pub fn update_text2d_layout(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
|
|||||||
@ -12,7 +12,7 @@ pub mod entity;
|
|||||||
pub mod update;
|
pub mod update;
|
||||||
pub mod widget;
|
pub mod widget;
|
||||||
|
|
||||||
use bevy_render::extract_component::ExtractComponentPlugin;
|
use bevy_render::{camera::CameraUpdateSystem, extract_component::ExtractComponentPlugin};
|
||||||
pub use flex::*;
|
pub use flex::*;
|
||||||
pub use focus::*;
|
pub use focus::*;
|
||||||
pub use geometry::*;
|
pub use geometry::*;
|
||||||
@ -104,11 +104,27 @@ impl Plugin for UiPlugin {
|
|||||||
CoreStage::PostUpdate,
|
CoreStage::PostUpdate,
|
||||||
widget::text_system
|
widget::text_system
|
||||||
.before(UiSystem::Flex)
|
.before(UiSystem::Flex)
|
||||||
.after(ModifiesWindows),
|
.after(ModifiesWindows)
|
||||||
|
// Potential conflict: `Assets<Image>`
|
||||||
|
// In practice, they run independently since `bevy_render::camera_update_system`
|
||||||
|
// will only ever observe its own render target, and `widget::text_system`
|
||||||
|
// will never modify a pre-existing `Image` asset.
|
||||||
|
.ambiguous_with(CameraUpdateSystem)
|
||||||
|
// Potential conflict: `Assets<Image>`
|
||||||
|
// Since both systems will only ever insert new [`Image`] assets,
|
||||||
|
// they will never observe each other's effects.
|
||||||
|
.ambiguous_with(bevy_text::update_text2d_layout),
|
||||||
)
|
)
|
||||||
.add_system_to_stage(
|
.add_system_to_stage(
|
||||||
CoreStage::PostUpdate,
|
CoreStage::PostUpdate,
|
||||||
widget::image_node_system.before(UiSystem::Flex),
|
widget::image_node_system
|
||||||
|
.before(UiSystem::Flex)
|
||||||
|
// Potential conflicts: `Assets<Image>`
|
||||||
|
// They run independently since `widget::image_node_system` will only ever observe
|
||||||
|
// its own UiImage, and `widget::text_system` & `bevy_text::update_text2d_layout`
|
||||||
|
// will never modify a pre-existing `Image` asset.
|
||||||
|
.ambiguous_with(bevy_text::update_text2d_layout)
|
||||||
|
.ambiguous_with(widget::text_system),
|
||||||
)
|
)
|
||||||
.add_system_to_stage(
|
.add_system_to_stage(
|
||||||
CoreStage::PostUpdate,
|
CoreStage::PostUpdate,
|
||||||
|
|||||||
@ -2,12 +2,13 @@ use crate::{CalculatedSize, Size, UiImage, Val};
|
|||||||
use bevy_asset::Assets;
|
use bevy_asset::Assets;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
component::Component,
|
component::Component,
|
||||||
query::With,
|
query::{With, Without},
|
||||||
reflect::ReflectComponent,
|
reflect::ReflectComponent,
|
||||||
system::{Query, Res},
|
system::{Query, Res},
|
||||||
};
|
};
|
||||||
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
||||||
use bevy_render::texture::Image;
|
use bevy_render::texture::Image;
|
||||||
|
use bevy_text::Text;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// Describes how to resize the Image node
|
/// Describes how to resize the Image node
|
||||||
@ -22,7 +23,7 @@ pub enum ImageMode {
|
|||||||
/// Updates calculated size of the node based on the image provided
|
/// Updates calculated size of the node based on the image provided
|
||||||
pub fn image_node_system(
|
pub fn image_node_system(
|
||||||
textures: Res<Assets<Image>>,
|
textures: Res<Assets<Image>>,
|
||||||
mut query: Query<(&mut CalculatedSize, &UiImage), With<ImageMode>>,
|
mut query: Query<(&mut CalculatedSize, &UiImage), (With<ImageMode>, Without<Text>)>,
|
||||||
) {
|
) {
|
||||||
for (mut calculated_size, image) in &mut query {
|
for (mut calculated_size, image) in &mut query {
|
||||||
if let Some(texture) = textures.get(image) {
|
if let Some(texture) = textures.get(image) {
|
||||||
|
|||||||
@ -39,6 +39,11 @@ pub fn text_constraint(min_size: Val, size: Val, max_size: Val, scale_factor: f6
|
|||||||
|
|
||||||
/// Updates the layout and size information whenever the text or style is changed.
|
/// Updates the layout and size information whenever the text or style is changed.
|
||||||
/// This information is computed by the `TextPipeline` on insertion, then stored.
|
/// This information is computed by the `TextPipeline` on insertion, then stored.
|
||||||
|
///
|
||||||
|
/// ## World Resources
|
||||||
|
///
|
||||||
|
/// [`ResMut<Assets<Image>>`](Assets<Image>) -- This system only adds new [`Image`] assets.
|
||||||
|
/// It does not modify or observe existing ones.
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn text_system(
|
pub fn text_system(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user