From c222fc5af95b1b0b6386beab2ec3a1466b62f88d Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Fri, 1 Aug 2025 00:33:58 +0100 Subject: [PATCH 01/18] use the hierarchy propagation plugin to propagate ComputedNodeTarget --- crates/bevy_ui/src/lib.rs | 5 ++- crates/bevy_ui/src/update.rs | 85 ++++++++++++++++++++---------------- 2 files changed, 50 insertions(+), 40 deletions(-) diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index d3f9cbd279016..24b422450c756 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -70,7 +70,7 @@ pub mod prelude { }; } -use bevy_app::{prelude::*, AnimationSystems}; +use bevy_app::{prelude::*, AnimationSystems, HierarchyPropagatePlugin}; use bevy_ecs::prelude::*; use bevy_input::InputSystems; use bevy_render::camera::CameraUpdateSystems; @@ -182,6 +182,8 @@ impl Plugin for UiPlugin { ) .chain(), ) + .add_plugins(HierarchyPropagatePlugin::::default()) + .add_systems(Update, update_ui_context_system) .add_systems( PreUpdate, ui_focus_system.in_set(UiSystems::Focus).after(InputSystems), @@ -206,7 +208,6 @@ impl Plugin for UiPlugin { app.add_systems( PostUpdate, ( - update_ui_context_system.in_set(UiSystems::Prepare), ui_layout_system_config, ui_stack_system .in_set(UiSystems::Stack) diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index 313b4af192f46..cbe9582b494f0 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -8,6 +8,7 @@ use crate::{ }; use super::ComputedNode; +use bevy_app::Propagate; use bevy_ecs::{ change_detection::DetectChangesMut, entity::Entity, @@ -135,14 +136,15 @@ fn update_clipping( } pub fn update_ui_context_system( + mut commands: Commands, default_ui_camera: DefaultUiCamera, ui_scale: Res, camera_query: Query<&Camera>, target_camera_query: Query<&UiTargetCamera>, ui_root_nodes: UiRootNodes, - mut computed_target_query: Query<&mut ComputedNodeTarget>, - ui_children: UiChildren, - reparented_nodes: Query<(Entity, &ChildOf), (Changed, With)>, + // mut computed_target_query: Query<&mut ComputedNodeTarget>, + // ui_children: UiChildren, + // reparented_nodes: Query<(Entity, &ChildOf), (Changed, With)>, ) { let default_camera_entity = default_ui_camera.get(); @@ -165,48 +167,55 @@ pub fn update_ui_context_system( }) .unwrap_or((1., UVec2::ZERO)); - update_contexts_recursively( - root_entity, - ComputedNodeTarget { + // update_contexts_recursively( + // root_entity, + // ComputedNodeTarget { + // camera, + // scale_factor, + // physical_size, + // }, + // &ui_children, + // &mut computed_target_query, + // ); + commands + .entity(root_entity) + .insert(Propagate(ComputedNodeTarget { camera, scale_factor, physical_size, - }, - &ui_children, - &mut computed_target_query, - ); + })); } - for (entity, child_of) in reparented_nodes.iter() { - let Ok(computed_target) = computed_target_query.get(child_of.parent()) else { - continue; - }; - - update_contexts_recursively( - entity, - *computed_target, - &ui_children, - &mut computed_target_query, - ); - } + // for (entity, child_of) in reparented_nodes.iter() { + // let Ok(computed_target) = computed_target_query.get(child_of.parent()) else { + // continue; + // }; + + // update_contexts_recursively( + // entity, + // *computed_target, + // &ui_children, + // &mut computed_target_query, + // ); + // } } -fn update_contexts_recursively( - entity: Entity, - inherited_computed_target: ComputedNodeTarget, - ui_children: &UiChildren, - query: &mut Query<&mut ComputedNodeTarget>, -) { - if query - .get_mut(entity) - .map(|mut computed_target| computed_target.set_if_neq(inherited_computed_target)) - .unwrap_or(false) - { - for child in ui_children.iter_ui_children(entity) { - update_contexts_recursively(child, inherited_computed_target, ui_children, query); - } - } -} +// fn update_contexts_recursively( +// entity: Entity, +// inherited_computed_target: ComputedNodeTarget, +// ui_children: &UiChildren, +// query: &mut Query<&mut ComputedNodeTarget>, +// ) { +// if query +// .get_mut(entity) +// .map(|mut computed_target| computed_target.set_if_neq(inherited_computed_target)) +// .unwrap_or(false) +// { +// for child in ui_children.iter_ui_children(entity) { +// update_contexts_recursively(child, inherited_computed_target, ui_children, query); +// } +// } +// } #[cfg(test)] mod tests { From af189159076a0f12bc7f405802f01e99dde184a8 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Tue, 5 Aug 2025 21:53:31 +0100 Subject: [PATCH 02/18] Clean up --- crates/bevy_ui/src/update.rs | 43 ------------------------------------ 1 file changed, 43 deletions(-) diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index cbe9582b494f0..7a984f4e08c53 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -142,9 +142,6 @@ pub fn update_ui_context_system( camera_query: Query<&Camera>, target_camera_query: Query<&UiTargetCamera>, ui_root_nodes: UiRootNodes, - // mut computed_target_query: Query<&mut ComputedNodeTarget>, - // ui_children: UiChildren, - // reparented_nodes: Query<(Entity, &ChildOf), (Changed, With)>, ) { let default_camera_entity = default_ui_camera.get(); @@ -167,16 +164,6 @@ pub fn update_ui_context_system( }) .unwrap_or((1., UVec2::ZERO)); - // update_contexts_recursively( - // root_entity, - // ComputedNodeTarget { - // camera, - // scale_factor, - // physical_size, - // }, - // &ui_children, - // &mut computed_target_query, - // ); commands .entity(root_entity) .insert(Propagate(ComputedNodeTarget { @@ -185,38 +172,8 @@ pub fn update_ui_context_system( physical_size, })); } - - // for (entity, child_of) in reparented_nodes.iter() { - // let Ok(computed_target) = computed_target_query.get(child_of.parent()) else { - // continue; - // }; - - // update_contexts_recursively( - // entity, - // *computed_target, - // &ui_children, - // &mut computed_target_query, - // ); - // } } -// fn update_contexts_recursively( -// entity: Entity, -// inherited_computed_target: ComputedNodeTarget, -// ui_children: &UiChildren, -// query: &mut Query<&mut ComputedNodeTarget>, -// ) { -// if query -// .get_mut(entity) -// .map(|mut computed_target| computed_target.set_if_neq(inherited_computed_target)) -// .unwrap_or(false) -// { -// for child in ui_children.iter_ui_children(entity) { -// update_contexts_recursively(child, inherited_computed_target, ui_children, query); -// } -// } -// } - #[cfg(test)] mod tests { use bevy_asset::AssetEvent; From 404aff5a41d3ecc9b0d9ab1488c569f3a455f96f Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Tue, 5 Aug 2025 21:54:34 +0100 Subject: [PATCH 03/18] Removed unused imports --- crates/bevy_ui/src/update.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index 7a984f4e08c53..45117942c6213 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -10,10 +10,8 @@ use crate::{ use super::ComputedNode; use bevy_app::Propagate; use bevy_ecs::{ - change_detection::DetectChangesMut, entity::Entity, - hierarchy::ChildOf, - query::{Changed, Has, With}, + query::Has, system::{Commands, Query, Res}, }; use bevy_math::{Rect, UVec2}; From d5ecbb66afe950b42b0656567a333e4363309f8b Mon Sep 17 00:00:00 2001 From: Tim Blackbird Date: Tue, 5 Aug 2025 23:24:53 +0200 Subject: [PATCH 04/18] Make `HierarchyPropagatePlugin` scheduling configurable --- crates/bevy_app/src/propagate.rs | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/crates/bevy_app/src/propagate.rs b/crates/bevy_app/src/propagate.rs index d851f0dd38402..fd132251bf639 100644 --- a/crates/bevy_app/src/propagate.rs +++ b/crates/bevy_app/src/propagate.rs @@ -8,10 +8,11 @@ use bevy_ecs::{ component::Component, entity::Entity, hierarchy::ChildOf, + intern::Interned, lifecycle::RemovedComponents, query::{Changed, Or, QueryFilter, With, Without}, relationship::{Relationship, RelationshipTarget}, - schedule::{IntoScheduleConfigs, SystemSet}, + schedule::{IntoScheduleConfigs, ScheduleLabel, SystemSet}, system::{Commands, Local, Query}, }; #[cfg(feature = "bevy_reflect")] @@ -33,7 +34,8 @@ use bevy_reflect::Reflect; /// Individual entities can be skipped or terminate the propagation with the [`PropagateOver`] /// and [`PropagateStop`] components. /// -/// Propagation occurs during [`Update`] in the [`PropagateSet`] system set. +/// By default the propagation occurs during [`Update`] schedule in the [`PropagateSet`] system set. +/// The schedule can be configured via [`HierarchyPropagatePlugin::new`]. /// You should be sure to schedule your logic relative to this set: making changes /// that modify component values before this logic, and reading the propagated /// values after it. @@ -41,7 +43,22 @@ pub struct HierarchyPropagatePlugin< C: Component + Clone + PartialEq, F: QueryFilter = (), R: Relationship = ChildOf, ->(PhantomData (C, F, R)>); +> { + schedule: Interned, + _marker: PhantomData (C, F, R)>, +} + +impl + HierarchyPropagatePlugin +{ + /// Construct the plugin. The propagation systems will be placed in the specified schedule. + pub fn new(schedule: impl ScheduleLabel) -> Self { + Self { + schedule: schedule.intern(), + _marker: PhantomData, + } + } +} /// Causes the inner component to be added to this entity and all direct and transient relationship /// targets. A target with a [`Propagate`] component of its own will override propagation from @@ -84,7 +101,10 @@ impl Default for HierarchyPropagatePlugin { fn default() -> Self { - Self(Default::default()) + Self { + schedule: Update.intern(), + _marker: PhantomData, + } } } @@ -129,7 +149,7 @@ impl, update_stopped::, From fb65108f36b3da48cff8c297c124554e92050ea8 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Tue, 5 Aug 2025 22:59:07 +0100 Subject: [PATCH 05/18] Use modified Hierarchy plugin with configurable schedule --- crates/bevy_ui/src/lib.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index 24b422450c756..52c2a3550603c 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -70,7 +70,7 @@ pub mod prelude { }; } -use bevy_app::{prelude::*, AnimationSystems, HierarchyPropagatePlugin}; +use bevy_app::{prelude::*, AnimationSystems, HierarchyPropagatePlugin, PropagateSet}; use bevy_ecs::prelude::*; use bevy_input::InputSystems; use bevy_render::camera::CameraUpdateSystems; @@ -182,8 +182,17 @@ impl Plugin for UiPlugin { ) .chain(), ) - .add_plugins(HierarchyPropagatePlugin::::default()) - .add_systems(Update, update_ui_context_system) + .configure_sets( + PostUpdate, + PropagateSet::::default().before(UiSystems::Content), + ) + .add_plugins(HierarchyPropagatePlugin::::new( + PostUpdate, + )) + .add_systems( + Update, + update_ui_context_system.before(PropagateSet::::default()), + ) .add_systems( PreUpdate, ui_focus_system.in_set(UiSystems::Focus).after(InputSystems), @@ -208,6 +217,7 @@ impl Plugin for UiPlugin { app.add_systems( PostUpdate, ( + update_ui_context_system.in_set(UiSystems::Prepare), ui_layout_system_config, ui_stack_system .in_set(UiSystems::Stack) From 0e7732ee792ce9d49b1b46cf4dffafe07110c4c2 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Wed, 6 Aug 2025 15:00:02 +0100 Subject: [PATCH 06/18] Moved `update_ui_context_system` to PostUpdate --- crates/bevy_ui/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index 52c2a3550603c..23968d837c6de 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -190,7 +190,7 @@ impl Plugin for UiPlugin { PostUpdate, )) .add_systems( - Update, + PostUpdate, update_ui_context_system.before(PropagateSet::::default()), ) .add_systems( From f1976cd28975f1ae37a8f95f9a96613de99a753b Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Wed, 6 Aug 2025 15:18:21 +0100 Subject: [PATCH 07/18] Use a test app not a test world for the UI tests so the hierarchy plugin can be added to the app. --- crates/bevy_ui/src/layout/mod.rs | 66 ++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index 14c468e157016..f9a74d1fe1546 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -352,6 +352,7 @@ pub fn ui_layout_system( #[cfg(test)] mod tests { + use bevy_app::{App, HierarchyPropagatePlugin, PostUpdate, PropagateSet}; use taffy::TraversePartialTree; use bevy_asset::{AssetEvent, Assets}; @@ -368,6 +369,7 @@ mod tests { PrimaryWindow, Window, WindowCreated, WindowResized, WindowResolution, WindowScaleFactorChanged, }; + //use uuid::timestamp::UUID_TICKS_BETWEEN_EPOCHS; use crate::{ layout::ui_surface::UiSurface, prelude::*, ui_layout_system, @@ -378,6 +380,61 @@ mod tests { const WINDOW_WIDTH: f32 = 1000.; const WINDOW_HEIGHT: f32 = 100.; + fn setup_ui_test_app() -> App { + let mut app = App::new(); + + app.add_plugins(HierarchyPropagatePlugin::::new( + PostUpdate, + )); + app.init_resource::(); + app.init_resource::(); + app.init_resource::>(); + app.init_resource::>(); + // Required for the camera system + app.init_resource::>(); + app.init_resource::>>(); + app.init_resource::>(); + app.init_resource::(); + app.init_resource::(); + app.init_resource::(); + app.init_resource::(); + + app.add_systems( + PostUpdate, + ( + // UI is driven by calculated camera target info, so we need to run the camera system first + bevy_render::camera::camera_system, + update_ui_context_system, + ApplyDeferred, + ui_layout_system, + mark_dirty_trees, + sync_simple_transforms, + propagate_parent_transforms, + ) + .chain(), + ); + + app.configure_sets( + PostUpdate, + PropagateSet::::default() + .after(update_ui_context_system) + .before(ui_layout_system), + ); + + let world = app.world_mut(); + // spawn a dummy primary window and camera + world.spawn(( + Window { + resolution: WindowResolution::new(WINDOW_WIDTH, WINDOW_HEIGHT), + ..default() + }, + PrimaryWindow, + )); + world.spawn(Camera2d); + + app + } + fn setup_ui_test_world() -> (World, Schedule) { let mut world = World::new(); world.init_resource::(); @@ -426,7 +483,9 @@ mod tests { #[test] fn ui_nodes_with_percent_100_dimensions_should_fill_their_parent() { - let (mut world, mut ui_schedule) = setup_ui_test_world(); + let mut app = setup_ui_test_app(); + + let world = app.world_mut(); // spawn a root entity with width and height set to fill 100% of its parent let ui_root = world @@ -447,8 +506,9 @@ mod tests { world.entity_mut(ui_root).add_child(ui_child); - ui_schedule.run(&mut world); - let mut ui_surface = world.resource_mut::(); + app.update(); + + let mut ui_surface = app.world_mut().resource_mut::(); for ui_entity in [ui_root, ui_child] { let layout = ui_surface.get_layout(ui_entity, true).unwrap().0; From 09753614dc829e7267da23b8a2b5fd6144e89232 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Wed, 6 Aug 2025 15:20:00 +0100 Subject: [PATCH 08/18] Updated ui_surface_tracks_ui_entities test to use app. --- crates/bevy_ui/src/layout/mod.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index f9a74d1fe1546..17f864ae7cc9a 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -519,18 +519,17 @@ mod tests { #[test] fn ui_surface_tracks_ui_entities() { - let (mut world, mut ui_schedule) = setup_ui_test_world(); - - ui_schedule.run(&mut world); + let mut app = setup_ui_test_app(); + let world = app.world_mut(); // no UI entities in world, none in UiSurface let ui_surface = world.resource::(); assert!(ui_surface.entity_to_taffy.is_empty()); let ui_entity = world.spawn(Node::default()).id(); - // `ui_layout_system` should map `ui_entity` to a ui node in `UiSurface::entity_to_taffy` - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); let ui_surface = world.resource::(); assert!(ui_surface.entity_to_taffy.contains_key(&ui_entity)); @@ -538,8 +537,8 @@ mod tests { world.despawn(ui_entity); - // `ui_layout_system` should remove `ui_entity` from `UiSurface::entity_to_taffy` - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); let ui_surface = world.resource::(); assert!(!ui_surface.entity_to_taffy.contains_key(&ui_entity)); From e31f10843e1aba2216cd7dbc3332de87033d8aa5 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Wed, 6 Aug 2025 15:33:30 +0100 Subject: [PATCH 09/18] Updated remaining tests --- crates/bevy_ui/src/layout/mod.rs | 166 ++++++++++++++++++++----------- 1 file changed, 106 insertions(+), 60 deletions(-) diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index 17f864ae7cc9a..510b6dba1d0c1 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -548,12 +548,14 @@ mod tests { #[test] #[should_panic] fn despawning_a_ui_entity_should_remove_its_corresponding_ui_node() { - let (mut world, mut ui_schedule) = setup_ui_test_world(); + let mut app = setup_ui_test_app(); + let world = app.world_mut(); let ui_entity = world.spawn(Node::default()).id(); // `ui_layout_system` will insert a ui node into the internal layout tree corresponding to `ui_entity` - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); // retrieve the ui node corresponding to `ui_entity` from ui surface let ui_surface = world.resource::(); @@ -563,7 +565,8 @@ mod tests { // `ui_layout_system` will receive a `RemovedComponents` event for `ui_entity` // and remove `ui_entity` from `ui_node` from the internal layout tree - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); let ui_surface = world.resource::(); @@ -573,12 +576,14 @@ mod tests { #[test] fn changes_to_children_of_a_ui_entity_change_its_corresponding_ui_nodes_children() { - let (mut world, mut ui_schedule) = setup_ui_test_world(); + let mut app = setup_ui_test_app(); + let world = app.world_mut(); let ui_parent_entity = world.spawn(Node::default()).id(); // `ui_layout_system` will insert a ui node into the internal layout tree corresponding to `ui_entity` - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); let ui_surface = world.resource::(); let ui_parent_node = ui_surface.entity_to_taffy[&ui_parent_entity]; @@ -594,7 +599,8 @@ mod tests { }) .collect::>(); - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); // `ui_parent_node` should have children now let ui_surface = world.resource::(); @@ -626,7 +632,8 @@ mod tests { deleted_children.push(child); } - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); let ui_surface = world.resource::(); assert_eq!( @@ -669,7 +676,8 @@ mod tests { // despawn the parent entity and its descendants world.entity_mut(ui_parent_entity).despawn(); - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); // all nodes should have been deleted let ui_surface = world.resource::(); @@ -679,9 +687,10 @@ mod tests { /// bugfix test, see [#16288](https://github.com/bevyengine/bevy/pull/16288) #[test] fn node_removal_and_reinsert_should_work() { - let (mut world, mut ui_schedule) = setup_ui_test_world(); + let mut app = setup_ui_test_app(); - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); // no UI entities in world, none in UiSurface let ui_surface = world.resource::(); @@ -690,7 +699,8 @@ mod tests { let ui_entity = world.spawn(Node::default()).id(); // `ui_layout_system` should map `ui_entity` to a ui node in `UiSurface::entity_to_taffy` - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); let ui_surface = world.resource::(); assert!(ui_surface.entity_to_taffy.contains_key(&ui_entity)); @@ -701,7 +711,8 @@ mod tests { world.entity_mut(ui_entity).insert(Node::default()); // `ui_layout_system` should still have `ui_entity` - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); let ui_surface = world.resource::(); assert!(ui_surface.entity_to_taffy.contains_key(&ui_entity)); @@ -710,17 +721,20 @@ mod tests { #[test] fn node_addition_should_sync_children() { - let (mut world, mut ui_schedule) = setup_ui_test_world(); + let mut app = setup_ui_test_app(); + let world = app.world_mut(); // spawn an invalid UI root node let root_node = world.spawn(()).with_child(Node::default()).id(); - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); // fix the invalid root node by inserting a Node world.entity_mut(root_node).insert(Node::default()); - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); let ui_surface = world.resource_mut::(); let taffy_root = ui_surface.entity_to_taffy[&root_node]; @@ -731,19 +745,22 @@ mod tests { #[test] fn node_addition_should_sync_parent_and_children() { - let (mut world, mut ui_schedule) = setup_ui_test_world(); + let mut app = setup_ui_test_app(); + let world = app.world_mut(); let d = world.spawn(Node::default()).id(); let c = world.spawn(()).add_child(d).id(); let b = world.spawn(Node::default()).id(); let a = world.spawn(Node::default()).add_children(&[b, c]).id(); - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); // fix the invalid middle node by inserting a Node world.entity_mut(c).insert(Node::default()); - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); let ui_surface = world.resource::(); for (entity, n) in [(a, 2), (b, 0), (c, 1), (d, 0)] { @@ -757,7 +774,8 @@ mod tests { /// without explicitly declaring it. #[test] fn ui_root_node_should_act_like_position_absolute() { - let (mut world, mut ui_schedule) = setup_ui_test_world(); + let mut app = setup_ui_test_app(); + let world = app.world_mut(); let mut size = 150.; @@ -787,7 +805,8 @@ mod tests { ..default() }); - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); let overlap_check = world .query_filtered::<(Entity, &ComputedNode, &UiGlobalTransform), Without>() @@ -879,14 +898,11 @@ mod tests { } } - fn do_move_and_test( - world: &mut World, - ui_schedule: &mut Schedule, - new_pos: Vec2, - expected_camera_entity: &Entity, - ) { + fn do_move_and_test(app: &mut App, new_pos: Vec2, expected_camera_entity: &Entity) { + let world = app.world_mut(); world.run_system_once_with(move_ui_node, new_pos).unwrap(); - ui_schedule.run(world); + app.update(); + let world = app.world_mut(); let (ui_node_entity, UiTargetCamera(target_camera_entity)) = world .query_filtered::<(Entity, &UiTargetCamera), With>() .single(world) @@ -907,7 +923,8 @@ mod tests { world.resource::().taffy.total_node_count() } - let (mut world, mut ui_schedule) = setup_ui_test_world(); + let mut app = setup_ui_test_app(); + let world = app.world_mut(); world.spawn(( Camera2d, @@ -927,7 +944,8 @@ mod tests { MovingUiNode, )); - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); let pos_inc = Vec2::splat(1.); let total_cameras = world.query::<&Camera>().iter(&world).len(); @@ -936,7 +954,8 @@ mod tests { world.run_system_once(update_camera_viewports).unwrap(); - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); let viewport_rects = world .query::<(Entity, &Camera)>() @@ -946,7 +965,7 @@ mod tests { for (camera_entity, viewport) in viewport_rects.iter() { let target_pos = viewport.min + pos_inc; - do_move_and_test(&mut world, &mut ui_schedule, target_pos, camera_entity); + do_move_and_test(&mut app, target_pos, camera_entity); } // reverse direction @@ -954,9 +973,10 @@ mod tests { viewport_rects.reverse(); for (camera_entity, viewport) in viewport_rects.iter() { let target_pos = viewport.max - pos_inc; - do_move_and_test(&mut world, &mut ui_schedule, target_pos, camera_entity); + do_move_and_test(&mut app, target_pos, camera_entity); } + let world = app.world(); let current_taffy_node_count = get_taffy_node_count(&world); if current_taffy_node_count > expected_max_taffy_node_count { panic!("extra taffy nodes detected: current: {current_taffy_node_count} max expected: {expected_max_taffy_node_count}"); @@ -965,7 +985,8 @@ mod tests { #[test] fn ui_node_should_be_set_to_its_content_size() { - let (mut world, mut ui_schedule) = setup_ui_test_world(); + let mut app = setup_ui_test_app(); + let world = app.world_mut(); let content_size = Vec2::new(50., 25.); @@ -979,7 +1000,8 @@ mod tests { )) .id(); - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); let mut ui_surface = world.resource_mut::(); let layout = ui_surface.get_layout(ui_entity, true).unwrap().0; @@ -991,7 +1013,8 @@ mod tests { #[test] fn measure_funcs_should_be_removed_on_content_size_removal() { - let (mut world, mut ui_schedule) = setup_ui_test_world(); + let mut app = setup_ui_test_app(); + let world = app.world_mut(); let content_size = Vec2::new(50., 25.); let ui_entity = world @@ -1004,7 +1027,8 @@ mod tests { )) .id(); - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); let mut ui_surface = world.resource_mut::(); let ui_node = ui_surface.entity_to_taffy[&ui_entity]; @@ -1017,7 +1041,8 @@ mod tests { world.entity_mut(ui_entity).remove::(); - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); let mut ui_surface = world.resource_mut::(); // a node without a content size should not have taffy context @@ -1031,7 +1056,8 @@ mod tests { #[test] fn ui_rounding_test() { - let (mut world, mut ui_schedule) = setup_ui_test_world(); + let mut app = setup_ui_test_app(); + let world = app.world_mut(); let parent = world .spawn(Node { @@ -1063,8 +1089,9 @@ mod tests { // This fails with very small / unrealistic scale values let mut s = 1. - r; while s <= 5. { - world.resource_mut::().0 = s; - ui_schedule.run(&mut world); + app.world_mut().resource_mut::().0 = s; + app.update(); + let world = app.world_mut(); let width_sum: f32 = children .iter() .map(|child| world.get::(*child).unwrap().size.x) @@ -1079,7 +1106,32 @@ mod tests { #[test] fn no_camera_ui() { - let mut world = World::new(); + let mut app = App::new(); + + app.add_systems( + PostUpdate, + ( + // UI is driven by calculated camera target info, so we need to run the camera system first + bevy_render::camera::camera_system, + update_ui_context_system, + ApplyDeferred, + ui_layout_system, + ) + .chain(), + ); + + app.add_plugins(HierarchyPropagatePlugin::::new( + PostUpdate, + )); + + app.configure_sets( + PostUpdate, + PropagateSet::::default() + .after(update_ui_context_system) + .before(ui_layout_system), + ); + + let world = app.world_mut(); world.init_resource::(); world.init_resource::(); world.init_resource::>(); @@ -1105,18 +1157,6 @@ mod tests { PrimaryWindow, )); - let mut ui_schedule = Schedule::default(); - ui_schedule.add_systems( - ( - // UI is driven by calculated camera target info, so we need to run the camera system first - bevy_render::camera::camera_system, - update_ui_context_system, - ApplyDeferred, - ui_layout_system, - ) - .chain(), - ); - let ui_root = world .spawn(Node { width: Val::Percent(100.), @@ -1135,7 +1175,7 @@ mod tests { world.entity_mut(ui_root).add_child(ui_child); - ui_schedule.run(&mut world); + app.update(); } #[test] @@ -1181,13 +1221,15 @@ mod tests { #[test] fn no_viewport_node_leak_on_root_despawned() { - let (mut world, mut ui_schedule) = setup_ui_test_world(); + let mut app = setup_ui_test_app(); + let world = app.world_mut(); let ui_root_entity = world.spawn(Node::default()).id(); // The UI schedule synchronizes Bevy UI's internal `TaffyTree` with the // main world's tree of `Node` entities. - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); // Two taffy nodes are added to the internal `TaffyTree` for each root UI entity. // An implicit taffy node representing the viewport and a taffy node corresponding to the @@ -1201,7 +1243,8 @@ mod tests { // The UI schedule removes both the taffy node corresponding to `ui_root_entity` and its // parent viewport node. - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); // Both taffy nodes should now be removed from the internal `TaffyTree` assert_eq!( @@ -1212,12 +1255,14 @@ mod tests { #[test] fn no_viewport_node_leak_on_parented_root() { - let (mut world, mut ui_schedule) = setup_ui_test_world(); + let mut app = setup_ui_test_app(); + let world = app.world_mut(); let ui_root_entity_1 = world.spawn(Node::default()).id(); let ui_root_entity_2 = world.spawn(Node::default()).id(); - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); // There are two UI root entities. Each root taffy node is given it's own viewport node parent, // so a total of four taffy nodes are added to the `TaffyTree` by the UI schedule. @@ -1234,7 +1279,8 @@ mod tests { // Now there is only one root node so the second viewport node is removed by // the UI schedule. - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); // There is only one viewport node now, so the `TaffyTree` contains 3 nodes in total. assert_eq!( From 40ad9d3acc62ca3c64e7b28544fda457bb530c35 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Wed, 6 Aug 2025 16:35:36 +0100 Subject: [PATCH 10/18] Deleted UI test world builder function --- crates/bevy_ui/src/layout/mod.rs | 50 ++------------------------------ 1 file changed, 3 insertions(+), 47 deletions(-) diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index 510b6dba1d0c1..7e7c0c96596e7 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -353,6 +353,7 @@ pub fn ui_layout_system( #[cfg(test)] mod tests { use bevy_app::{App, HierarchyPropagatePlugin, PostUpdate, PropagateSet}; + use bevy_ecs::world; use taffy::TraversePartialTree; use bevy_asset::{AssetEvent, Assets}; @@ -435,52 +436,6 @@ mod tests { app } - fn setup_ui_test_world() -> (World, Schedule) { - let mut world = World::new(); - world.init_resource::(); - world.init_resource::(); - world.init_resource::>(); - world.init_resource::>(); - // Required for the camera system - world.init_resource::>(); - world.init_resource::>>(); - world.init_resource::>(); - world.init_resource::(); - - world.init_resource::(); - - world.init_resource::(); - - world.init_resource::(); - - // spawn a dummy primary window and camera - world.spawn(( - Window { - resolution: WindowResolution::new(WINDOW_WIDTH, WINDOW_HEIGHT), - ..default() - }, - PrimaryWindow, - )); - world.spawn(Camera2d); - - let mut ui_schedule = Schedule::default(); - ui_schedule.add_systems( - ( - // UI is driven by calculated camera target info, so we need to run the camera system first - bevy_render::camera::camera_system, - update_ui_context_system, - ApplyDeferred, - ui_layout_system, - mark_dirty_trees, - sync_simple_transforms, - propagate_parent_transforms, - ) - .chain(), - ); - - (world, ui_schedule) - } - #[test] fn ui_nodes_with_percent_100_dimensions_should_fill_their_parent() { let mut app = setup_ui_test_app(); @@ -1182,7 +1137,8 @@ mod tests { fn test_ui_surface_compute_camera_layout() { use bevy_ecs::prelude::ResMut; - let (mut world, ..) = setup_ui_test_world(); + let mut app = setup_ui_test_app(); + let world = app.world_mut(); let root_node_entity = Entity::from_raw_u32(1).unwrap(); From e05bd485a833d8a3cb3509357805e77faf4ab092 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Wed, 6 Aug 2025 16:35:57 +0100 Subject: [PATCH 11/18] Removed unused import --- crates/bevy_ui/src/layout/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index 7e7c0c96596e7..b8100ab984f66 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -353,7 +353,6 @@ pub fn ui_layout_system( #[cfg(test)] mod tests { use bevy_app::{App, HierarchyPropagatePlugin, PostUpdate, PropagateSet}; - use bevy_ecs::world; use taffy::TraversePartialTree; use bevy_asset::{AssetEvent, Assets}; From c3de3091ae150cb81ee1e6e799069e276d0c1730 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Wed, 6 Aug 2025 16:51:34 +0100 Subject: [PATCH 12/18] Added `UiSystemSet::Propagate`. Propgate `ComputedNodeTarget` values during `UiSystem::Propagate`. --- crates/bevy_ui/src/lib.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index 23968d837c6de..df44595ce6e9f 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -93,6 +93,8 @@ pub enum UiSystems { Focus, /// All UI systems in [`PostUpdate`] will run in or after this label. Prepare, + /// Propagate UI component values needed by layout. + Propagate, /// Update content requirements before layout. Content, /// After this label, the ui layout state has been updated. @@ -176,6 +178,7 @@ impl Plugin for UiPlugin { ( CameraUpdateSystems, UiSystems::Prepare.after(AnimationSystems), + UiSystems::Propagate, UiSystems::Content, UiSystems::Layout, UiSystems::PostLayout, @@ -184,15 +187,11 @@ impl Plugin for UiPlugin { ) .configure_sets( PostUpdate, - PropagateSet::::default().before(UiSystems::Content), + PropagateSet::::default().in_set(UiSystems::Propagate), ) .add_plugins(HierarchyPropagatePlugin::::new( PostUpdate, )) - .add_systems( - PostUpdate, - update_ui_context_system.before(PropagateSet::::default()), - ) .add_systems( PreUpdate, ui_focus_system.in_set(UiSystems::Focus).after(InputSystems), From 65aadc89f7d0d148021c77408446c226f625b0d6 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Wed, 6 Aug 2025 16:57:46 +0100 Subject: [PATCH 13/18] Updated tests in `update` module. --- crates/bevy_ui/src/update.rs | 68 ++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index 45117942c6213..e220957009000 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -180,8 +180,6 @@ mod tests { use bevy_ecs::event::Events; use bevy_ecs::hierarchy::ChildOf; use bevy_ecs::schedule::IntoScheduleConfigs; - use bevy_ecs::schedule::Schedule; - use bevy_ecs::world::World; use bevy_image::Image; use bevy_math::UVec2; use bevy_render::camera::Camera; @@ -202,22 +200,19 @@ mod tests { use crate::UiScale; use crate::UiTargetCamera; - fn setup_test_world_and_schedule() -> (World, Schedule) { - let mut world = World::new(); - - world.init_resource::(); + fn setup_test_app() -> App { + let mut app = App::new(); // init resources required by `camera_system` - world.init_resource::>(); - world.init_resource::>(); - world.init_resource::>(); - world.init_resource::>>(); - world.init_resource::>(); - world.init_resource::(); - - let mut schedule = Schedule::default(); - - schedule.add_systems( + app.init_resource::>(); + app.init_resource::>(); + app.init_resource::>(); + app.init_resource::>>(); + app.init_resource::>(); + app.init_resource::(); + + app.add_systems( + bevy_app::Update, ( bevy_render::camera::camera_system, super::update_ui_context_system, @@ -225,12 +220,13 @@ mod tests { .chain(), ); - (world, schedule) + app } #[test] fn update_context_for_single_ui_root() { - let (mut world, mut schedule) = setup_test_world_and_schedule(); + let app = setup_test_app(); + let world = app.world_mut(); let scale_factor = 10.; let physical_size = UVec2::new(1000, 500); @@ -248,7 +244,8 @@ mod tests { let uinode = world.spawn(Node::default()).id(); - schedule.run(&mut world); + app.update(); + let world = app.world_mut(); assert_eq!( *world.get::(uinode).unwrap(), @@ -262,7 +259,8 @@ mod tests { #[test] fn update_multiple_context_for_multiple_ui_roots() { - let (mut world, mut schedule) = setup_test_world_and_schedule(); + let app = setup_test_app(); + let world = app.world_mut(); let scale1 = 1.; let size1 = UVec2::new(100, 100); @@ -303,7 +301,8 @@ mod tests { let uinode2c = world.spawn((Node::default(), UiTargetCamera(camera2))).id(); let uinode1b = world.spawn(Node::default()).id(); - schedule.run(&mut world); + app.update(); + let world = app.world_mut(); for (uinode, camera, scale_factor, physical_size) in [ (uinode1a, camera1, scale1, size1), @@ -325,7 +324,8 @@ mod tests { #[test] fn update_context_on_changed_camera() { - let (mut world, mut schedule) = setup_test_world_and_schedule(); + let app = setup_test_app(); + let world = app.world_mut(); let scale1 = 1.; let size1 = UVec2::new(100, 100); @@ -362,7 +362,8 @@ mod tests { let uinode = world.spawn(Node::default()).id(); - schedule.run(&mut world); + app.update(); + let world = app.world_mut(); assert_eq!( world @@ -391,7 +392,8 @@ mod tests { world.entity_mut(uinode).insert(UiTargetCamera(camera2)); - schedule.run(&mut world); + app.update(); + let world = app.world_mut(); assert_eq!( world @@ -421,7 +423,8 @@ mod tests { #[test] fn update_context_after_parent_removed() { - let (mut world, mut schedule) = setup_test_world_and_schedule(); + let app = setup_test_app(); + let world = app.world_mut(); let scale1 = 1.; let size1 = UVec2::new(100, 100); @@ -460,7 +463,8 @@ mod tests { let uinode1 = world.spawn((Node::default(), UiTargetCamera(camera2))).id(); let uinode2 = world.spawn(Node::default()).add_child(uinode1).id(); - schedule.run(&mut world); + app.update(); + let world = app.world_mut(); assert_eq!( world @@ -499,7 +503,8 @@ mod tests { // Now `uinode1` is a root UI node its `UiTargetCamera` component will be used and its camera target set to `camera2`. world.entity_mut(uinode1).remove::(); - schedule.run(&mut world); + app.update(); + let world = app.world_mut(); assert_eq!( world @@ -538,7 +543,8 @@ mod tests { #[test] fn update_great_grandchild() { - let (mut world, mut schedule) = setup_test_world_and_schedule(); + let app = setup_test_app(); + let world = app.world_mut(); let scale = 1.; let size = UVec2::new(100, 100); @@ -561,7 +567,8 @@ mod tests { }); }); - schedule.run(&mut world); + app.update(); + let world = app.world_mut(); assert_eq!( world @@ -590,7 +597,8 @@ mod tests { world.resource_mut::().0 = 2.; - schedule.run(&mut world); + app.update(); + let world = app.world_mut(); assert_eq!( world From 8d176210f4d874c542207c3ca730985d3394abb1 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Wed, 6 Aug 2025 16:59:05 +0100 Subject: [PATCH 14/18] Made App mutable. --- crates/bevy_ui/src/update.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index e220957009000..6bb8fcaa37d55 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -174,6 +174,7 @@ pub fn update_ui_context_system( #[cfg(test)] mod tests { + use bevy_app::App; use bevy_asset::AssetEvent; use bevy_asset::Assets; use bevy_core_pipeline::core_2d::Camera2d; @@ -225,7 +226,7 @@ mod tests { #[test] fn update_context_for_single_ui_root() { - let app = setup_test_app(); + let mut app = setup_test_app(); let world = app.world_mut(); let scale_factor = 10.; @@ -259,7 +260,7 @@ mod tests { #[test] fn update_multiple_context_for_multiple_ui_roots() { - let app = setup_test_app(); + let mut app = setup_test_app(); let world = app.world_mut(); let scale1 = 1.; @@ -324,7 +325,7 @@ mod tests { #[test] fn update_context_on_changed_camera() { - let app = setup_test_app(); + let mut app = setup_test_app(); let world = app.world_mut(); let scale1 = 1.; @@ -423,7 +424,7 @@ mod tests { #[test] fn update_context_after_parent_removed() { - let app = setup_test_app(); + let mut app = setup_test_app(); let world = app.world_mut(); let scale1 = 1.; @@ -543,7 +544,7 @@ mod tests { #[test] fn update_great_grandchild() { - let app = setup_test_app(); + let mut app = setup_test_app(); let world = app.world_mut(); let scale = 1.; From 3988214d601bd5bae74d341646864541e138f81d Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Wed, 6 Aug 2025 17:10:04 +0100 Subject: [PATCH 15/18] Added `HierarchyPropagatePlugin` to `setup_test_app` --- crates/bevy_ui/src/update.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index 6bb8fcaa37d55..8b465f73f9899 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -141,15 +141,18 @@ pub fn update_ui_context_system( target_camera_query: Query<&UiTargetCamera>, ui_root_nodes: UiRootNodes, ) { + println!("update_ui_context_system!"); let default_camera_entity = default_ui_camera.get(); for root_entity in ui_root_nodes.iter() { + println!("root entity: {root_entity}"); let camera = target_camera_query .get(root_entity) .ok() .map(UiTargetCamera::entity) .or(default_camera_entity) .unwrap_or(Entity::PLACEHOLDER); + println!("\tcamera: {camera}"); let (scale_factor, physical_size) = camera_query .get(camera) @@ -161,6 +164,7 @@ pub fn update_ui_context_system( ) }) .unwrap_or((1., UVec2::ZERO)); + println!("\tphysical_size: {physical_size}"); commands .entity(root_entity) @@ -175,6 +179,9 @@ pub fn update_ui_context_system( #[cfg(test)] mod tests { use bevy_app::App; + use bevy_app::HierarchyPropagatePlugin; + use bevy_app::PostUpdate; + use bevy_app::PropagateSet; use bevy_asset::AssetEvent; use bevy_asset::Assets; use bevy_core_pipeline::core_2d::Camera2d; @@ -195,6 +202,7 @@ mod tests { use bevy_window::WindowResolution; use bevy_window::WindowScaleFactorChanged; + use crate::update::update_ui_context_system; use crate::ComputedNodeTarget; use crate::IsDefaultUiCamera; use crate::Node; @@ -211,14 +219,15 @@ mod tests { app.init_resource::>>(); app.init_resource::>(); app.init_resource::(); + app.add_plugins(HierarchyPropagatePlugin::::new( + PostUpdate, + )); + + app.configure_sets(PostUpdate, PropagateSet::::default()); app.add_systems( bevy_app::Update, - ( - bevy_render::camera::camera_system, - super::update_ui_context_system, - ) - .chain(), + (bevy_render::camera::camera_system, update_ui_context_system).chain(), ); app From 95e658007655de966454c97c31344f5e52927704 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Wed, 6 Aug 2025 17:12:09 +0100 Subject: [PATCH 16/18] init UiScale for test app --- crates/bevy_ui/src/update.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index 8b465f73f9899..9d124a9199425 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -212,6 +212,8 @@ mod tests { fn setup_test_app() -> App { let mut app = App::new(); + app.init_resource::(); + // init resources required by `camera_system` app.init_resource::>(); app.init_resource::>(); From 971881e23232dc6571318ded2c734f54bf3a3bb6 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Wed, 6 Aug 2025 17:19:56 +0100 Subject: [PATCH 17/18] Removed debug code. --- crates/bevy_ui/src/update.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index 9d124a9199425..b49e1f90c4db6 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -141,18 +141,15 @@ pub fn update_ui_context_system( target_camera_query: Query<&UiTargetCamera>, ui_root_nodes: UiRootNodes, ) { - println!("update_ui_context_system!"); let default_camera_entity = default_ui_camera.get(); for root_entity in ui_root_nodes.iter() { - println!("root entity: {root_entity}"); let camera = target_camera_query .get(root_entity) .ok() .map(UiTargetCamera::entity) .or(default_camera_entity) .unwrap_or(Entity::PLACEHOLDER); - println!("\tcamera: {camera}"); let (scale_factor, physical_size) = camera_query .get(camera) @@ -164,7 +161,6 @@ pub fn update_ui_context_system( ) }) .unwrap_or((1., UVec2::ZERO)); - println!("\tphysical_size: {physical_size}"); commands .entity(root_entity) From 3ae5bfb6f48ad22b80b89fde297f2eb3714a3321 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Wed, 6 Aug 2025 17:40:35 +0100 Subject: [PATCH 18/18] Fixed needless borrows --- crates/bevy_ui/src/layout/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index b8100ab984f66..3d011358fe7c9 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -764,7 +764,7 @@ mod tests { let overlap_check = world .query_filtered::<(Entity, &ComputedNode, &UiGlobalTransform), Without>() - .iter(&world) + .iter(world) .fold( Option::<(Rect, bool)>::None, |option_rect, (entity, node, transform)| { @@ -902,9 +902,9 @@ mod tests { let world = app.world_mut(); let pos_inc = Vec2::splat(1.); - let total_cameras = world.query::<&Camera>().iter(&world).len(); + let total_cameras = world.query::<&Camera>().iter(world).len(); // add total cameras - 1 (the assumed default) to get an idea for how many nodes we should expect - let expected_max_taffy_node_count = get_taffy_node_count(&world) + total_cameras - 1; + let expected_max_taffy_node_count = get_taffy_node_count(world) + total_cameras - 1; world.run_system_once(update_camera_viewports).unwrap(); @@ -913,7 +913,7 @@ mod tests { let viewport_rects = world .query::<(Entity, &Camera)>() - .iter(&world) + .iter(world) .map(|(e, c)| (e, c.logical_viewport_rect().expect("missing viewport"))) .collect::>(); @@ -931,7 +931,7 @@ mod tests { } let world = app.world(); - let current_taffy_node_count = get_taffy_node_count(&world); + let current_taffy_node_count = get_taffy_node_count(world); if current_taffy_node_count > expected_max_taffy_node_count { panic!("extra taffy nodes detected: current: {current_taffy_node_count} max expected: {expected_max_taffy_node_count}"); }