From 484721be80aa15db3fbea547396c9d9fe36a5d8a Mon Sep 17 00:00:00 2001 From: Shane Date: Mon, 26 Aug 2024 11:24:59 -0700 Subject: [PATCH] Have EntityCommands methods consume self for easier chaining (#14897) # Objective Fixes #14883 ## Solution Pretty simple update to `EntityCommands` methods to consume `self` and return it rather than taking `&mut self`. The things probably worth noting: * I added `#[allow(clippy::should_implement_trait)]` to the `add` method because it causes a linting conflict with `std::ops::Add`. * `despawn` and `log_components` now return `Self`. I'm not sure if that's exactly the desired behavior so I'm happy to adjust if that seems wrong. ## Testing Tested with `cargo run -p ci`. I think that should be sufficient to call things good. ## Migration Guide The most likely migration needed is changing code from this: ``` let mut entity = commands.get_or_spawn(entity); if depth_prepass { entity.insert(DepthPrepass); } if normal_prepass { entity.insert(NormalPrepass); } if motion_vector_prepass { entity.insert(MotionVectorPrepass); } if deferred_prepass { entity.insert(DeferredPrepass); } ``` to this: ``` let mut entity = commands.get_or_spawn(entity); if depth_prepass { entity = entity.insert(DepthPrepass); } if normal_prepass { entity = entity.insert(NormalPrepass); } if motion_vector_prepass { entity = entity.insert(MotionVectorPrepass); } if deferred_prepass { entity.insert(DeferredPrepass); } ``` as can be seen in several of the example code updates here. There will probably also be instances where mutable `EntityCommands` vars no longer need to be mutable. --- benches/benches/bevy_ecs/world/commands.rs | 19 +-- crates/bevy_core_pipeline/src/core_3d/mod.rs | 20 +-- crates/bevy_ecs/src/system/commands/mod.rs | 134 ++++++++++++++----- crates/bevy_pbr/src/prepass/mod.rs | 2 +- crates/bevy_pbr/src/wireframe.rs | 2 +- crates/bevy_picking/src/focus.rs | 2 +- crates/bevy_render/src/camera/camera.rs | 10 +- crates/bevy_sprite/src/mesh2d/wireframe2d.rs | 2 +- crates/bevy_winit/src/system.rs | 3 +- examples/2d/sprite_slice.rs | 2 +- examples/3d/anti_aliasing.rs | 38 +++--- examples/3d/depth_of_field.rs | 19 +-- examples/3d/motion_blur.rs | 23 ++-- examples/3d/ssao.rs | 49 ++++--- examples/animation/animation_graph.rs | 2 +- examples/ecs/observers.rs | 2 +- examples/games/game_menu.rs | 2 +- examples/stress_tests/many_buttons.rs | 2 +- examples/stress_tests/many_cubes.rs | 27 ++-- examples/stress_tests/transform_hierarchy.rs | 4 +- 20 files changed, 211 insertions(+), 153 deletions(-) diff --git a/benches/benches/bevy_ecs/world/commands.rs b/benches/benches/bevy_ecs/world/commands.rs index 75b4b25a2a..d6b6c1438a 100644 --- a/benches/benches/bevy_ecs/world/commands.rs +++ b/benches/benches/bevy_ecs/world/commands.rs @@ -1,4 +1,5 @@ use std::mem::size_of; + use bevy_ecs::{ component::Component, entity::Entity, @@ -44,19 +45,11 @@ pub fn spawn_commands(criterion: &mut Criterion) { bencher.iter(|| { let mut commands = Commands::new(&mut command_queue, &world); for i in 0..entity_count { - let mut entity = commands.spawn_empty(); - - if black_box(i % 2 == 0) { - entity.insert(A); - } - - if black_box(i % 3 == 0) { - entity.insert(B); - } - - if black_box(i % 4 == 0) { - entity.insert(C); - } + let mut entity = commands + .spawn_empty() + .insert_if(A, || black_box(i % 2 == 0)) + .insert_if(B, || black_box(i % 3 == 0)) + .insert_if(C, || black_box(i % 4 == 0)); if black_box(i % 5 == 0) { entity.despawn(); diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index bf38e1deb2..c539c10fa7 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -584,20 +584,12 @@ pub fn extract_camera_prepass_phase( live_entities.insert(entity); - let mut entity = commands.get_or_spawn(entity); - - if depth_prepass { - entity.insert(DepthPrepass); - } - if normal_prepass { - entity.insert(NormalPrepass); - } - if motion_vector_prepass { - entity.insert(MotionVectorPrepass); - } - if deferred_prepass { - entity.insert(DeferredPrepass); - } + commands + .get_or_spawn(entity) + .insert_if(DepthPrepass, || depth_prepass) + .insert_if(NormalPrepass, || normal_prepass) + .insert_if(MotionVectorPrepass, || motion_vector_prepass) + .insert_if(DeferredPrepass, || deferred_prepass); } opaque_3d_prepass_phases.retain(|entity, _| live_entities.contains(entity)); diff --git a/crates/bevy_ecs/src/system/commands/mod.rs b/crates/bevy_ecs/src/system/commands/mod.rs index 14748ac070..c0846a8c88 100644 --- a/crates/bevy_ecs/src/system/commands/mod.rs +++ b/crates/bevy_ecs/src/system/commands/mod.rs @@ -364,9 +364,7 @@ impl<'w, 's> Commands<'w, 's> { /// - [`spawn_batch`](Self::spawn_batch) to spawn entities with a bundle each. #[track_caller] pub fn spawn(&mut self, bundle: T) -> EntityCommands { - let mut e = self.spawn_empty(); - e.insert(bundle); - e + self.spawn_empty().insert(bundle) } /// Returns the [`EntityCommands`] for the requested [`Entity`]. @@ -951,10 +949,51 @@ impl EntityCommands<'_> { /// # bevy_ecs::system::assert_is_system(add_combat_stats_system); /// ``` #[track_caller] - pub fn insert(&mut self, bundle: impl Bundle) -> &mut Self { + pub fn insert(self, bundle: impl Bundle) -> Self { self.add(insert(bundle, InsertMode::Replace)) } + /// Similar to [`Self::insert`] but will only insert if the predicate returns true. + /// This is useful for chaining method calls. + /// + /// # Panics + /// + /// The command will panic when applied if the associated entity does not exist. + /// + /// To avoid a panic in this case, use the command [`Self::try_insert_if`] instead. + /// + /// # Example + /// + /// ``` + /// # use bevy_ecs::prelude::*; + /// # #[derive(Resource)] + /// # struct PlayerEntity { entity: Entity } + /// # impl PlayerEntity { fn is_spectator(&self) -> bool { true } } + /// #[derive(Component)] + /// struct StillLoadingStats; + /// #[derive(Component)] + /// struct Health(u32); + /// + /// fn add_health_system(mut commands: Commands, player: Res) { + /// commands + /// .entity(player.entity) + /// .insert_if(Health(10), || !player.is_spectator()) + /// .remove::(); + /// } + /// # bevy_ecs::system::assert_is_system(add_health_system); + /// ``` + #[track_caller] + pub fn insert_if(self, bundle: impl Bundle, condition: F) -> Self + where + F: FnOnce() -> bool, + { + if condition() { + self.add(insert(bundle, InsertMode::Replace)) + } else { + self + } + } + /// Adds a [`Bundle`] of components to the entity without overwriting. /// /// This is the same as [`EntityCommands::insert`], but in case of duplicate @@ -968,7 +1007,7 @@ impl EntityCommands<'_> { /// /// To avoid a panic in this case, use the command [`Self::try_insert_if_new`] /// instead. - pub fn insert_if_new(&mut self, bundle: impl Bundle) -> &mut Self { + pub fn insert_if_new(self, bundle: impl Bundle) -> Self { self.add(insert(bundle, InsertMode::Keep)) } @@ -988,16 +1027,15 @@ impl EntityCommands<'_> { /// - `T` must have the same layout as the one passed during `component_id` creation. #[track_caller] pub unsafe fn insert_by_id( - &mut self, + self, component_id: ComponentId, value: T, - ) -> &mut Self { + ) -> Self { let caller = Location::caller(); // SAFETY: same invariants as parent call self.add(unsafe {insert_by_id(component_id, value, move |entity| { panic!("error[B0003]: {caller}: Could not insert a component {component_id:?} (with type {}) for entity {entity:?} because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/#b0003", std::any::type_name::()); - })}); - self + })}) } /// Attempts to add a dynamic component to an entity. @@ -1009,13 +1047,12 @@ impl EntityCommands<'_> { /// - [`ComponentId`] must be from the same world as `self`. /// - `T` must have the same layout as the one passed during `component_id` creation. pub unsafe fn try_insert_by_id( - &mut self, + self, component_id: ComponentId, value: T, - ) -> &mut Self { + ) -> Self { // SAFETY: same invariants as parent call - self.add(unsafe { insert_by_id(component_id, value, |_| {}) }); - self + self.add(unsafe { insert_by_id(component_id, value, |_| {}) }) } /// Tries to add a [`Bundle`] of components to the entity. @@ -1067,10 +1104,48 @@ impl EntityCommands<'_> { /// # bevy_ecs::system::assert_is_system(add_combat_stats_system); /// ``` #[track_caller] - pub fn try_insert(&mut self, bundle: impl Bundle) -> &mut Self { + pub fn try_insert(self, bundle: impl Bundle) -> Self { self.add(try_insert(bundle, InsertMode::Replace)) } + /// Similar to [`Self::try_insert`] but will only try to insert if the predicate returns true. + /// This is useful for chaining method calls. + /// + /// # Example + /// + /// ``` + /// # use bevy_ecs::prelude::*; + /// # #[derive(Resource)] + /// # struct PlayerEntity { entity: Entity } + /// # impl PlayerEntity { fn is_spectator(&self) -> bool { true } } + /// #[derive(Component)] + /// struct StillLoadingStats; + /// #[derive(Component)] + /// struct Health(u32); + /// + /// fn add_health_system(mut commands: Commands, player: Res) { + /// commands.entity(player.entity) + /// .try_insert_if(Health(10), || !player.is_spectator()) + /// .remove::(); + /// + /// commands.entity(player.entity) + /// // This will not panic nor will it add the component + /// .try_insert_if(Health(5), || !player.is_spectator()); + /// } + /// # bevy_ecs::system::assert_is_system(add_health_system); + /// ``` + #[track_caller] + pub fn try_insert_if(self, bundle: impl Bundle, condition: F) -> Self + where + F: FnOnce() -> bool, + { + if condition() { + self.add(try_insert(bundle, InsertMode::Replace)) + } else { + self + } + } + /// Tries to add a [`Bundle`] of components to the entity without overwriting. /// /// This is the same as [`EntityCommands::try_insert`], but in case of duplicate @@ -1080,7 +1155,7 @@ impl EntityCommands<'_> { /// # Note /// /// Unlike [`Self::insert_if_new`], this will not panic if the associated entity does not exist. - pub fn try_insert_if_new(&mut self, bundle: impl Bundle) -> &mut Self { + pub fn try_insert_if_new(self, bundle: impl Bundle) -> Self { self.add(try_insert(bundle, InsertMode::Keep)) } @@ -1119,7 +1194,7 @@ impl EntityCommands<'_> { /// } /// # bevy_ecs::system::assert_is_system(remove_combat_stats_system); /// ``` - pub fn remove(&mut self) -> &mut Self + pub fn remove(self) -> Self where T: Bundle, { @@ -1127,12 +1202,12 @@ impl EntityCommands<'_> { } /// Removes a component from the entity. - pub fn remove_by_id(&mut self, component_id: ComponentId) -> &mut Self { + pub fn remove_by_id(self, component_id: ComponentId) -> Self { self.add(remove_by_id(component_id)) } /// Removes all components associated with the entity. - pub fn clear(&mut self) -> &mut Self { + pub fn clear(self) -> Self { self.add(clear()) } @@ -1164,8 +1239,8 @@ impl EntityCommands<'_> { /// # bevy_ecs::system::assert_is_system(remove_character_system); /// ``` #[track_caller] - pub fn despawn(&mut self) { - self.add(despawn()); + pub fn despawn(self) -> Self { + self.add(despawn()) } /// Pushes an [`EntityCommand`] to the queue, which will get executed for the current [`Entity`]. @@ -1184,7 +1259,8 @@ impl EntityCommands<'_> { /// # } /// # bevy_ecs::system::assert_is_system(my_system); /// ``` - pub fn add(&mut self, command: impl EntityCommand) -> &mut Self { + #[allow(clippy::should_implement_trait)] + pub fn add(mut self, command: impl EntityCommand) -> Self { self.commands.add(command.with_entity(self.entity)); self } @@ -1226,7 +1302,7 @@ impl EntityCommands<'_> { /// } /// # bevy_ecs::system::assert_is_system(remove_combat_stats_system); /// ``` - pub fn retain(&mut self) -> &mut Self + pub fn retain(self) -> Self where T: Bundle, { @@ -1238,8 +1314,8 @@ impl EntityCommands<'_> { /// # Panics /// /// The command will panic when applied if the associated entity does not exist. - pub fn log_components(&mut self) { - self.add(log_components); + pub fn log_components(self) -> Self { + self.add(log_components) } /// Returns the underlying [`Commands`]. @@ -1251,18 +1327,14 @@ impl EntityCommands<'_> { /// watches this entity. /// /// [`Trigger`]: crate::observer::Trigger - pub fn trigger(&mut self, event: impl Event) -> &mut Self { + pub fn trigger(mut self, event: impl Event) -> Self { self.commands.trigger_targets(event, self.entity); self } /// Creates an [`Observer`] listening for a trigger of type `T` that targets this entity. - pub fn observe( - &mut self, - system: impl IntoObserverSystem, - ) -> &mut Self { - self.add(observe(system)); - self + pub fn observe(self, system: impl IntoObserverSystem) -> Self { + self.add(observe(system)) } } diff --git a/crates/bevy_pbr/src/prepass/mod.rs b/crates/bevy_pbr/src/prepass/mod.rs index e545e3df3b..a639813d0d 100644 --- a/crates/bevy_pbr/src/prepass/mod.rs +++ b/crates/bevy_pbr/src/prepass/mod.rs @@ -581,7 +581,7 @@ pub fn extract_camera_previous_view_data( ) { for (entity, camera, maybe_previous_view_data) in cameras_3d.iter() { if camera.is_active { - let mut entity = commands.get_or_spawn(entity); + let entity = commands.get_or_spawn(entity); if let Some(previous_view_data) = maybe_previous_view_data { entity.insert(previous_view_data.clone()); diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index 0c9798adfc..abb24aae7a 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -154,7 +154,7 @@ fn apply_wireframe_material( global_material: Res, ) { for e in removed_wireframes.read().chain(no_wireframes.iter()) { - if let Some(mut commands) = commands.get_entity(e) { + if let Some(commands) = commands.get_entity(e) { commands.remove::>(); } } diff --git a/crates/bevy_picking/src/focus.rs b/crates/bevy_picking/src/focus.rs index 8a593335cd..8ae93ce2be 100644 --- a/crates/bevy_picking/src/focus.rs +++ b/crates/bevy_picking/src/focus.rs @@ -231,7 +231,7 @@ pub fn update_interactions( for (hovered_entity, new_interaction) in new_interaction_state.drain() { if let Ok(mut interaction) = interact.get_mut(hovered_entity) { *interaction = new_interaction; - } else if let Some(mut entity_commands) = commands.get_entity(hovered_entity) { + } else if let Some(entity_commands) = commands.get_entity(hovered_entity) { entity_commands.try_insert(new_interaction); } } diff --git a/crates/bevy_render/src/camera/camera.rs b/crates/bevy_render/src/camera/camera.rs index 4f533345b9..78dbec4a37 100644 --- a/crates/bevy_render/src/camera/camera.rs +++ b/crates/bevy_render/src/camera/camera.rs @@ -935,9 +935,7 @@ pub fn extract_cameras( continue; } - let mut commands = commands.get_or_spawn(entity); - - commands.insert(( + let mut commands = commands.get_or_spawn(entity).insert(( ExtractedCamera { target: camera.target.normalize(primary_window), viewport: camera.viewport.clone(), @@ -973,15 +971,15 @@ pub fn extract_cameras( )); if let Some(temporal_jitter) = temporal_jitter { - commands.insert(temporal_jitter.clone()); + commands = commands.insert(temporal_jitter.clone()); } if let Some(render_layers) = render_layers { - commands.insert(render_layers.clone()); + commands = commands.insert(render_layers.clone()); } if let Some(perspective) = projection { - commands.insert(perspective.clone()); + commands = commands.insert(perspective.clone()); } if gpu_culling { diff --git a/crates/bevy_sprite/src/mesh2d/wireframe2d.rs b/crates/bevy_sprite/src/mesh2d/wireframe2d.rs index 83633a95e2..43bd10c622 100644 --- a/crates/bevy_sprite/src/mesh2d/wireframe2d.rs +++ b/crates/bevy_sprite/src/mesh2d/wireframe2d.rs @@ -150,7 +150,7 @@ fn apply_wireframe_material( global_material: Res, ) { for e in removed_wireframes.read().chain(no_wireframes.iter()) { - if let Some(mut commands) = commands.get_entity(e) { + if let Some(commands) = commands.get_entity(e) { commands.remove::>(); } } diff --git a/crates/bevy_winit/src/system.rs b/crates/bevy_winit/src/system.rs index 86d3b24acb..bd9f2dee14 100644 --- a/crates/bevy_winit/src/system.rs +++ b/crates/bevy_winit/src/system.rs @@ -88,8 +88,7 @@ pub fn create_windows( }); if let Ok(handle_wrapper) = RawHandleWrapper::new(winit_window) { - let mut entity = commands.entity(entity); - entity.insert(handle_wrapper.clone()); + commands.entity(entity).insert(handle_wrapper.clone()); if let Some(handle_holder) = handle_holder { *handle_holder.0.lock().unwrap() = Some(handle_wrapper); } diff --git a/examples/2d/sprite_slice.rs b/examples/2d/sprite_slice.rs index 7afb0c975c..9782710326 100644 --- a/examples/2d/sprite_slice.rs +++ b/examples/2d/sprite_slice.rs @@ -83,7 +83,7 @@ fn spawn_sprites( ..default() }); if let Some(scale_mode) = scale_mode { - cmd.insert(scale_mode); + cmd = cmd.insert(scale_mode); } cmd.with_children(|builder| { builder.spawn(Text2dBundle { diff --git a/examples/3d/anti_aliasing.rs b/examples/3d/anti_aliasing.rs index b5e785b953..81822c32c6 100644 --- a/examples/3d/anti_aliasing.rs +++ b/examples/3d/anti_aliasing.rs @@ -49,16 +49,18 @@ fn modify_aa( // No AA if keys.just_pressed(KeyCode::Digit1) { *msaa = Msaa::Off; - camera.remove::(); - camera.remove::(); - camera.remove::(); + camera = camera + .remove::() + .remove::() + .remove::(); } // MSAA if keys.just_pressed(KeyCode::Digit2) && *msaa == Msaa::Off { - camera.remove::(); - camera.remove::(); - camera.remove::(); + camera = camera + .remove::() + .remove::() + .remove::(); *msaa = Msaa::Sample4; } @@ -79,10 +81,10 @@ fn modify_aa( // FXAA if keys.just_pressed(KeyCode::Digit3) && fxaa.is_none() { *msaa = Msaa::Off; - camera.remove::(); - camera.remove::(); - - camera.insert(Fxaa::default()); + camera = camera + .remove::() + .remove::() + .insert(Fxaa::default()); } // FXAA Settings @@ -112,10 +114,10 @@ fn modify_aa( // SMAA if keys.just_pressed(KeyCode::Digit4) && smaa.is_none() { *msaa = Msaa::Off; - camera.remove::(); - camera.remove::(); - - camera.insert(SmaaSettings::default()); + camera = camera + .remove::() + .remove::() + .insert(SmaaSettings::default()); } // SMAA Settings @@ -137,10 +139,10 @@ fn modify_aa( // TAA if keys.just_pressed(KeyCode::Digit5) && taa.is_none() { *msaa = Msaa::Off; - camera.remove::(); - camera.remove::(); - - camera.insert(TemporalAntiAliasBundle::default()); + camera + .remove::() + .remove::() + .insert(TemporalAntiAliasBundle::default()); } } diff --git a/examples/3d/depth_of_field.rs b/examples/3d/depth_of_field.rs index 61a8bdfd70..b2ae247545 100644 --- a/examples/3d/depth_of_field.rs +++ b/examples/3d/depth_of_field.rs @@ -70,16 +70,17 @@ fn main() { fn setup(mut commands: Commands, asset_server: Res, app_settings: Res) { // Spawn the camera. Enable HDR and bloom, as that highlights the depth of // field effect. - let mut camera = commands.spawn(Camera3dBundle { - transform: Transform::from_xyz(0.0, 4.5, 8.25).looking_at(Vec3::ZERO, Vec3::Y), - camera: Camera { - hdr: true, + let camera = commands + .spawn(Camera3dBundle { + transform: Transform::from_xyz(0.0, 4.5, 8.25).looking_at(Vec3::ZERO, Vec3::Y), + camera: Camera { + hdr: true, + ..default() + }, + tonemapping: Tonemapping::TonyMcMapface, ..default() - }, - tonemapping: Tonemapping::TonyMcMapface, - ..default() - }); - camera.insert(BloomSettings::NATURAL); + }) + .insert(BloomSettings::NATURAL); // Insert the depth of field settings. if let Some(dof_settings) = Option::::from(*app_settings) { diff --git a/examples/3d/motion_blur.rs b/examples/3d/motion_blur.rs index 11297e0527..510412e300 100644 --- a/examples/3d/motion_blur.rs +++ b/examples/3d/motion_blur.rs @@ -144,18 +144,17 @@ fn spawn_cars( for i in 0..N_CARS { let color = colors[i % colors.len()].clone(); - let mut entity = commands.spawn(( - PbrBundle { - mesh: box_mesh.clone(), - material: color.clone(), - transform: Transform::from_scale(Vec3::splat(0.5)), - ..default() - }, - Moves(i as f32 * 2.0), - )); - if i == 0 { - entity.insert(CameraTracked); - } + let mut entity = commands + .spawn(( + PbrBundle { + mesh: box_mesh.clone(), + material: color.clone(), + transform: Transform::from_scale(Vec3::splat(0.5)), + ..default() + }, + Moves(i as f32 * 2.0), + )) + .insert_if(CameraTracked, || i == 0); entity.with_children(|parent| { parent.spawn(PbrBundle { mesh: box_mesh.clone(), diff --git a/examples/3d/ssao.rs b/examples/3d/ssao.rs index 54af555b5b..ede71f46bb 100644 --- a/examples/3d/ssao.rs +++ b/examples/3d/ssao.rs @@ -123,29 +123,34 @@ fn update( let (camera_entity, ssao_settings, temporal_jitter) = camera.single(); - let mut commands = commands.entity(camera_entity); + let mut commands = commands + .entity(camera_entity) + .insert_if( + ScreenSpaceAmbientOcclusionSettings { + quality_level: ScreenSpaceAmbientOcclusionQualityLevel::Low, + }, + || keycode.just_pressed(KeyCode::Digit2), + ) + .insert_if( + ScreenSpaceAmbientOcclusionSettings { + quality_level: ScreenSpaceAmbientOcclusionQualityLevel::Medium, + }, + || keycode.just_pressed(KeyCode::Digit3), + ) + .insert_if( + ScreenSpaceAmbientOcclusionSettings { + quality_level: ScreenSpaceAmbientOcclusionQualityLevel::High, + }, + || keycode.just_pressed(KeyCode::Digit4), + ) + .insert_if( + ScreenSpaceAmbientOcclusionSettings { + quality_level: ScreenSpaceAmbientOcclusionQualityLevel::Ultra, + }, + || keycode.just_pressed(KeyCode::Digit5), + ); if keycode.just_pressed(KeyCode::Digit1) { - commands.remove::(); - } - if keycode.just_pressed(KeyCode::Digit2) { - commands.insert(ScreenSpaceAmbientOcclusionSettings { - quality_level: ScreenSpaceAmbientOcclusionQualityLevel::Low, - }); - } - if keycode.just_pressed(KeyCode::Digit3) { - commands.insert(ScreenSpaceAmbientOcclusionSettings { - quality_level: ScreenSpaceAmbientOcclusionQualityLevel::Medium, - }); - } - if keycode.just_pressed(KeyCode::Digit4) { - commands.insert(ScreenSpaceAmbientOcclusionSettings { - quality_level: ScreenSpaceAmbientOcclusionQualityLevel::High, - }); - } - if keycode.just_pressed(KeyCode::Digit5) { - commands.insert(ScreenSpaceAmbientOcclusionSettings { - quality_level: ScreenSpaceAmbientOcclusionQualityLevel::Ultra, - }); + commands = commands.remove::(); } if keycode.just_pressed(KeyCode::Space) { if temporal_jitter.is_some() { diff --git a/examples/animation/animation_graph.rs b/examples/animation/animation_graph.rs index bfb9b66371..50423e21fb 100644 --- a/examples/animation/animation_graph.rs +++ b/examples/animation/animation_graph.rs @@ -310,7 +310,7 @@ fn setup_node_rects(commands: &mut Commands) { )); if let NodeType::Clip(ref clip) = node_type { - container.insert(( + container = container.insert(( Interaction::None, RelativeCursorPosition::default(), (*clip).clone(), diff --git a/examples/ecs/observers.rs b/examples/ecs/observers.rs index aae7d446e9..cd06fef3ab 100644 --- a/examples/ecs/observers.rs +++ b/examples/ecs/observers.rs @@ -148,7 +148,7 @@ fn on_remove_mine( fn explode_mine(trigger: Trigger, query: Query<&Mine>, mut commands: Commands) { // If a triggered event is targeting a specific entity you can access it with `.entity()` let id = trigger.entity(); - let Some(mut entity) = commands.get_entity(id) else { + let Some(entity) = commands.get_entity(id) else { return; }; info!("Boom! {:?} exploded.", id.index()); diff --git a/examples/games/game_menu.rs b/examples/games/game_menu.rs index f93c258a62..5c5f1c4752 100644 --- a/examples/games/game_menu.rs +++ b/examples/games/game_menu.rs @@ -743,7 +743,7 @@ mod menu { button_text_style.clone(), )); for volume_setting in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] { - let mut entity = parent.spawn(( + let entity = parent.spawn(( ButtonBundle { style: Style { width: Val::Px(30.0), diff --git a/examples/stress_tests/many_buttons.rs b/examples/stress_tests/many_buttons.rs index 027a4af20c..d85d25e2c4 100644 --- a/examples/stress_tests/many_buttons.rs +++ b/examples/stress_tests/many_buttons.rs @@ -257,7 +257,7 @@ fn spawn_button( )); if let Some(image) = image { - builder.insert(UiImage::new(image)); + builder = builder.insert(UiImage::new(image)); } if spawn_text { diff --git a/examples/stress_tests/many_cubes.rs b/examples/stress_tests/many_cubes.rs index a10ced7d0f..3c04b85ea5 100644 --- a/examples/stress_tests/many_cubes.rs +++ b/examples/stress_tests/many_cubes.rs @@ -163,26 +163,23 @@ fn setup( fibonacci_spiral_on_sphere(golden_ratio, i, N_POINTS); let unit_sphere_p = spherical_polar_to_cartesian(spherical_polar_theta_phi); let (mesh, transform) = meshes.choose(&mut material_rng).unwrap(); - let mut cube = commands.spawn(PbrBundle { - mesh: mesh.clone(), - material: materials.choose(&mut material_rng).unwrap().clone(), - transform: Transform::from_translation((radius * unit_sphere_p).as_vec3()) - .looking_at(Vec3::ZERO, Vec3::Y) - .mul_transform(*transform), - ..default() - }); - if args.no_frustum_culling { - cube.insert(NoFrustumCulling); - } - if args.no_automatic_batching { - cube.insert(NoAutomaticBatching); - } + commands + .spawn(PbrBundle { + mesh: mesh.clone(), + material: materials.choose(&mut material_rng).unwrap().clone(), + transform: Transform::from_translation((radius * unit_sphere_p).as_vec3()) + .looking_at(Vec3::ZERO, Vec3::Y) + .mul_transform(*transform), + ..default() + }) + .insert_if(NoFrustumCulling, || args.no_frustum_culling) + .insert_if(NoAutomaticBatching, || args.no_automatic_batching); } // camera let mut camera = commands.spawn(Camera3dBundle::default()); if args.gpu_culling { - camera.insert(GpuCulling); + camera = camera.insert(GpuCulling); } if args.no_cpu_culling { camera.insert(NoCpuCulling); diff --git a/examples/stress_tests/transform_hierarchy.rs b/examples/stress_tests/transform_hierarchy.rs index 404dc4cf82..0b95d5705d 100644 --- a/examples/stress_tests/transform_hierarchy.rs +++ b/examples/stress_tests/transform_hierarchy.rs @@ -413,7 +413,7 @@ fn spawn_tree( && (depth >= update_filter.min_depth && depth <= update_filter.max_depth); if update { - cmd.insert(UpdateValue(sep)); + cmd = cmd.insert(UpdateValue(sep)); result.active_nodes += 1; } @@ -426,7 +426,7 @@ fn spawn_tree( }; // only insert the components necessary for the transform propagation - cmd.insert(TransformBundle::from(transform)); + cmd = cmd.insert(TransformBundle::from(transform)); cmd.id() };