diff --git a/event-bus-core/src/main/java/dev/kske/eventbus/core/EventBus.java b/event-bus-core/src/main/java/dev/kske/eventbus/core/EventBus.java index 3eef15c..3d8113d 100644 --- a/event-bus-core/src/main/java/dev/kske/eventbus/core/EventBus.java +++ b/event-bus-core/src/main/java/dev/kske/eventbus/core/EventBus.java @@ -66,11 +66,27 @@ public final class EventBus { return singletonInstance; } - private final Map, TreeSet> bindings = - new ConcurrentHashMap<>(); - private final Set registeredListeners = - ConcurrentHashMap.newKeySet(); - private final ThreadLocal dispatchState = + /** + * Event handler bindings (target class to handlers registered for that class), does not contain + * other (polymorphic) handlers. + * + * @since 0.0.1 + */ + private final Map, TreeSet> bindings = new ConcurrentHashMap<>(); + + /** + * Registered listeners. + * + * @since 0.0.1 + */ + private final Set registeredListeners = ConcurrentHashMap.newKeySet(); + + /** + * Thread-local dispatch state. + * + * @since 0.1.0 + */ + private final ThreadLocal dispatchState = ThreadLocal.withInitial(DispatchState::new); /** @@ -78,7 +94,8 @@ public final class EventBus { * priority. * * @param event the event to dispatch - * @throws EventBusException if an event handler isn't accessible or has an invalid signature + * @throws EventBusException if an event handler isn't accessible or has an invalid signature + * @throws NullPointerException if the specified event is {@code null} * @since 0.0.1 */ public void dispatch(Object event) throws EventBusException { @@ -173,8 +190,9 @@ public final class EventBus { * Registers an event listener at this event bus. * * @param listener the listener to register - * @throws EventBusException if the listener is already registered or a declared event handler - * does not comply with the specification + * @throws EventBusException if the listener is already registered or a declared event + * handler does not comply with the specification + * @throws NullPointerException if the specified listener is {@code null} * @since 0.0.1 * @see Event */ @@ -229,6 +247,7 @@ public final class EventBus { Objects.requireNonNull(listener); logger.log(Level.INFO, "Removing event listener {0}", listener.getClass().getName()); + // Remove bindings from binding map for (var binding : bindings.values()) { var it = binding.iterator(); while (it.hasNext()) { @@ -239,6 +258,8 @@ public final class EventBus { } } } + + // Remove the listener itself registeredListeners.remove(listener); } diff --git a/event-bus-core/src/main/java/dev/kske/eventbus/core/EventBusException.java b/event-bus-core/src/main/java/dev/kske/eventbus/core/EventBusException.java index d67616c..959cbff 100644 --- a/event-bus-core/src/main/java/dev/kske/eventbus/core/EventBusException.java +++ b/event-bus-core/src/main/java/dev/kske/eventbus/core/EventBusException.java @@ -1,14 +1,18 @@ package dev.kske.eventbus.core; /** - * This runtime exception is thrown when an event bus error occurs. This can - * either occur while registering event listeners with invalid handlers, or when - * an event handler throws an exception. + * This unchecked exception is specific to the event bus and can be thrown under the following + * circumstances: + *
    + *
  • An event handler throws an exception (which is stores as the cause)
  • + *
  • An event listener with an invalid event handler is registered
  • + *
  • {@link EventBus#cancel()} is invoked from outside an active dispatch thread
  • + *
* * @author Kai S. K. Engelbart * @since 0.0.1 */ -public class EventBusException extends RuntimeException { +public final class EventBusException extends RuntimeException { private static final long serialVersionUID = 1L; diff --git a/pom.xml b/pom.xml index 965c03f..50b750f 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ pom Event Bus - An event handling framework for Java utilizing annotations. + An event handling library for Java utilizing annotations. https://git.kske.dev/kske/event-bus