use crate::prelude::*;
use bevy::ecs::system::Commands;
use bevy::prelude::*;
use bevy::utils::all_tuples;
use smallvec::SmallVec;
pub trait ReactionTrigger: Copy + Clone + Send + Sync + 'static
{
fn reactor_type(&self) -> ReactorType;
fn register(&self, commands: &mut Commands, handle: &ReactorHandle);
}
impl<R: ReactionTrigger> ReactionTriggerBundle for R
{
fn len(&self) -> usize { 1 }
fn collect_reactor_types(self, func: &mut impl FnMut(ReactorType))
{
func(self.reactor_type());
}
fn register_triggers(self, commands: &mut Commands, handle: &ReactorHandle)
{
self.register(commands, handle);
}
}
pub trait EntityTrigger: Copy + Clone + Send + Sync + 'static
{
fn new_trigger(entity: Entity) -> Self;
fn entity(&self) -> Entity;
}
impl<E: EntityTrigger> EntityTriggerBundle for E
{
fn new_bundle(entity: Entity) -> Self
{
Self::new_trigger(entity)
}
}
pub trait ReactionTriggerBundle: Copy + Clone + Send + Sync + 'static
{
fn len(&self) -> usize;
fn collect_reactor_types(self, func: &mut impl FnMut(ReactorType));
fn register_triggers(
self,
commands : &mut Commands,
handle : &ReactorHandle,
);
}
pub trait EntityTriggerBundle
{
fn new_bundle(entity: Entity) -> Self;
}
pub fn get_reactor_types(bundle: impl ReactionTriggerBundle) -> SmallVec<[ReactorType; 10]>
{
let mut reactors = SmallVec::<[ReactorType; 10]>::with_capacity(bundle.len());
let mut func =
|reactor_type: ReactorType|
{
reactors.push(reactor_type);
};
bundle.collect_reactor_types(&mut func);
reactors
}
macro_rules! tuple_impl
{
($($name: ident),*) =>
{
impl<$($name: ReactionTriggerBundle),*> ReactionTriggerBundle for ($($name,)*)
{
#[allow(unused_variables, unused_mut)]
#[inline(always)]
fn len(&self) -> usize
{
let mut len = 0;
#[allow(non_snake_case)]
let ($($name,)*) = self;
$(
len += $name.len();
)*
len
}
#[allow(unused_variables, unused_mut)]
#[inline(always)]
fn collect_reactor_types(self, func: &mut impl FnMut(ReactorType))
{
#[allow(non_snake_case)]
let ($(mut $name,)*) = self;
$(
$name.collect_reactor_types(&mut *func);
)*
}
#[allow(unused_variables, unused_mut)]
#[inline(always)]
fn register_triggers(
self,
commands : &mut Commands,
handle : &ReactorHandle,
){
#[allow(non_snake_case)]
let ($(mut $name,)*) = self;
$(
$name.register_triggers(commands, handle);
)*
}
}
}
}
all_tuples!(tuple_impl, 0, 15, B);
macro_rules! tuple_impl
{
($($name: ident),*) =>
{
impl<$($name: EntityTriggerBundle),*> EntityTriggerBundle for ($($name,)*)
{
#[allow(unused_variables, unused_mut)]
#[inline(always)]
fn new_bundle(entity: Entity) -> Self
{
#[allow(non_snake_case)]
($(
$name::new_bundle(entity),
)*)
}
}
}
}
all_tuples!(tuple_impl, 1, 15, B);