Replace priority with @Priority
The new @Priority annotation serves the exact same purpose as @Event(priority = ...), but should be easier to read in complex handler declarations. It has to be used in conjunction with the @Event annotation, not instead of it.
This commit is contained in:
parent
3a6ebe9a19
commit
9b1c708514
22
README.md
22
README.md
@ -73,20 +73,18 @@ private void onSimpleEvent(SimpleEvent event) { ... }
|
|||||||
|
|
||||||
## Event Handler Execution Order
|
## Event Handler Execution Order
|
||||||
|
|
||||||
Sometimes when using multiple handlers for one event, it might be useful to know in which order they will be executed.
|
Sometimes when using multiple handlers for one event, it might be useful to define in which order they will be executed.
|
||||||
Event Bus provides a mechanism to ensure the correct propagation of events: the `priority`.
|
Event Bus assigns a priority to every handler, which is `100` by default, but can be explicitly set using the `@Priority` annotation in addition to `@Event`:
|
||||||
|
|
||||||
Priority can be set on the `@Event` annotation like that:
|
|
||||||
```java
|
```java
|
||||||
@Event(priority=100)
|
@Event
|
||||||
|
@Priority(250)
|
||||||
|
private void onSimpleEvent(SimpleEvent event) { ... }
|
||||||
```
|
```
|
||||||
|
|
||||||
The default priority for events is `100`.
|
|
||||||
|
|
||||||
**Important:**
|
**Important:**
|
||||||
Events are dispatched top-down, meaning the event handler with the highest priority will be executed first.
|
Events are dispatched to handlers in descending order of their priority.
|
||||||
|
The execution order is undefined for handlers with the same priority.
|
||||||
If no priority is set or multiple handlers have the same priority, the order of execution is undefined.
|
|
||||||
|
|
||||||
## Parameter-Less Event Handlers
|
## Parameter-Less Event Handlers
|
||||||
|
|
||||||
@ -108,12 +106,14 @@ In some cases it might be useful to stop the propagation of an event.
|
|||||||
Event Bus makes this possible with event consumption:
|
Event Bus makes this possible with event consumption:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
@Event(eventType = SimpleEvent.class, priority=100)
|
@Event(eventType = SimpleEvent.class)
|
||||||
|
@Priority(100)
|
||||||
private void onSimpleEvent() {
|
private void onSimpleEvent() {
|
||||||
EventBus.getInstance().cancel();
|
EventBus.getInstance().cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Event(eventType = SimpleEvent.class, priority=50)
|
@Event(eventType = SimpleEvent.class)
|
||||||
|
@Priority(50)
|
||||||
private void onSimpleEvent2() {
|
private void onSimpleEvent2() {
|
||||||
System.out.println("Will not be printed!");
|
System.out.println("Will not be printed!");
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ public class EventProcessor extends AbstractProcessor {
|
|||||||
if (declaredElement.getKind() == ElementKind.INTERFACE
|
if (declaredElement.getKind() == ElementKind.INTERFACE
|
||||||
|| declaredElement.getModifiers().contains(Modifier.ABSTRACT))
|
|| declaredElement.getModifiers().contains(Modifier.ABSTRACT))
|
||||||
warning(paramElement,
|
warning(paramElement,
|
||||||
"Parameter should be instantiable or handler should include subtypes");
|
"Parameter should be instantiable or handler should use @Polymorphic");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check listener for interface implementation
|
// Check listener for interface implementation
|
||||||
|
@ -22,23 +22,13 @@ import java.lang.annotation.*;
|
|||||||
* @author Kai S. K. Engelbart
|
* @author Kai S. K. Engelbart
|
||||||
* @since 0.0.1
|
* @since 0.0.1
|
||||||
* @see Polymorphic
|
* @see Polymorphic
|
||||||
|
* @see Priority
|
||||||
*/
|
*/
|
||||||
@Documented
|
@Documented
|
||||||
@Retention(RUNTIME)
|
@Retention(RUNTIME)
|
||||||
@Target(METHOD)
|
@Target(METHOD)
|
||||||
public @interface Event {
|
public @interface Event {
|
||||||
|
|
||||||
/**
|
|
||||||
* Defines the priority of the event handler. Handlers are executed in descending order of their
|
|
||||||
* priority.
|
|
||||||
* <p>
|
|
||||||
* The execution order of handlers with the same priority is undefined.
|
|
||||||
*
|
|
||||||
* @return the priority of the event handler
|
|
||||||
* @since 0.0.1
|
|
||||||
*/
|
|
||||||
int priority() default 100;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the event type the handler listens to. If this value is set, the handler is not
|
* Defines the event type the handler listens to. If this value is set, the handler is not
|
||||||
* allowed to declare parameters.
|
* allowed to declare parameters.
|
||||||
|
@ -13,11 +13,20 @@ 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 EventListener listener;
|
private final EventListener listener;
|
||||||
private final Method method;
|
private final Method method;
|
||||||
private final Event annotation;
|
private final Event annotation;
|
||||||
private final Class<? extends IEvent> eventType;
|
private final Class<? extends IEvent> eventType;
|
||||||
private final boolean polymorphic;
|
private final boolean polymorphic;
|
||||||
|
private final int priority;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an event handler.
|
* Constructs an event handler.
|
||||||
@ -58,14 +67,17 @@ final class EventHandler implements Comparable<EventHandler> {
|
|||||||
}
|
}
|
||||||
this.eventType = eventType;
|
this.eventType = eventType;
|
||||||
polymorphic = method.isAnnotationPresent(Polymorphic.class);
|
polymorphic = method.isAnnotationPresent(Polymorphic.class);
|
||||||
|
priority = method.isAnnotationPresent(Priority.class)
|
||||||
|
? method.getAnnotation(Priority.class).value()
|
||||||
|
: DEFAULT_PRIORITY;
|
||||||
|
|
||||||
// Allow access if the method is non-public
|
// Allow access if the method is non-public
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares this to another event handler based on {@link Event#priority()}. In case of equal
|
* Compares this to another event handler based on priority. In case of equal priority a
|
||||||
* priority a non-zero value based on hash codes is returned.
|
* non-zero value based on hash codes is returned.
|
||||||
* <p>
|
* <p>
|
||||||
* This is used to retrieve event handlers in order of descending priority from a tree set.
|
* This is used to retrieve event handlers in order of descending priority from a tree set.
|
||||||
*
|
*
|
||||||
@ -73,7 +85,7 @@ final class EventHandler implements Comparable<EventHandler> {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(EventHandler other) {
|
public int compareTo(EventHandler other) {
|
||||||
int priority = other.annotation.priority() - annotation.priority();
|
int priority = other.priority - this.priority;
|
||||||
if (priority == 0)
|
if (priority == 0)
|
||||||
priority = listener.hashCode() - other.listener.hashCode();
|
priority = listener.hashCode() - other.listener.hashCode();
|
||||||
return priority == 0 ? hashCode() - other.hashCode() : priority;
|
return priority == 0 ? hashCode() - other.hashCode() : priority;
|
||||||
@ -81,7 +93,8 @@ final class EventHandler implements Comparable<EventHandler> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("EventHandler[method=%s, annotation=%s]", method, annotation);
|
return String.format("EventHandler[method=%s, eventType=%s, polymorphic=%b, priority=%d]",
|
||||||
|
method, annotation.eventType(), polymorphic, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,16 +122,17 @@ final class EventHandler implements Comparable<EventHandler> {
|
|||||||
EventListener getListener() { return listener; }
|
EventListener getListener() { return listener; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the event annotation
|
* @return the event type this handler listens to
|
||||||
* @since 0.0.1
|
* @since 0.0.3
|
||||||
*/
|
*/
|
||||||
Event getAnnotation() { return annotation; }
|
Class<? extends IEvent> getEventType() { return eventType; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the priority of the event annotation
|
* @return the priority of this handler
|
||||||
* @since 0.0.1
|
* @since 0.0.1
|
||||||
|
* @see Priority
|
||||||
*/
|
*/
|
||||||
int getPriority() { return annotation.priority(); }
|
int getPriority() { return priority; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return whether this handler is polymorphic
|
* @return whether this handler is polymorphic
|
||||||
@ -126,10 +140,4 @@ final class EventHandler implements Comparable<EventHandler> {
|
|||||||
* @see Polymorphic
|
* @see Polymorphic
|
||||||
*/
|
*/
|
||||||
boolean isPolymorphic() { return polymorphic; }
|
boolean isPolymorphic() { return polymorphic; }
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the event type this handler listens to
|
|
||||||
* @since 0.0.3
|
|
||||||
*/
|
|
||||||
Class<? extends IEvent> getEventType() { return eventType; }
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
package dev.kske.eventbus.core;
|
||||||
|
|
||||||
|
import static java.lang.annotation.ElementType.METHOD;
|
||||||
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the priority of an event handler. Handlers are executed in descending order of their
|
||||||
|
* priority.
|
||||||
|
* <p>
|
||||||
|
* Handlers without this annotation have the default priority of 100.
|
||||||
|
* <p>
|
||||||
|
* The execution order of handlers with the same priority is undefined.
|
||||||
|
*
|
||||||
|
* @author Kai S. K. Engelbart
|
||||||
|
* @since 1.0.0
|
||||||
|
* @see Event
|
||||||
|
*/
|
||||||
|
@Documented
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
@Target(METHOD)
|
||||||
|
public @interface Priority {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the priority of the event handler
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
int value();
|
||||||
|
}
|
@ -39,13 +39,15 @@ class CancelTest implements EventListener {
|
|||||||
assertEquals(1, hits);
|
assertEquals(1, hits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Event(eventType = SimpleEvent.class, priority = 100)
|
@Event(eventType = SimpleEvent.class)
|
||||||
|
@Priority(100)
|
||||||
void onSimpleFirst() {
|
void onSimpleFirst() {
|
||||||
++hits;
|
++hits;
|
||||||
bus.cancel();
|
bus.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Event(eventType = SimpleEvent.class, priority = 50)
|
@Event(eventType = SimpleEvent.class)
|
||||||
|
@Priority(50)
|
||||||
void onSimpleSecond() {
|
void onSimpleSecond() {
|
||||||
++hits;
|
++hits;
|
||||||
}
|
}
|
||||||
|
@ -38,20 +38,22 @@ class DispatchTest implements EventListener {
|
|||||||
bus.dispatch(new SimpleEvent());
|
bus.dispatch(new SimpleEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Event(eventType = SimpleEvent.class, priority = 200)
|
@Event(eventType = SimpleEvent.class)
|
||||||
|
@Priority(200)
|
||||||
@Polymorphic
|
@Polymorphic
|
||||||
void onSimpleEventFirst() {
|
void onSimpleEventFirst() {
|
||||||
++hits;
|
++hits;
|
||||||
assertTrue(hits == 1 || hits == 2);
|
assertTrue(hits == 1 || hits == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Event(eventType = SimpleEvent.class, priority = 150)
|
@Event(eventType = SimpleEvent.class)
|
||||||
|
@Priority(150)
|
||||||
static void onSimpleEventSecond() {
|
static void onSimpleEventSecond() {
|
||||||
++hits;
|
++hits;
|
||||||
assertEquals(3, hits);
|
assertEquals(3, hits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Event(priority = 100)
|
@Event
|
||||||
void onSimpleEventThird(SimpleEvent event) {
|
void onSimpleEventThird(SimpleEvent event) {
|
||||||
++hits;
|
++hits;
|
||||||
assertEquals(4, hits);
|
assertEquals(4, hits);
|
||||||
|
Loading…
Reference in New Issue
Block a user