diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index 14c468e157016..3d011358fe7c9 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,36 +380,27 @@ mod tests { const WINDOW_WIDTH: f32 = 1000.; const WINDOW_HEIGHT: f32 = 100.; - 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::(); + fn setup_ui_test_app() -> App { + let mut app = App::new(); - 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, + app.add_plugins(HierarchyPropagatePlugin::::new( + PostUpdate, )); - world.spawn(Camera2d); - - let mut ui_schedule = Schedule::default(); - ui_schedule.add_systems( + 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, @@ -421,12 +414,32 @@ mod tests { .chain(), ); - (world, ui_schedule) + 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 } #[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 +460,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; @@ -459,18 +473,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)); @@ -478,8 +491,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)); @@ -489,12 +502,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::(); @@ -504,7 +519,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::(); @@ -514,12 +530,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]; @@ -535,7 +553,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::(); @@ -567,7 +586,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!( @@ -610,7 +630,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::(); @@ -620,9 +641,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::(); @@ -631,7 +653,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)); @@ -642,7 +665,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)); @@ -651,17 +675,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]; @@ -672,19 +699,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)] { @@ -698,7 +728,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.; @@ -728,11 +759,12 @@ 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>() - .iter(&world) + .iter(world) .fold( Option::<(Rect, bool)>::None, |option_rect, (entity, node, transform)| { @@ -820,14 +852,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) @@ -848,7 +877,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, @@ -868,26 +898,28 @@ 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(); + 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(); - ui_schedule.run(&mut world); + app.update(); + let world = app.world_mut(); let viewport_rects = world .query::<(Entity, &Camera)>() - .iter(&world) + .iter(world) .map(|(e, c)| (e, c.logical_viewport_rect().expect("missing viewport"))) .collect::>(); 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 @@ -895,10 +927,11 @@ 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 current_taffy_node_count = get_taffy_node_count(&world); + 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}"); } @@ -906,7 +939,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.); @@ -920,7 +954,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; @@ -932,7 +967,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 @@ -945,7 +981,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]; @@ -958,7 +995,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 @@ -972,7 +1010,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 { @@ -1004,8 +1043,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) @@ -1020,7 +1060,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::>(); @@ -1046,18 +1111,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.), @@ -1076,14 +1129,15 @@ mod tests { world.entity_mut(ui_root).add_child(ui_child); - ui_schedule.run(&mut world); + app.update(); } #[test] 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(); @@ -1122,13 +1176,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 @@ -1142,7 +1198,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!( @@ -1153,12 +1210,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. @@ -1175,7 +1234,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!( diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index d3f9cbd279016..df44595ce6e9f 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, PropagateSet}; use bevy_ecs::prelude::*; use bevy_input::InputSystems; use bevy_render::camera::CameraUpdateSystems; @@ -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,12 +178,20 @@ impl Plugin for UiPlugin { ( CameraUpdateSystems, UiSystems::Prepare.after(AnimationSystems), + UiSystems::Propagate, UiSystems::Content, UiSystems::Layout, UiSystems::PostLayout, ) .chain(), ) + .configure_sets( + PostUpdate, + PropagateSet::::default().in_set(UiSystems::Propagate), + ) + .add_plugins(HierarchyPropagatePlugin::::new( + PostUpdate, + )) .add_systems( PreUpdate, ui_focus_system.in_set(UiSystems::Focus).after(InputSystems), diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index 313b4af192f46..b49e1f90c4db6 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -8,11 +8,10 @@ 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}; @@ -135,14 +134,12 @@ 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)>, ) { let default_camera_entity = default_ui_camera.get(); @@ -165,59 +162,28 @@ pub fn update_ui_context_system( }) .unwrap_or((1., UVec2::ZERO)); - update_contexts_recursively( - root_entity, - ComputedNodeTarget { + 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, - ); - } -} - -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_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; 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; @@ -232,41 +198,43 @@ 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; use crate::UiScale; use crate::UiTargetCamera; - fn setup_test_world_and_schedule() -> (World, Schedule) { - let mut world = World::new(); + fn setup_test_app() -> App { + let mut app = App::new(); - world.init_resource::(); + app.init_resource::(); // 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( - ( - bevy_render::camera::camera_system, - super::update_ui_context_system, - ) - .chain(), + app.init_resource::>(); + app.init_resource::>(); + app.init_resource::>(); + 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, update_ui_context_system).chain(), ); - (world, schedule) + app } #[test] fn update_context_for_single_ui_root() { - let (mut world, mut schedule) = setup_test_world_and_schedule(); + let mut app = setup_test_app(); + let world = app.world_mut(); let scale_factor = 10.; let physical_size = UVec2::new(1000, 500); @@ -284,7 +252,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(), @@ -298,7 +267,8 @@ mod tests { #[test] fn update_multiple_context_for_multiple_ui_roots() { - let (mut world, mut schedule) = setup_test_world_and_schedule(); + let mut app = setup_test_app(); + let world = app.world_mut(); let scale1 = 1.; let size1 = UVec2::new(100, 100); @@ -339,7 +309,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), @@ -361,7 +332,8 @@ mod tests { #[test] fn update_context_on_changed_camera() { - let (mut world, mut schedule) = setup_test_world_and_schedule(); + let mut app = setup_test_app(); + let world = app.world_mut(); let scale1 = 1.; let size1 = UVec2::new(100, 100); @@ -398,7 +370,8 @@ mod tests { let uinode = world.spawn(Node::default()).id(); - schedule.run(&mut world); + app.update(); + let world = app.world_mut(); assert_eq!( world @@ -427,7 +400,8 @@ mod tests { world.entity_mut(uinode).insert(UiTargetCamera(camera2)); - schedule.run(&mut world); + app.update(); + let world = app.world_mut(); assert_eq!( world @@ -457,7 +431,8 @@ mod tests { #[test] fn update_context_after_parent_removed() { - let (mut world, mut schedule) = setup_test_world_and_schedule(); + let mut app = setup_test_app(); + let world = app.world_mut(); let scale1 = 1.; let size1 = UVec2::new(100, 100); @@ -496,7 +471,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 @@ -535,7 +511,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 @@ -574,7 +551,8 @@ mod tests { #[test] fn update_great_grandchild() { - let (mut world, mut schedule) = setup_test_world_and_schedule(); + let mut app = setup_test_app(); + let world = app.world_mut(); let scale = 1.; let size = UVec2::new(100, 100); @@ -597,7 +575,8 @@ mod tests { }); }); - schedule.run(&mut world); + app.update(); + let world = app.world_mut(); assert_eq!( world @@ -626,7 +605,8 @@ mod tests { world.resource_mut::().0 = 2.; - schedule.run(&mut world); + app.update(); + let world = app.world_mut(); assert_eq!( world