Respect listener-level properties

This commit is contained in:
Kai S. K. Engelbart 2021-03-14 11:18:11 +01:00
parent 6c74af608c
commit 2ec0a82a96
Signed by: kske
GPG Key ID: 8BEB13EC5DF7EF13
3 changed files with 36 additions and 17 deletions

View File

@ -30,6 +30,14 @@ public final class EventBus {
boolean isDispatching, isCancelled; boolean isDispatching, isCancelled;
} }
/**
* The priority assigned to every event handler without an explicitly defined priority.
*
* @since 1.1.0
* @see Priority
*/
public static final int DEFAULT_PRIORITY = 100;
private static volatile EventBus singletonInstance; private static volatile EventBus singletonInstance;
private static final Logger logger = System.getLogger(EventBus.class.getName()); private static final Logger logger = System.getLogger(EventBus.class.getName());
@ -165,6 +173,16 @@ public final class EventBus {
logger.log(Level.INFO, "Registering event listener {0}", listener.getClass().getName()); logger.log(Level.INFO, "Registering event listener {0}", listener.getClass().getName());
boolean handlerBound = false; boolean handlerBound = false;
// Predefined handler polymorphism
boolean polymorphic = false;
if (listener.getClass().isAnnotationPresent(Polymorphic.class))
polymorphic = listener.getClass().getAnnotation(Polymorphic.class).value();
// Predefined handler priority
int priority = 100;
if (listener.getClass().isAnnotationPresent(Priority.class))
priority = listener.getClass().getAnnotation(Priority.class).value();
registeredListeners.add(listener); registeredListeners.add(listener);
for (var method : listener.getClass().getDeclaredMethods()) { for (var method : listener.getClass().getDeclaredMethods()) {
Event annotation = method.getAnnotation(Event.class); Event annotation = method.getAnnotation(Event.class);
@ -174,7 +192,7 @@ public final class EventBus {
continue; continue;
// Initialize and bind the handler // Initialize and bind the handler
var handler = new EventHandler(listener, method, annotation); var handler = new EventHandler(listener, method, annotation, polymorphic, priority);
bindings.putIfAbsent(handler.getEventType(), new TreeSet<>()); bindings.putIfAbsent(handler.getEventType(), new TreeSet<>());
logger.log(Level.DEBUG, "Binding event handler {0}", handler); logger.log(Level.DEBUG, "Binding event handler {0}", handler);
bindings.get(handler.getEventType()) bindings.get(handler.getEventType())

View File

@ -13,14 +13,6 @@ import dev.kske.eventbus.core.Event.USE_PARAMETER;
*/ */
final class EventHandler implements Comparable<EventHandler> { final class EventHandler implements Comparable<EventHandler> {
/**
* The priority assigned to every event handler without an explicitly defined priority.
*
* @since 1.0.0
* @see Priority
*/
public static final int DEFAULT_PRIORITY = 100;
private final Object listener; private final Object listener;
private final Method method; private final Method method;
private final Class<?> eventType; private final Class<?> eventType;
@ -31,14 +23,17 @@ final class EventHandler implements Comparable<EventHandler> {
/** /**
* Constructs an event handler. * Constructs an event handler.
* *
* @param listener the listener containing the handler * @param listener the listener containing the handler
* @param method the handler method * @param method the handler method
* @param annotation the event annotation * @param annotation the event annotation
* @param defPolymorphism the predefined polymorphism (default or listener-level)
* @param defPriority the predefined priority (default or listener-level)
* @throws EventBusException if the method or the annotation do not comply with the * @throws EventBusException if the method or the annotation do not comply with the
* specification * specification
* @since 0.0.1 * @since 0.0.1
*/ */
EventHandler(Object listener, Method method, Event annotation) throws EventBusException { EventHandler(Object listener, Method method, Event annotation, boolean defPolymorphism,
int defPriority) throws EventBusException {
this.listener = listener; this.listener = listener;
this.method = method; this.method = method;
useParameter = annotation.value() == USE_PARAMETER.class; useParameter = annotation.value() == USE_PARAMETER.class;
@ -55,10 +50,12 @@ final class EventHandler implements Comparable<EventHandler> {
// Determine handler properties // Determine handler properties
eventType = useParameter ? method.getParameterTypes()[0] : annotation.value(); eventType = useParameter ? method.getParameterTypes()[0] : annotation.value();
polymorphic = method.isAnnotationPresent(Polymorphic.class); polymorphic = method.isAnnotationPresent(Polymorphic.class)
? method.getAnnotation(Polymorphic.class).value()
: defPolymorphism;
priority = method.isAnnotationPresent(Priority.class) priority = method.isAnnotationPresent(Priority.class)
? method.getAnnotation(Priority.class).value() ? method.getAnnotation(Priority.class).value()
: DEFAULT_PRIORITY; : defPriority;
// Allow access if the method is non-public // Allow access if the method is non-public
method.setAccessible(true); method.setAccessible(true);
@ -94,6 +91,7 @@ final class EventHandler implements Comparable<EventHandler> {
* @throws EventBusException if the event handler isn't accessible or has an invalid * @throws EventBusException if the event handler isn't accessible or has an invalid
* signature * signature
* @throws InvocationTargetException if the handler throws an exception * @throws InvocationTargetException if the handler throws an exception
* @throws EventBusException if the handler has the wrong signature or is inaccessible
* @since 0.0.1 * @since 0.0.1
*/ */
void execute(Object event) throws EventBusException, InvocationTargetException { void execute(Object event) throws EventBusException, InvocationTargetException {

View File

@ -10,6 +10,8 @@ import org.junit.jupiter.api.*;
* @author Kai S. K. Engelbart * @author Kai S. K. Engelbart
* @since 0.0.1 * @since 0.0.1
*/ */
@Polymorphic
@Priority(150)
class DispatchTest { class DispatchTest {
EventBus bus; EventBus bus;
@ -40,20 +42,21 @@ class DispatchTest {
@Event(SimpleEvent.class) @Event(SimpleEvent.class)
@Priority(200) @Priority(200)
@Polymorphic
void onSimpleEventFirst() { void onSimpleEventFirst() {
++hits; ++hits;
assertTrue(hits == 1 || hits == 2); assertTrue(hits == 1 || hits == 2);
} }
@Event(SimpleEvent.class) @Event(SimpleEvent.class)
@Priority(150) @Polymorphic(false)
static void onSimpleEventSecond() { static void onSimpleEventSecond() {
++hits; ++hits;
assertEquals(3, hits); assertEquals(3, hits);
} }
@Event @Event
@Polymorphic(false)
@Priority(100)
void onSimpleEventThird(SimpleEvent event) { void onSimpleEventThird(SimpleEvent event) {
++hits; ++hits;
assertEquals(4, hits); assertEquals(4, hits);