Conduit usage

Register, post, repeat.

Conduit keeps the API small: implement Event, annotate listeners, and post events. This page covers the dispatch rules and the few knobs available.

Quickstart

A minimal setup.

Basic bus + listener
public final class PlayerJoin implements Event {
  private final String name;
  public PlayerJoin(String name) { this.name = name; }
  public String getName() { return name; }
}

public final class JoinListener {
  @Subscribe
  public void onJoin(PlayerJoin event) {
    System.out.println("Hello, " + event.getName());
  }
}

EventBus bus = new EventBus();
JoinListener listener = new JoinListener();
bus.register(listener);

bus.post(new PlayerJoin("Nova"));

@Subscribe

Listener methods must be instance methods with exactly one parameter that implements Event.

Annotation options
priority

Order: HIGHEST to LOWEST. Same priority uses registration order.

ignoreCancelled

Skip cancelled events when the event implements Cancellable.

receiveSubtypes

If true, handlers for type T also receive subtypes of T.

once

Unregister the handler after the first call.

Dispatch rules

Conduit dispatches synchronously by default. Handlers are sorted by priority then registration order for deterministic results.

Cancellation flow

If an event implements Cancellable and a handler calls setCancelled(true), remaining handlers marked ignoreCancelled are skipped.

Weak listener references

Listeners are stored with weak references. Keep a strong reference to listener instances in your code, or they can be collected and automatically unregistered.

Async posting

Construct the bus with an Executor to enable postAsync. This returns a CompletableFuture that completes once dispatch is done.

Async example
Executor executor = Executors.newCachedThreadPool();
EventBus bus = new EventBus(executor);

bus.postAsync(new PlayerJoin("Ivy"))
  .thenAccept(event -> System.out.println("Posted: " + event));

Diagnostics + error handling

If an event has no handlers, Conduit can publish a DeadEvent when something is listening for it. Errors inside handlers are reported through an ErrorHandler callback (defaults to stderr).

Custom error handler
EventBus.ErrorHandler handler = (event, listener, method, error) -> {
  System.err.println("Boom in " + listener.getClass().getSimpleName());
  error.printStackTrace();
};

EventBus bus = new EventBus(null, handler);