Compare commits
No commits in common. "51f10c4144cd557d75cefe6dbeb15fa61767df7d" and "52719d22d441935554155b9f03536c8e0e1c48d1" have entirely different histories.
51f10c4144
...
52719d22d4
@ -97,13 +97,6 @@ private void onSimpleEvent() {
|
|||||||
|
|
||||||
Make sure that you **do not** both declare a parameter and specify the event type in the annotation, as this would be ambiguous.
|
Make sure that you **do not** both declare a parameter and specify the event type in the annotation, as this would be ambiguous.
|
||||||
|
|
||||||
## Listener-Level Properties
|
|
||||||
|
|
||||||
When defining a dedicated event listener that, for example, performs pre- or post-processing, all event handlers will probably have the same non-standard priority.
|
|
||||||
Instead of defining that priority for each handler, it can be defined at the listener level by annotating the listener itself.
|
|
||||||
|
|
||||||
The same applies to polymorphism.
|
|
||||||
|
|
||||||
## Event Consumption
|
## Event Consumption
|
||||||
|
|
||||||
In some cases it might be useful to stop the propagation of an event.
|
In some cases it might be useful to stop the propagation of an event.
|
||||||
|
@ -30,14 +30,6 @@ 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());
|
||||||
@ -177,16 +169,6 @@ 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 = DEFAULT_PRIORITY;
|
|
||||||
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);
|
||||||
@ -196,7 +178,7 @@ public final class EventBus {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Initialize and bind the handler
|
// Initialize and bind the handler
|
||||||
var handler = new EventHandler(listener, method, annotation, polymorphic, priority);
|
var handler = new EventHandler(listener, method, annotation);
|
||||||
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())
|
||||||
|
@ -13,6 +13,14 @@ 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;
|
||||||
@ -26,14 +34,11 @@ final class EventHandler implements Comparable<EventHandler> {
|
|||||||
* @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, boolean defPolymorphism,
|
EventHandler(Object listener, Method method, Event annotation) throws EventBusException {
|
||||||
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;
|
||||||
@ -50,12 +55,10 @@ 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()
|
||||||
: defPriority;
|
: DEFAULT_PRIORITY;
|
||||||
|
|
||||||
// Allow access if the method is non-public
|
// Allow access if the method is non-public
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
@ -91,7 +94,6 @@ 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 {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package dev.kske.eventbus.core;
|
package dev.kske.eventbus.core;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.*;
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
@ -8,9 +8,6 @@ import java.lang.annotation.*;
|
|||||||
/**
|
/**
|
||||||
* Allows an event handler to receive events that are subtypes of the declared event type.
|
* Allows an event handler to receive events that are subtypes of the declared event type.
|
||||||
* <p>
|
* <p>
|
||||||
* When used on a type, the value applies to all event handlers declared within that type that don't
|
|
||||||
* define a value on their own.
|
|
||||||
* <p>
|
|
||||||
* This is useful when defining an event handler for an interface or an abstract class.
|
* This is useful when defining an event handler for an interface or an abstract class.
|
||||||
*
|
*
|
||||||
* @author Kai S. K. Engelbart
|
* @author Kai S. K. Engelbart
|
||||||
@ -19,12 +16,5 @@ import java.lang.annotation.*;
|
|||||||
*/
|
*/
|
||||||
@Documented
|
@Documented
|
||||||
@Retention(RUNTIME)
|
@Retention(RUNTIME)
|
||||||
@Target({ METHOD, TYPE })
|
@Target(METHOD)
|
||||||
public @interface Polymorphic {
|
public @interface Polymorphic {}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return whether the event handler is polymorphic
|
|
||||||
* @since 1.1.0
|
|
||||||
*/
|
|
||||||
boolean value() default true;
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package dev.kske.eventbus.core;
|
package dev.kske.eventbus.core;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.*;
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
@ -9,9 +9,6 @@ import java.lang.annotation.*;
|
|||||||
* Defines the priority of an event handler. Handlers are executed in descending order of their
|
* Defines the priority of an event handler. Handlers are executed in descending order of their
|
||||||
* priority.
|
* priority.
|
||||||
* <p>
|
* <p>
|
||||||
* When used on a type, the value applies to all event handlers declared within that type that don't
|
|
||||||
* define a value on their own.
|
|
||||||
* <p>
|
|
||||||
* Handlers without this annotation have the default priority of 100.
|
* Handlers without this annotation have the default priority of 100.
|
||||||
* <p>
|
* <p>
|
||||||
* The execution order of handlers with the same priority is undefined.
|
* The execution order of handlers with the same priority is undefined.
|
||||||
@ -22,7 +19,7 @@ import java.lang.annotation.*;
|
|||||||
*/
|
*/
|
||||||
@Documented
|
@Documented
|
||||||
@Retention(RUNTIME)
|
@Retention(RUNTIME)
|
||||||
@Target({ METHOD, TYPE })
|
@Target(METHOD)
|
||||||
public @interface Priority {
|
public @interface Priority {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,8 +10,6 @@ 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;
|
||||||
@ -42,21 +40,20 @@ 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)
|
||||||
@Polymorphic(false)
|
@Priority(150)
|
||||||
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);
|
||||||
|
@ -84,44 +84,8 @@ public class EventProcessor extends AbstractProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the listener containing this handler
|
|
||||||
TypeElement listener = (TypeElement) eventHandler.getEnclosingElement();
|
|
||||||
|
|
||||||
// Default properties
|
|
||||||
boolean defPolymorphic = false;
|
|
||||||
int defPriority = 100;
|
|
||||||
|
|
||||||
// Listener-level polymorphism
|
|
||||||
Polymorphic listenerPolymorphic = listener.getAnnotation(Polymorphic.class);
|
|
||||||
boolean hasListenerPolymorphic = listenerPolymorphic != null;
|
|
||||||
|
|
||||||
// Listener-level priority
|
|
||||||
Priority listenerPriority = listener.getAnnotation(Priority.class);
|
|
||||||
boolean hasListenerPriority = listenerPriority != null;
|
|
||||||
|
|
||||||
// Effective polymorphism
|
|
||||||
boolean polymorphic =
|
|
||||||
hasListenerPolymorphic ? listenerPolymorphic.value() : defPolymorphic;
|
|
||||||
boolean hasHandlerPolymorphic = eventHandler.getAnnotation(Polymorphic.class) != null;
|
|
||||||
if (hasHandlerPolymorphic)
|
|
||||||
polymorphic = eventHandler.getAnnotation(Polymorphic.class).value();
|
|
||||||
|
|
||||||
// Effective priority
|
|
||||||
int priority = hasListenerPriority ? listenerPriority.value() : defPriority;
|
|
||||||
boolean hasHandlerPriority = eventHandler.getAnnotation(Priority.class) != null;
|
|
||||||
if (hasHandlerPriority)
|
|
||||||
priority = eventHandler.getAnnotation(Priority.class).value();
|
|
||||||
|
|
||||||
// Detect useless polymorphism redefinition
|
|
||||||
if (hasListenerPolymorphic && hasHandlerPolymorphic
|
|
||||||
&& listenerPolymorphic.value() == polymorphic)
|
|
||||||
warning(eventHandler, "@Polymorphism is already defined at listener level");
|
|
||||||
|
|
||||||
// Detect useless priority redefinition
|
|
||||||
if (hasListenerPriority && hasHandlerPriority && listenerPriority.value() == priority)
|
|
||||||
warning(eventHandler, "@Priority is already defined at the listener level");
|
|
||||||
|
|
||||||
// Detect missing or useless @Polymorphic
|
// Detect missing or useless @Polymorphic
|
||||||
|
boolean polymorphic = eventHandler.getAnnotation(Polymorphic.class) != null;
|
||||||
Element eventElement = ((DeclaredType) eventType).asElement();
|
Element eventElement = ((DeclaredType) eventType).asElement();
|
||||||
|
|
||||||
// Check for handlers for abstract types that aren't polymorphic
|
// Check for handlers for abstract types that aren't polymorphic
|
||||||
|
Loading…
Reference in New Issue
Block a user