barker
A small, synchronous, trait-object event bus for Rust — type-safe handlers, TTL, and a static global for low-ceremony use.
Usage
use ;
use Arc;
use ;
use ;
// 1. Any '`static + Send + Sync + Debug` type can be a message.
;
// 2. Handlers see `&dyn Message`; downcast to the concrete type to read fields.
;
Prefer a process-wide bus? barker::send, barker::register_handler, and barker::process_messages are free-function wrappers around MessageBus::global().
Design overview
- Trait-based messages. Any
'static + Send + Sync + Debugtype implementingMessagecan flow through the bus. There is no centralenum, so downstream crates extend the message vocabulary without modifying barker. - Filtering: typed vs generic handlers. Registering a handler with
Some(TypeId::of::<T>())makes it fire only for messages of typeT. Registering withNonemakes it a generic handler that fires for every message. Matching usesstd::any::TypeId. - Buffered send, explicit drain.
sendenqueues onto an internalflumechannel and returns. Handlers do not run untilprocess_messagesis called — typically once per frame, per tick, or at some other coarse cadence your application controls. - TTL enforcement. A message can return
Some(Duration)fromMessage::ttl(); if the drain encounters it past its expiry, it is silently skipped. - Registration-order dispatch. Within a single drain, handlers fire in the order they were registered. Fan-out (multiple handlers for the same
TypeId) is supported and each handler runs to completion before the next.
Aspirational metadata
The Message trait declares priority() and requires_ack(), but the drain does not currently consult either:
priority()is not used to reorder dispatch. Handlers fire in registration order regardless of the priorities of pending messages.requires_ack()has no acknowledgement plumbing. Senders cannot observe whether a message was received.
These methods are preserved on the trait for forward compatibility; document your own conventions per-message, but do not rely on the bus to honour them.
Origin
Extracted from the VITRIOL game engine, where the bus decouples input, window, and system events across the plugin architecture.
License
Dual-licensed under either of MIT or Apache-2.0 at your option.