nightshade-api 0.45.0

Procedural high level API for the nightshade game engine
Documentation
//! A typed in-process message bus for participant-to-participant signals that
//! are not engine events: a quest system telling the HUD, an AI telling the
//! audio director. Broadcast a value of any type, drain values of that type
//! elsewhere this frame or next. It stays in process, so the payload is a live
//! value and never serializes, which is why this is a Rust-only api with no
//! command form.

use std::any::Any;
use std::collections::VecDeque;

use nightshade::ecs::event_bus::commands::publish_app_event;
use nightshade::ecs::event_bus::resources::Message;
use nightshade::prelude::*;

/// Broadcasts a typed message onto the bus. Any system can drain it with
/// [`drain_messages`] of the same type.
pub fn broadcast<T: Any + Send + Sync>(world: &mut World, message: T) {
    publish_app_event(world, message);
}

/// Drains every message of type `T` from the bus, returning them in order and
/// leaving messages of other types in place.
pub fn drain_messages<T: Any + Send + Sync>(world: &mut World) -> Vec<T> {
    let mut kept: VecDeque<Message> = VecDeque::new();
    let mut drained: Vec<T> = Vec::new();
    while let Some(message) = world.resources.event_bus.messages.pop_front() {
        match message {
            Message::App { type_name, payload } => match payload.downcast::<T>() {
                Ok(value) => drained.push(*value),
                Err(payload) => kept.push_back(Message::App { type_name, payload }),
            },
            other => kept.push_back(other),
        }
    }
    world.resources.event_bus.messages = kept;
    drained
}