Skip to content

Commit

Permalink
Make standard commands more ergonomic (in niche cases) (#8249)
Browse files Browse the repository at this point in the history
# Objective

I ran into a case where I need to create a `CommandQueue` and push
standard `Command` actions like `Insert` or `Remove` to it manually. I
saw that `Remove` looked as follows:

```rust
struct Remove<T> {
  entity: Entity,
  phantom: PhantomData<T>
}
```

so naturally, I tried to use `Remove::<Foo>::from(entity)` but it didn't
exist. We need to specify the `PhantomData` explicitly when creating
this command action. The same goes for `RemoveResource` and
`InitResource`

## Solution

This PR implements the following:

- `From<Entity>` for `Remove<T>`
- `Default` for `RemoveResource` and `InitResource`
- use these traits in the implementation of methods of `Commands`
- rename `phantom` field on the structs above to `_phantom` to have a
more uniform field naming scheme for the command actions

---

## Changelog

> This section is optional. If this was a trivial fix, or has no
externally-visible impact, you can delete this section.

- Added: implemented `From<Entity>` for `Remove<T>` and `Default` for
`RemoveResource` and `InitResource` for ergonomics

---------

Co-authored-by: Alice Cecile <[email protected]>
  • Loading branch information
RobWalt and alice-i-cecile authored Mar 29, 2023
1 parent 36ada9d commit 5f0abbf
Showing 1 changed file with 31 additions and 10 deletions.
41 changes: 31 additions & 10 deletions crates/bevy_ecs/src/system/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,9 +444,7 @@ impl<'w, 's> Commands<'w, 's> {
/// # bevy_ecs::system::assert_is_system(initialise_scoreboard);
/// ```
pub fn init_resource<R: Resource + FromWorld>(&mut self) {
self.queue.push(InitResource::<R> {
_phantom: PhantomData::<R>::default(),
});
self.queue.push(InitResource::<R>::new());
}

/// Pushes a [`Command`] to the queue for inserting a [`Resource`] in the [`World`] with a specific value.
Expand Down Expand Up @@ -499,9 +497,7 @@ impl<'w, 's> Commands<'w, 's> {
/// # bevy_ecs::system::assert_is_system(system);
/// ```
pub fn remove_resource<R: Resource>(&mut self) {
self.queue.push(RemoveResource::<R> {
phantom: PhantomData,
});
self.queue.push(RemoveResource::<R>::new());
}

/// Pushes a generic [`Command`] to the command queue.
Expand Down Expand Up @@ -748,10 +744,7 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> {
where
T: Bundle,
{
self.commands.add(Remove::<T> {
entity: self.entity,
phantom: PhantomData,
});
self.commands.add(Remove::<T>::new(self.entity));
self
}

Expand Down Expand Up @@ -956,6 +949,16 @@ where
}
}

impl<T> Remove<T> {
/// Creates a [`Command`] which will remove the specified [`Entity`] when flushed
pub const fn new(entity: Entity) -> Self {
Self {
entity,
phantom: PhantomData::<T>,
}
}
}

pub struct InitResource<R: Resource + FromWorld> {
_phantom: PhantomData<R>,
}
Expand All @@ -966,6 +969,15 @@ impl<R: Resource + FromWorld> Command for InitResource<R> {
}
}

impl<R: Resource + FromWorld> InitResource<R> {
/// Creates a [`Command`] which will insert a default created [`Resource`] into the [`World`]
pub const fn new() -> Self {
Self {
_phantom: PhantomData::<R>,
}
}
}

pub struct InsertResource<R: Resource> {
pub resource: R,
}
Expand All @@ -986,6 +998,15 @@ impl<R: Resource> Command for RemoveResource<R> {
}
}

impl<R: Resource> RemoveResource<R> {
/// Creates a [`Command`] which will remove a [`Resource`] from the [`World`]
pub const fn new() -> Self {
Self {
phantom: PhantomData::<R>,
}
}
}

/// [`Command`] to log the components of a given entity. See [`EntityCommands::log_components`].
pub struct LogComponents {
entity: Entity,
Expand Down

0 comments on commit 5f0abbf

Please sign in to comment.