Split @Event Parameters Into @Polymorphic and @Property, Remove Marker Interfaces #5

Merged
kske merged 4 commits from f/new-annotations into develop 2021-02-15 20:38:19 +01:00
6 changed files with 34 additions and 25 deletions
Showing only changes of commit cd2e7ad023 - Show all commits

View File

@ -92,13 +92,13 @@ In some cases an event handler is not interested in the dispatched event instanc
To avoid declaring a useless parameter just to specify the event type of the handler, there is an alternative:
```java
@Event(eventType = SimpleEvent.class)
@Event(SimpleEvent.class)
private void onSimpleEvent() {
System.out.println("SimpleEvent received!");
}
```
Make sure that you **do not** declare both a parameter and the `eventType` value of 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.
## Event Consumption
@ -106,13 +106,13 @@ In some cases it might be useful to stop the propagation of an event.
Event Bus makes this possible with event consumption:
```java
@Event(eventType = SimpleEvent.class)
@Event(SimpleEvent.class)
@Priority(100)
private void onSimpleEvent() {
EventBus.getInstance().cancel();
}
@Event(eventType = SimpleEvent.class)
@Event(SimpleEvent.class)
@Priority(50)
private void onSimpleEvent2() {
System.out.println("Will not be printed!");
@ -154,6 +154,12 @@ Then, require the Event Bus Core module in your `module-info.java`:
requires dev.kske.eventbus.core;
```
If you intend to use event handlers that are inaccessible to Event Bus by means of Java language access control, make sure to allow reflective access from your module:
```java
opens my.module to dev.kske.eventbus.core;
```
## Compile-Time Error Checking with Event Bus AP
To assist you with writing event listeners, the Event Bus AP (Annotation Processor) module enforces correct usage of the `@Event` annotation during compile time.

View File

@ -40,7 +40,7 @@ public class EventProcessor extends AbstractProcessor {
// Determine how the event type is defined
boolean useParameter;
try {
eventAnnotation.eventType();
eventAnnotation.value();
throw new EventBusException(
"Could not determine event type of handler " + eventHandler);
} catch (MirroredTypeException e) {

View File

@ -13,7 +13,7 @@ import java.lang.annotation.*;
* <li>Specifying an event type by either
* <ul>
* <li>Declaring one parameter of a type that implements {@link IEvent}</li>
* <li>Defining the class of the event using the {@link Event#eventType()} value</li>
* <li>Defining the class of the event using the annotation value</li>
* </ul>
* </li>
* <li>Return type of {@code void}</li>
@ -36,9 +36,9 @@ public @interface Event {
* This is useful when the event handler does not utilize the event instance.
*
* @return the event type accepted by the handler
* @since 0.0.3
* @since 1.0.0
*/
Class<? extends IEvent> eventType() default USE_PARAMETER.class;
Class<? extends IEvent> value() default USE_PARAMETER.class;
/**
* Signifies that the event type the handler listens to is determined by the type of its only

View File

@ -23,8 +23,8 @@ final class EventHandler implements Comparable<EventHandler> {
private final EventListener listener;
private final Method method;
private final Event annotation;
private final Class<? extends IEvent> eventType;
private final boolean useParameter;
private final boolean polymorphic;
private final int priority;
@ -42,13 +42,13 @@ final class EventHandler implements Comparable<EventHandler> {
EventHandler(EventListener listener, Method method, Event annotation) throws EventBusException {
this.listener = listener;
this.method = method;
this.annotation = annotation;
useParameter = annotation.value() == USE_PARAMETER.class;
// Check for correct method signature and return type
if (method.getParameterCount() == 0 && annotation.eventType().equals(USE_PARAMETER.class))
if (method.getParameterCount() == 0 && useParameter)
throw new EventBusException(method + " does not define an event type!");
if (method.getParameterCount() == 1 && !annotation.eventType().equals(USE_PARAMETER.class))
if (method.getParameterCount() == 1 && !useParameter)
throw new EventBusException(method + " defines an ambiguous event type!");
if (method.getParameterCount() > 1)
@ -58,16 +58,18 @@ final class EventHandler implements Comparable<EventHandler> {
throw new EventBusException(method + " does not have a return type of void!");
// Determine the event type
Class<? extends IEvent> eventType = annotation.eventType();
if (eventType.equals(USE_PARAMETER.class)) {
if (useParameter) {
var param = method.getParameterTypes()[0];
if (!IEvent.class.isAssignableFrom(param))
throw new EventBusException(param + " is not of type IEvent!");
eventType = (Class<? extends IEvent>) param;
} else {
eventType = annotation.value();
}
this.eventType = eventType;
polymorphic = method.isAnnotationPresent(Polymorphic.class);
priority = method.isAnnotationPresent(Priority.class)
// Determine additional handler properties
polymorphic = method.isAnnotationPresent(Polymorphic.class);
priority = method.isAnnotationPresent(Priority.class)
? method.getAnnotation(Priority.class).value()
: DEFAULT_PRIORITY;
@ -93,8 +95,9 @@ final class EventHandler implements Comparable<EventHandler> {
@Override
public String toString() {
return String.format("EventHandler[method=%s, eventType=%s, polymorphic=%b, priority=%d]",
method, annotation.eventType(), polymorphic, priority);
return String.format(
"EventHandler[method=%s, eventType=%s, useParameter=%b, polymorphic=%b, priority=%d]",
method, eventType, useParameter, polymorphic, priority);
kske marked this conversation as resolved Outdated
Outdated
Review

Why is that now an object instead of an event?

Why is that now an object instead of an event?
Outdated
Review

Because I got rid of the IEvent interface so that every object can be used as an event.

Because I got rid of the `IEvent` interface so that every object can be used as an event.
}
/**
@ -106,7 +109,7 @@ final class EventHandler implements Comparable<EventHandler> {
*/
void execute(IEvent event) throws EventBusException {
try {
if (annotation.eventType() == USE_PARAMETER.class)
if (useParameter)
method.invoke(listener, event);
else
method.invoke(listener);
@ -122,7 +125,7 @@ final class EventHandler implements Comparable<EventHandler> {
EventListener getListener() { return listener; }
/**
* @return the event type this handler listens to
* @return the event type this handler listens for
* @since 0.0.3
*/
Class<? extends IEvent> getEventType() { return eventType; }

View File

@ -39,14 +39,14 @@ class CancelTest implements EventListener {
assertEquals(1, hits);
}
@Event(eventType = SimpleEvent.class)
@Event(SimpleEvent.class)
@Priority(100)
void onSimpleFirst() {
++hits;
bus.cancel();
}
@Event(eventType = SimpleEvent.class)
@Event(SimpleEvent.class)
@Priority(50)
void onSimpleSecond() {
++hits;

View File

@ -38,7 +38,7 @@ class DispatchTest implements EventListener {
bus.dispatch(new SimpleEvent());
}
@Event(eventType = SimpleEvent.class)
@Event(SimpleEvent.class)
@Priority(200)
@Polymorphic
void onSimpleEventFirst() {
@ -46,7 +46,7 @@ class DispatchTest implements EventListener {
assertTrue(hits == 1 || hits == 2);
}
@Event(eventType = SimpleEvent.class)
@Event(SimpleEvent.class)
@Priority(150)
static void onSimpleEventSecond() {
++hits;