use bevy::prelude::{Bundle, Component, Entity};
use crate::{effects::EntityEffect, Cx};
pub struct InsertBundleEffect<B: Bundle, F: Fn(D) -> B, D: PartialEq + Clone> {
pub factory: F,
pub deps: D,
}
impl<B: Bundle, F: Fn(D) -> B + Send + Sync, D: PartialEq + Clone + Send + Sync> EntityEffect
for InsertBundleEffect<B, F, D>
{
type State = D;
fn apply(&self, cx: &mut Cx, target: Entity) -> Self::State {
let mut target = cx.world_mut().entity_mut(target);
target.insert((self.factory)(self.deps.clone()));
self.deps.clone()
}
fn reapply(&self, cx: &mut Cx, target: Entity, state: &mut Self::State) {
if *state != self.deps {
*state = self.apply(cx, target);
}
}
}
pub struct ConditionalInsertComponentEffect<B: Bundle, F: Fn() -> B> {
pub factory: F,
pub condition: bool,
}
impl<C: Component, F: Fn() -> C + Send + Sync> EntityEffect
for ConditionalInsertComponentEffect<C, F>
{
type State = bool;
fn apply(&self, cx: &mut Cx, target: Entity) -> Self::State {
if self.condition {
let mut target = cx.world_mut().entity_mut(target);
target.insert((self.factory)());
}
self.condition
}
fn reapply(&self, cx: &mut Cx, target: Entity, state: &mut Self::State) {
if self.condition != *state {
*state = self.condition;
if self.condition {
self.apply(cx, target);
} else {
let mut target = cx.world_mut().entity_mut(target);
target.remove::<C>();
}
}
}
}
pub struct StaticInsertBundleEffect<B: Bundle + Clone> {
pub bundle: B,
}
impl<B: Bundle + Clone> EntityEffect for StaticInsertBundleEffect<B> {
type State = ();
fn apply(&self, cx: &mut Cx, target: Entity) -> Self::State {
let mut target = cx.world_mut().entity_mut(target);
target.insert(self.bundle.clone());
}
fn reapply(&self, _cx: &mut Cx, _target: Entity, _state: &mut Self::State) {}
}