Replaced EntityCommand Implementation for FnOnce (#9604)

# Objective

- Fixes #4917
- Replaces #9602

## Solution

- Replaced `EntityCommand` implementation for `FnOnce` to apply to
`FnOnce(EntityMut)` instead of `FnOnce(Entity, &mut World)`

---

## Changelog

- `FnOnce(Entity, &mut World)` no longer implements `EntityCommand`.
This is a breaking change.

## Migration Guide

### 1. New-Type `FnOnce`

Create an `EntityCommand` type which implements the method you
previously wrote:

```rust
pub struct ClassicEntityCommand<F>(pub F);

impl<F> EntityCommand for ClassicEntityCommand<F>
where
    F: FnOnce(Entity, &mut World) + Send + 'static,
{
    fn apply(self, id: Entity, world: &mut World) {
        (self.0)(id, world);
    }
}

commands.add(ClassicEntityCommand(|id: Entity, world: &mut World| {
    /* ... */
}));
```

### 2. Extract `(Entity, &mut World)` from `EntityMut`

The method `into_world_mut` can be used to gain access to the `World`
from an `EntityMut`.

```rust
let old = |id: Entity, world: &mut World| {
    /* ... */
};

let new = |mut entity: EntityMut| {
    let id = entity.id();
    let world = entity.into_world_mut();
    /* ... */
};
```
This commit is contained in:
Zachary Harrold 2023-08-29 04:08:53 +10:00 committed by GitHub
parent a47a5b30fe
commit 1839ff7e2a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -5,7 +5,7 @@ use crate::{
self as bevy_ecs,
bundle::Bundle,
entity::{Entities, Entity},
world::{FromWorld, World},
world::{EntityMut, FromWorld, World},
};
use bevy_ecs_macros::SystemParam;
use bevy_utils::tracing::{error, info};
@ -805,12 +805,13 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> {
///
/// ```
/// # use bevy_ecs::prelude::*;
/// # use bevy_ecs::world::EntityMut;
/// # fn my_system(mut commands: Commands) {
/// commands
/// .spawn_empty()
/// // Closures with this signature implement `EntityCommand`.
/// .add(|id: Entity, world: &mut World| {
/// println!("Executed an EntityCommand for {id:?}");
/// .add(|entity: EntityMut| {
/// println!("Executed an EntityCommand for {:?}", entity.id());
/// });
/// # }
/// # bevy_ecs::system::assert_is_system(my_system);
@ -848,10 +849,10 @@ where
impl<F> EntityCommand for F
where
F: FnOnce(Entity, &mut World) + Send + 'static,
F: FnOnce(EntityMut) + Send + 'static,
{
fn apply(self, id: Entity, world: &mut World) {
self(id, world);
self(world.entity_mut(id));
}
}