use bevy::prelude::*;
use std::marker::PhantomData;
#[derive(Component, Debug, PartialEq, Eq, Reflect)]
#[relationship_target(relationship = PeriodicEffectTarget<T>, linked_spawn)]
#[reflect(Component, FromWorld)]
pub struct PeriodicEffectTargets<T: Reflect> {
#[entities]
#[relationship]
entities: Vec<Entity>,
#[reflect(ignore)]
_pd: PhantomData<T>,
}
impl<T: Reflect> Default for PeriodicEffectTargets<T> {
fn default() -> Self {
Self {
entities: Vec::new(),
_pd: PhantomData,
}
}
}
impl<T: Reflect> PeriodicEffectTargets<T> {
pub fn iter(&self) -> impl Iterator<Item = Entity> + '_ {
self.entities.iter().copied()
}
}
#[derive(Component, Clone, Debug, Reflect)]
#[relationship(relationship_target = PeriodicEffectTargets<T>)]
#[reflect(Component, FromWorld, Default)]
pub struct PeriodicEffectTarget<T: Reflect> {
#[entities]
#[relationship]
pub entity: Entity,
#[reflect(ignore)]
_pd: PhantomData<T>,
}
impl<T: Reflect> Default for PeriodicEffectTarget<T> {
fn default() -> Self {
Self {
entity: Entity::PLACEHOLDER,
_pd: PhantomData,
}
}
}
impl<T: Reflect> PeriodicEffectTarget<T> {
pub fn new(entity: Entity) -> Self {
Self {
entity,
_pd: PhantomData,
}
}
}
#[derive(EntityEvent, Clone, Debug, Reflect)]
pub struct PeriodicTick<T: Reflect> {
#[event_target]
pub target: Entity,
pub source: Entity,
#[reflect(ignore)]
_pd: PhantomData<T>,
}
impl<T: Reflect> PeriodicTick<T> {
pub fn new(source: Entity, target: Entity) -> Self {
Self {
target,
source,
_pd: PhantomData,
}
}
}
pub fn periodic_tick_system<T: Reflect + Component>(
q_effects: Query<(Entity, &PeriodicEffectTargets<T>)>,
mut commands: Commands,
) {
for (source, targets) in q_effects.iter() {
for target in targets.iter() {
commands.trigger(PeriodicTick::<T>::new(source, target));
}
}
}