pkecs 9.0.0

Another ECS implementation.
Documentation
//! Types for storing event handlers.

use std::any::Any;
use super::handler::EventHandler;
use crate::ecs::world::UnsafeWorldCell;

use super::queue::{EventQueue, ErasedEventQueue};
/// Contains event handlers of a specific type.
pub struct EventChannel<E> {
    /// Registered handlers for the event channel.
    handlers: Vec<Box<dyn EventHandler<E>>>,
}

impl<E> EventChannel<E> {
    /// Initializes a new, empty instance of [`self`].
    pub fn new() -> Self {
        let handlers = vec![];

        Self { handlers }
    }

    /// Initializes a new, empty instance of [`self`] in a [`Box`].
    pub fn new_box() -> Box<Self> {
        let this = Self::new();

        Box::new(this)
    }

    /// Adds an [`EventHandler`] to the channel.
    pub fn register<H>(&mut self, handler: H)
        where
            H: EventHandler<E> + 'static,
    {
        let handler = Box::new(handler);

        self.handlers.push(handler);
    }

    /// Queues an event onto the back of [`self`].
    pub fn trigger(&self, event: &E, cell: &UnsafeWorldCell) {
        self.handlers
            .iter()
            .for_each(|h| h.trigger(event, cell))
    }
}

/// A type-erased wrapper over a channel of typed event handlers.
pub trait ErasedEventChannel {
    /// Casts [`self`] to [`Any`].
    fn as_any_mut(&mut self) -> &mut dyn Any;

    /// Executes all events in the queue.
    fn trigger_all(&self, queue: &mut dyn ErasedEventQueue, cell: &UnsafeWorldCell);
}

impl<E> ErasedEventChannel for EventChannel<E>
    where
        E: 'static,
{
    fn as_any_mut(&mut self) -> &mut dyn Any {
        self
    }

    fn trigger_all(&self, queue: &mut dyn ErasedEventQueue, cell: &UnsafeWorldCell) {
        queue
            .as_any_mut()
            .downcast_mut::<EventQueue<E>>()
            .map(|queue| queue.drain())
            .map(|events| {
                events.for_each(|e| self.trigger(&e, cell));
            });
    }
}