See More

use hecs::{Component, Entity, World}; /// Function to remove an event from the ECS. type EventRemoveFn = fn(&mut World, Entity); fn entity_event_remove_fn() -> EventRemoveFn { |ecs, entity| { let _ = ecs.remove_one::(entity); } } fn event_remove_fn(world: &mut World, event_entity: Entity) { let _ = world.despawn(event_entity); } /// Maintains a set of events that need to be removed /// from entities. /// /// An event's lifecycle is as follows: /// 1. The event is added as a component to its entity /// by calling `Ecs::insert_event`. The system that /// inserts the event is called the "triggering system." /// 2. Each system runs and has exactly one chance to observe /// the event through a query. /// 3. Immediately before the triggering system runs again, /// the event is removed from the entity. #[derive(Default)] pub struct EventTracker { /// Events to remove from entities. /// /// Indexed by the index of the triggering system. events: Vec>, current_system_index: usize, } impl EventTracker { /// Adds an entity event to be tracked. pub fn insert_entity_event(&mut self, entity: Entity) { let events_vec = self.current_events_vec(); events_vec.push((entity, entity_event_remove_fn::())) } /// Adds an event to be tracked. pub fn insert_event(&mut self, event_entity: Entity) { let events_vec = self.current_events_vec(); events_vec.push((event_entity, event_remove_fn)); } /// Adds a custom function to run /// before the current systems executes again. #[allow(unused)] pub fn insert_custom(&mut self, entity: Entity, callback: fn(&mut World, Entity)) { let events_vec = self.current_events_vec(); events_vec.push((entity, callback)); } pub fn set_current_system_index(&mut self, index: usize) { self.current_system_index = index; } /// Deletes events that were triggered on the previous tick /// by the current system. pub fn remove_old_events(&mut self, world: &mut World) { let events_vec = self.current_events_vec(); for (entity, remove_fn) in events_vec.drain(..) { remove_fn(world, entity); } } fn current_events_vec(&mut self) -> &mut Vec<(Entity, EventRemoveFn)> { while self.events.len() <= self.current_system_index { self.events.push(Vec::new()); } &mut self.events[self.current_system_index] } }