use bevy::prelude::*;
mod blanket_impls;
#[derive(Event)]
pub struct SpawnEvent<T, D = ()>
where
T: Eq + Send + Sync + 'static,
D: Send + Sync + 'static,
{
pub object: T,
pub data: D,
pub delay: Delay,
}
impl Default for Delay {
fn default() -> Self {
Self::Frames(0)
}
}
impl<T, D> SpawnEvent<T, D>
where
T: Eq + Send + Sync + 'static,
D: Default + Send + Sync + 'static,
{
pub fn new(object: T) -> SpawnEvent<T, D> {
SpawnEvent {
object,
data: default(),
delay: default(),
}
}
}
impl<T, D> SpawnEvent<T, D>
where
T: Eq + Send + Sync + 'static,
D: Send + Sync + 'static,
{
pub fn with_data(object: T, data: D) -> SpawnEvent<T, D> {
SpawnEvent {
object,
data,
delay: default(),
}
}
pub fn delay_frames(mut self, delay: usize) -> SpawnEvent<T, D> {
self.delay = Delay::Frames(delay);
self
}
pub fn delay_seconds(mut self, delay: f32) -> Self {
self.delay = Delay::Seconds(delay);
self
}
pub fn data(mut self, data: D) -> Self {
self.data = data;
self
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Delay {
Frames(usize),
Seconds(f32),
}
pub(crate) fn delay_spawn_events<T, D>(
time: Res<Time>,
mut delayed_spawn_events: ResMut<Events<SpawnEvent<T, D>>>,
mut spawn_event_writer: EventWriter<ReadySpawnEvent<T, D>>,
) where
T: Eq + Send + Sync + 'static,
D: Send + Sync + 'static,
{
let mut advanced_events = Vec::new();
for event in delayed_spawn_events.drain() {
match event.delay {
Delay::Frames(delay) => {
if delay == 0 {
spawn_event_writer.send(event.into());
} else {
advanced_events.push(SpawnEvent {
delay: Delay::Frames(delay - 1),
..event
});
}
}
Delay::Seconds(delay) => {
if delay <= 1e-5 {
spawn_event_writer.send(event.into());
} else {
advanced_events.push(SpawnEvent {
delay: Delay::Seconds(delay - time.delta_seconds()),
..event
});
}
}
}
}
for event in advanced_events {
delayed_spawn_events.send(event);
}
}
#[derive(Event)]
pub(crate) struct ReadySpawnEvent<T, D>
where
T: Eq + Send + Sync + 'static,
D: Send + Sync + 'static,
{
pub(crate) object: T,
pub(crate) data: D,
}
impl<T, D> From<SpawnEvent<T, D>> for ReadySpawnEvent<T, D>
where
T: Eq + Send + Sync + 'static,
D: Send + Sync + 'static,
{
fn from(event: SpawnEvent<T, D>) -> Self {
Self {
object: event.object,
data: event.data,
}
}
}