use bevy_ecs::prelude::{Component, Entity};
use bevy_hierarchy::DespawnRecursiveExt;
use crate::{
add_lifecycle_dependency, Collection, Impulsive, Input, InputBundle, ManageInput,
OperationRequest, OperationResult, OperationSetup, OrBroken, Storage,
};
#[derive(Component)]
pub(crate) struct Push<T> {
target: Entity,
is_stream: bool,
_ignore: std::marker::PhantomData<fn(T)>,
}
impl<T> Push<T> {
pub(crate) fn new(target: Entity, is_stream: bool) -> Self {
Self {
target,
is_stream,
_ignore: Default::default(),
}
}
}
impl<T: 'static + Send + Sync> Impulsive for Push<T> {
fn setup(self, OperationSetup { source, world }: OperationSetup) -> OperationResult {
if !self.is_stream {
add_lifecycle_dependency(source, self.target, world);
}
world
.entity_mut(source)
.insert((InputBundle::<T>::new(), self));
Ok(())
}
fn execute(OperationRequest { source, world, .. }: OperationRequest) -> OperationResult {
let mut source_mut = world.get_entity_mut(source).or_broken()?;
let Input { session, data } = source_mut.take_input::<T>()?;
let target = source_mut.get::<Push<T>>().or_broken()?.target;
let mut target_mut = world.get_entity_mut(target).or_broken()?;
if let Some(mut collection) = target_mut.get_mut::<Collection<T>>() {
collection.items.push(Storage { session, data });
} else {
let mut collection = Collection::default();
collection.items.push(Storage { session, data });
target_mut.insert(collection);
}
world.entity_mut(source).despawn_recursive();
Ok(())
}
}