Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions mvp-effects.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@
# Entity command effects:
- [x] `EntityCommandQueue<C>`

- [ ] `EntityCommandInsert`
- [ ] `EntityCommandRemove`
- [x] `EntityCommandInsert`
- [x] `EntityCommandRemove`
- [ ] `EntityCommandDespawn`

## Nice to have
Expand Down
108 changes: 108 additions & 0 deletions src/effects/entity_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,59 @@ where
}
}

/// [`Effect`] that queues a command for inserting the provided `Bundle` onto the `Entity`.
#[doc = include_str!("defer_command_note.md")]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct EntityCommandInsert<B>(pub Entity, pub B)
where
B: Bundle;

impl<B> Effect for EntityCommandInsert<B>
where
B: Bundle,
{
type MutParam = Commands<'static, 'static>;

fn affect(self, param: &mut <Self::MutParam as bevy::ecs::system::SystemParam>::Item<'_, '_>) {
param.entity(self.0).insert(self.1);
}
}

/// [`Effect`] that queues a command for removing the `Bundle` from the `Entity`.
#[doc = include_str!("defer_command_note.md")]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct EntityCommandRemove<B>
where
B: Bundle,
{
entity: Entity,
bundle: PhantomData<B>,
}

impl<B> EntityCommandRemove<B>
where
B: Bundle,
{
/// Construct a new [`EntityCommandRemove`]
pub fn new(entity: Entity) -> Self {
EntityCommandRemove {
entity,
bundle: PhantomData,
}
}
}

impl<B> Effect for EntityCommandRemove<B>
where
B: Bundle,
{
type MutParam = Commands<'static, 'static>;

fn affect(self, param: &mut <Self::MutParam as bevy::ecs::system::SystemParam>::Item<'_, '_>) {
param.entity(self.entity).remove::<B>();
}
}

#[cfg(test)]
mod tests {
use proptest::prelude::*;
Expand Down Expand Up @@ -82,5 +135,60 @@ mod tests {

assert_eq!(actual_component, &component);
}

#[test]
fn bundle_commands_correctly_insert_and_remove(component_0 in any::<NumberComponent<0>>(), component_1 in any::<NumberComponent<1>>()) {
let mut app = App::new();

let entity = app.world_mut().spawn(()).id();

let actual_component_0 = app.world().entity(entity).get::<NumberComponent<0>>();
let actual_component_1 = app.world().entity(entity).get::<NumberComponent<1>>();

assert!(actual_component_0.is_none());
assert!(actual_component_1.is_none());

#[derive(Debug, Clone, PartialEq, Eq, Hash, SystemSet)]
struct InsertSystem;

app.add_systems(
Update,
(move || EntityCommandInsert(entity, (component_0, component_1))).pipe(affect).in_set(InsertSystem),
);

app.update();

let actual_component_0 = app.world().entity(entity).get::<NumberComponent<0>>();
let actual_component_1 = app.world().entity(entity).get::<NumberComponent<1>>();

assert_eq!(actual_component_0, Some(&component_0));
assert_eq!(actual_component_1, Some(&component_1));

app.add_systems(
Update,
(move || EntityCommandRemove::<(NumberComponent<1>, NumberComponent<2>)>::new(entity)).pipe(affect).after(InsertSystem),
);

app.update();

let actual_component_0 = app.world().entity(entity).get::<NumberComponent<0>>();
let actual_component_1 = app.world().entity(entity).get::<NumberComponent<1>>();

assert_eq!(actual_component_0, Some(&component_0));
assert!(actual_component_1.is_none());

app.add_systems(
Update,
(move || EntityCommandRemove::<(NumberComponent<0>, NumberComponent<1>)>::new(entity)).pipe(affect).after(InsertSystem),
);

app.update();

let actual_component_0 = app.world().entity(entity).get::<NumberComponent<0>>();
let actual_component_1 = app.world().entity(entity).get::<NumberComponent<1>>();

assert!(actual_component_0.is_none());
assert!(actual_component_1.is_none());
}
}
}
2 changes: 1 addition & 1 deletion src/effects/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ mod command;
pub use command::{CommandInsertResource, CommandQueue, CommandRemoveResource};

mod entity_command;
pub use entity_command::EntityCommandQueue;
pub use entity_command::{EntityCommandInsert, EntityCommandQueue, EntityCommandRemove};

mod variadic;

Expand Down
2 changes: 2 additions & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ pub use crate::effects::{
CommandRemoveResource,
ComponentsPut,
ComponentsWith,
EntityCommandInsert,
EntityCommandQueue,
EntityCommandRemove,
EntityComponentsPut,
EntityComponentsWith,
EventWrite,
Expand Down