use crate::prelude::*;
use beet_core::prelude::*;
#[action(insert::<E , B>)]
#[derive(Debug, Component, Reflect)]
#[reflect(Component)]
pub struct InsertOn<E: EntityTargetEvent, B: Bundle + Clone> {
pub bundle: B,
pub target_entity: TargetEntity,
phantom: PhantomData<E>,
}
impl<E: EntityTargetEvent> InsertOn<E, OnSpawnClone> {
pub fn new_func<B: Bundle>(
bundle: impl 'static + Send + Sync + Clone + FnOnce() -> B,
) -> Self {
Self {
bundle: OnSpawnClone::new(move |entity| {
entity.insert(bundle.clone()());
}),
phantom: PhantomData,
target_entity: TargetEntity::default(),
}
}
}
impl<E: EntityTargetEvent, B: Bundle + Clone> InsertOn<E, B> {
pub fn new(bundle: B) -> Self {
Self {
bundle,
phantom: PhantomData,
target_entity: TargetEntity::default(),
}
}
pub fn new_with_target(bundle: B, target_entity: TargetEntity) -> Self {
Self {
bundle,
phantom: PhantomData,
target_entity,
}
}
}
impl<E: EntityTargetEvent, B: Bundle + Clone + Default> Default
for InsertOn<E, B>
{
fn default() -> Self {
Self {
bundle: default(),
phantom: default(),
target_entity: default(),
}
}
}
fn insert<E: EntityTargetEvent, B: Bundle + Clone>(
ev: On<E>,
mut commands: Commands,
query: Query<&InsertOn<E, B>>,
agent_query: AgentQuery,
) -> Result {
let action = ev.target();
let insert_on = query.get(action)?;
let target = insert_on.target_entity.get(action, &agent_query);
commands.entity(target).insert(insert_on.bundle.clone());
Ok(())
}
#[cfg(test)]
mod test {
use crate::prelude::*;
use beet_core::prelude::*;
#[test]
fn on_run() {
let mut app = App::new();
let world = app.world_mut();
let entity = world
.spawn(InsertOn::<GetOutcome, Running>::default())
.trigger_target(GetOutcome)
.flush()
.id();
world.get::<Running>(entity).xpect_some();
}
#[test]
fn on_result() {
let mut app = App::new();
app.add_plugins(ControlFlowPlugin::default());
let world = app.world_mut();
let entity = world
.spawn((
InsertOn::<Outcome, Running>::default(),
EndWith(Outcome::Pass),
))
.trigger_target(GetOutcome)
.flush()
.id();
world.get::<Running>(entity).xpect_some();
}
}