use bevy::app::AppBuilder;
pub trait EventSet {
fn apply(app: &mut AppBuilder);
}
pub trait AddEventSet {
fn add_event_set<E: EventSet>(&mut self) -> &mut Self;
}
impl AddEventSet for AppBuilder {
fn add_event_set<E: EventSet>(&mut self) -> &mut Self {
E::apply(self);
self
}
}
pub trait SendEvent<T> {
fn send(&mut self, event: T);
}
#[macro_export]
macro_rules! event_set {
($name:ident {}) => {
compile_error!("cannot make an empty event set");
};
($name:ident { $($event:ident),* $(,)? }) => {
#[allow(non_snake_case)]
#[derive(bevy::ecs::SystemParam)]
pub struct $name<'a> {
$(
$event: bevy::ecs::ResMut<'a, bevy::app::Events<$event>>,
)*
}
impl<'a> $crate::EventSet for $name<'a> {
fn apply(app: &mut bevy::app::AppBuilder) {
$(
app.add_event::<$event>();
)*
}
}
$(
impl<'a> $crate::SendEvent<$event> for $name<'a> {
fn send(&mut self, event: $event) {
self.$event.send(event)
}
}
)*
};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn single() {
struct TestEvent;
event_set!(MyEvents { TestEvent });
event_set!(MyEvents2 { TestEvent });
}
#[test]
fn multiple() {
struct TestEvent1(usize);
struct TestEvent2 {
number: usize,
}
event_set!(MyEvents {
TestEvent1,
TestEvent2
});
}
#[test]
fn add_to_builder() {
use bevy::app::App;
struct TestEvent;
event_set!(MyEvents { TestEvent });
App::build().add_event_set::<MyEvents>();
}
}