Skip to content

FastEventBus

Ultra-fast, lock-free, zero-allocation event bus without reflection or hash-maps.

Overview

FastEventBus is the high-performance event bus engine powering UniGUI. Designed specifically for performance-critical scenarios such as game rendering loops and input dispatching, it eliminates runtime reflection, hash map lookups, and allocation garbage during dispatch.

Zero-Garbage Architecture

Traditional event buses use class-to-method reflection maps or string identifiers, which generate iterator allocations, boxing overhead, and hash lookups on every dispatch.

FastEventBus solves this through dense integer indexing:

  • EventType<T>: Each event type receives an automatically assigned sequential integer index (id = 0, 1, 2...).
  • AtomicReferenceArray: Listeners are stored in contiguous typed arrays indexed directly by event ID.
  • Direct Iteration: fire() directly indexes into the array and loops through listeners with zero intermediate objects.

Concurrency & Thread Safety

The bus uses lock-free reads combined with copy-on-write writes:

  • fire(): Entirely lock-free. Reads the current listener array atomically and iterates over it.
  • subscribe() / unsubscribe(): Synchronized and use Copy-On-Write array duplication, keeping reader threads completely unblocked.
  • Exception Isolation: Exceptions thrown inside a listener callback are caught and logged via SLF4J, ensuring one broken handler never halts dispatch to other listeners.

Subscribe and fire

FastEventBus.EventType<String> CHAT_EVENT = new FastEventBus.EventType<>("chat");
FastEventBus bus = FastEventBus.DEFAULT_BUS;

EventSubscription sub = bus.subscribe(CHAT_EVENT, msg -> {
    System.out.println("Received: " + msg);
});

bus.fire(CHAT_EVENT, "Hello World!");
sub.unsubscribe();

Custom record event

public record PlayerScore(String player, int score) {}
public static final FastEventBus.EventType<PlayerScore> SCORE = new FastEventBus.EventType<>("score");

FastEventBus.DEFAULT_BUS.subscribe(SCORE, e -> {
    System.out.printf("%s scored %d points%n", e.player(), e.score());
});

FastEventBus.DEFAULT_BUS.fire(SCORE, new PlayerScore("Alex", 100));

API

FastEventBus::subscribe(EventType, EventListener)

Subscribe listener

Registers a listener for an event type using copy-on-write.

Parameter Type Description
type EventType Unique event type token
listener EventListener Listener callback

Returns EventSubscription: EventSubscription handle to unregister.

FastEventBus::unsubscribe(EventType, EventListener)

Unsubscribe listener

Removes a listener using copy-on-write array shrinking.

Parameter Type Description
type EventType Event type token
listener EventListener Listener to remove

FastEventBus::fire(EventType, Object)

Fire event

Dispatches an event lock-free with zero garbage allocation.

Parameter Type Description
type EventType Event type token
event Object Event payload data