use std::sync::mpsc::Receiver;
use std::sync::Mutex;
use bevy::prelude::*;
use crate::{PhysicsSchedule, PhysicsSet};
#[derive(Resource, Deref, DerefMut)]
struct ChannelReceiver<T>(Mutex<Receiver<T>>);
pub trait AppExtensions {
fn add_physics_event<T: Event>(&mut self) -> &mut Self;
fn add_event_channel<T: Event>(&mut self, receiver: Receiver<T>) -> &mut Self;
fn add_physics_event_channel<T: Event>(&mut self, receiver: Receiver<T>) -> &mut Self;
}
impl AppExtensions for App {
fn add_physics_event<T: Event>(&mut self) -> &mut Self {
if !self.world.contains_resource::<Events<T>>() {
self.init_resource::<Events<T>>();
self.add_systems(PhysicsSchedule, (
Events::<T>::update_system,
).before(PhysicsSet::Create));
}
self
}
fn add_event_channel<T: Event>(&mut self, receiver: Receiver<T>) -> &mut Self {
assert!(
!self.world.contains_resource::<ChannelReceiver<T>>(),
"this event channel is already initialized",
);
self.add_event::<T>();
self.add_systems(PhysicsSchedule, (
channel_to_event::<T>,
).after(Events::<T>::update_system).before(PhysicsSet::Create));
self.insert_resource(ChannelReceiver(Mutex::new(receiver)));
self
}
fn add_physics_event_channel<T: Event>(&mut self, receiver: Receiver<T>) -> &mut Self {
assert!(
!self.world.contains_resource::<ChannelReceiver<T>>(),
"this event channel is already initialized",
);
self.add_physics_event::<T>();
self.add_systems(PhysicsSchedule, (
channel_to_event::<T>,
).after(Events::<T>::update_system).before(PhysicsSet::Create));
self.insert_resource(ChannelReceiver(Mutex::new(receiver)));
self
}
}
fn channel_to_event<T: Event>(
receiver: Res<ChannelReceiver<T>>,
mut writer: EventWriter<T>,
) {
let events = receiver.lock().expect("unable to acquire mutex lock");
writer.send_batch(events.try_iter());
}