use parking_lot::Mutex; use specs::Entity as EcsEntity; use std::{collections::VecDeque, ops::DerefMut}; use vek::*; pub enum Event { LandOnGround { entity: EcsEntity, vel: Vec3 }, Explosion { pos: Vec3, radius: f32 }, } #[derive(Default)] pub struct EventBus { queue: Mutex>, } impl EventBus { pub fn emitter(&self) -> Emitter { Emitter { bus: self, events: VecDeque::new(), } } pub fn emit(&self, event: Event) { self.queue.lock().push_front(event); } pub fn recv_all(&self) -> impl ExactSizeIterator { std::mem::replace(self.queue.lock().deref_mut(), VecDeque::new()).into_iter() } } pub struct Emitter<'a> { bus: &'a EventBus, events: VecDeque, } impl<'a> Emitter<'a> { pub fn emit(&mut self, event: Event) { self.events.push_front(event); } } impl<'a> Drop for Emitter<'a> { fn drop(&mut self) { self.bus.queue.lock().append(&mut self.events); } }