deepslate 0.3.1

A high-performance Minecraft server proxy written in Rust.
Documentation
//! Type-erased event handler and observer storage.
//!
//! Provides the internal plumbing that makes the type-safe public API work:
//! handlers and observers are stored as trait objects keyed by `TypeId`, and
//! downcast back to the concrete event type when dispatched.

use std::any::Any;
use std::cmp::Reverse;

use super::priority::PostOrder;

// ---------------------------------------------------------------------------
// Handlers (mutable access — &mut E)
// ---------------------------------------------------------------------------

/// A type-erased event handler that can be stored in a heterogeneous collection.
///
/// This is an internal trait — users interact with the type-safe
/// `EventManager::subscribe` API instead.
pub(crate) trait ErasedHandler: Send + Sync {
    /// Call the handler with a type-erased event reference.
    ///
    /// The implementation downcasts to the concrete event type. Panics if
    /// the wrong type is passed (should never happen — the `EventManager`
    /// guarantees correct dispatch by `TypeId`).
    fn call(&self, event: &mut dyn Any);
}

/// Wrapper that implements `ErasedHandler` for a concrete `Fn(&mut E)` closure.
pub(crate) struct TypedHandler<E: 'static> {
    handler: Box<dyn Fn(&mut E) + Send + Sync>,
}

impl<E: 'static> TypedHandler<E> {
    pub(crate) fn new(handler: impl Fn(&mut E) + Send + Sync + 'static) -> Self {
        Self {
            handler: Box::new(handler),
        }
    }
}

impl<E: 'static> ErasedHandler for TypedHandler<E> {
    fn call(&self, event: &mut dyn Any) {
        let event = event
            .downcast_mut::<E>()
            .expect("EventManager dispatched wrong event type to handler");
        (self.handler)(event);
    }
}

/// A registered handler with its priority and metadata.
pub(crate) struct HandlerRegistration {
    /// Execution priority (higher values execute first).
    pub(crate) priority: PostOrder,
    /// The type-erased handler.
    pub(crate) handler: Box<dyn ErasedHandler>,
}

/// Sort handler registrations by priority (highest first).
///
/// Uses `Reverse` so that higher priority values sort earlier. Handlers at
/// the same priority level retain their registration order (stable sort).
pub(crate) fn sort_handlers(handlers: &mut [HandlerRegistration]) {
    handlers.sort_by_key(|h| Reverse(h.priority));
}

// ---------------------------------------------------------------------------
// Observers (immutable access — &E)
// ---------------------------------------------------------------------------

/// A type-erased event observer that receives a shared reference to the event.
///
/// Unlike [`ErasedHandler`], observers cannot modify the event. This
/// compile-time guarantee makes them safe to run in parallel in the future.
pub(crate) trait ErasedObserver: Send + Sync {
    /// Call the observer with a type-erased shared event reference.
    ///
    /// The implementation downcasts to the concrete event type. Panics if
    /// the wrong type is passed (should never happen — the `EventManager`
    /// guarantees correct dispatch by `TypeId`).
    fn call(&self, event: &dyn Any);
}

/// Wrapper that implements `ErasedObserver` for a concrete `Fn(&E)` closure.
pub(crate) struct TypedObserver<E: 'static> {
    observer: Box<dyn Fn(&E) + Send + Sync>,
}

impl<E: 'static> TypedObserver<E> {
    pub(crate) fn new(observer: impl Fn(&E) + Send + Sync + 'static) -> Self {
        Self {
            observer: Box::new(observer),
        }
    }
}

impl<E: 'static> ErasedObserver for TypedObserver<E> {
    fn call(&self, event: &dyn Any) {
        let event = event
            .downcast_ref::<E>()
            .expect("EventManager dispatched wrong event type to observer");
        (self.observer)(event);
    }
}

/// A registered observer (no priority — observers run in registration order).
pub(crate) struct ObserverRegistration {
    /// The type-erased observer.
    pub(crate) observer: Box<dyn ErasedObserver>,
}

// ---------------------------------------------------------------------------
// EventPipeline
// ---------------------------------------------------------------------------

/// Per-event-type dispatch pipeline holding observers and handlers.
///
/// Dispatch order:
/// 1. Pre-observers (`&E`, registration order)
/// 2. Handlers (`&mut E`, priority order)
/// 3. Post-observers (`&E`, registration order)
#[derive(Default)]
pub(crate) struct EventPipeline {
    /// Observers that run before any handler.
    pub(crate) pre_observers: Vec<ObserverRegistration>,
    /// Mutable handlers, sorted by priority (highest first).
    pub(crate) handlers: Vec<HandlerRegistration>,
    /// Observers that run after all handlers.
    pub(crate) post_observers: Vec<ObserverRegistration>,
}