use bevy::app::App;
use bevy::prelude::*;
use std::sync::mpsc::{channel, Receiver, Sender};
use std::sync::Mutex;
#[derive(Resource, Deref, DerefMut)]
pub struct EventSender<T>(pub Sender<T>);
#[derive(Resource, Deref, DerefMut)]
struct EventReceiver<T>(Mutex<Receiver<T>>);
pub trait AsyncEventApp {
fn add_async_event<T: Event>(&mut self) -> &mut Self;
}
impl AsyncEventApp for App {
fn add_async_event<T: Event>(&mut self) -> &mut Self {
if self.world.contains_resource::<EventReceiver<T>>() {
return self;
}
let (sender, receiver) = channel::<T>();
self.add_event::<T>()
.add_systems(Update, channel_to_event::<T>)
.insert_resource(EventSender(sender))
.insert_resource(EventReceiver(Mutex::new(receiver)));
self
}
}
fn channel_to_event<T: Event>(receiver: Res<EventReceiver<T>>, mut writer: EventWriter<T>) {
let events = receiver.lock().expect("unable to acquire mutex lock");
writer.send_batch(events.try_iter());
}