From 9b1c708514d003fa67aaa4f548bf7d8b914d67fc Mon Sep 17 00:00:00 2001 From: kske Date: Mon, 15 Feb 2021 12:06:33 +0100 Subject: [PATCH] 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. --- README.md | 22 +++++------ .../dev/kske/eventbus/ap/EventProcessor.java | 2 +- .../java/dev/kske/eventbus/core/Event.java | 12 +----- .../dev/kske/eventbus/core/EventHandler.java | 38 +++++++++++-------- .../java/dev/kske/eventbus/core/Priority.java | 30 +++++++++++++++ .../dev/kske/eventbus/core/CancelTest.java | 6 ++- .../dev/kske/eventbus/core/DispatchTest.java | 8 ++-- 7 files changed, 75 insertions(+), 43 deletions(-) create mode 100644 event-bus-core/src/main/java/dev/kske/eventbus/core/Priority.java diff --git a/README.md b/README.md index 62ed2c8..f6fa60c 100644 --- a/README.md +++ b/README.md @@ -73,20 +73,18 @@ private void onSimpleEvent(SimpleEvent event) { ... } ## 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. -Event Bus provides a mechanism to ensure the correct propagation of events: the `priority`. +Sometimes when using multiple handlers for one event, it might be useful to define in which order they will be executed. +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 -@Event(priority=100) +@Event +@Priority(250) +private void onSimpleEvent(SimpleEvent event) { ... } ``` -The default priority for events is `100`. - **Important:** -Events are dispatched top-down, meaning the event handler with the highest priority will be executed first. - -If no priority is set or multiple handlers have the same priority, the order of execution is undefined. +Events are dispatched to handlers in descending order of their priority. +The execution order is undefined for handlers with the same priority. ## 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: ```java -@Event(eventType = SimpleEvent.class, priority=100) +@Event(eventType = SimpleEvent.class) +@Priority(100) private void onSimpleEvent() { EventBus.getInstance().cancel(); } -@Event(eventType = SimpleEvent.class, priority=50) +@Event(eventType = SimpleEvent.class) +@Priority(50) private void onSimpleEvent2() { System.out.println("Will not be printed!"); } diff --git a/event-bus-ap/src/main/java/dev/kske/eventbus/ap/EventProcessor.java b/event-bus-ap/src/main/java/dev/kske/eventbus/ap/EventProcessor.java index 9e661a6..f38b997 100644 --- a/event-bus-ap/src/main/java/dev/kske/eventbus/ap/EventProcessor.java +++ b/event-bus-ap/src/main/java/dev/kske/eventbus/ap/EventProcessor.java @@ -80,7 +80,7 @@ public class EventProcessor extends AbstractProcessor { if (declaredElement.getKind() == ElementKind.INTERFACE || declaredElement.getModifiers().contains(Modifier.ABSTRACT)) 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 diff --git a/event-bus-core/src/main/java/dev/kske/eventbus/core/Event.java b/event-bus-core/src/main/java/dev/kske/eventbus/core/Event.java index 1011d89..34be499 100644 --- a/event-bus-core/src/main/java/dev/kske/eventbus/core/Event.java +++ b/event-bus-core/src/main/java/dev/kske/eventbus/core/Event.java @@ -22,23 +22,13 @@ import java.lang.annotation.*; * @author Kai S. K. Engelbart * @since 0.0.1 * @see Polymorphic + * @see Priority */ @Documented @Retention(RUNTIME) @Target(METHOD) public @interface Event { - /** - * Defines the priority of the event handler. Handlers are executed in descending order of their - * priority. - *

- * 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 * allowed to declare parameters. diff --git a/event-bus-core/src/main/java/dev/kske/eventbus/core/EventHandler.java b/event-bus-core/src/main/java/dev/kske/eventbus/core/EventHandler.java index 436bf70..d36549f 100644 --- a/event-bus-core/src/main/java/dev/kske/eventbus/core/EventHandler.java +++ b/event-bus-core/src/main/java/dev/kske/eventbus/core/EventHandler.java @@ -13,11 +13,20 @@ import dev.kske.eventbus.core.Event.USE_PARAMETER; */ final class EventHandler implements Comparable { + /** + * 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 Method method; private final Event annotation; private final Class eventType; private final boolean polymorphic; + private final int priority; /** * Constructs an event handler. @@ -58,14 +67,17 @@ final class EventHandler implements Comparable { } this.eventType = eventType; 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 method.setAccessible(true); } /** - * Compares this to another event handler based on {@link Event#priority()}. In case of equal - * priority a non-zero value based on hash codes is returned. + * Compares this to another event handler based on priority. In case of equal priority a + * non-zero value based on hash codes is returned. *

* 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 { */ @Override public int compareTo(EventHandler other) { - int priority = other.annotation.priority() - annotation.priority(); + int priority = other.priority - this.priority; if (priority == 0) priority = listener.hashCode() - other.listener.hashCode(); return priority == 0 ? hashCode() - other.hashCode() : priority; @@ -81,7 +93,8 @@ final class EventHandler implements Comparable { @Override 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 { EventListener getListener() { return listener; } /** - * @return the event annotation - * @since 0.0.1 + * @return the event type this handler listens to + * @since 0.0.3 */ - Event getAnnotation() { return annotation; } + Class getEventType() { return eventType; } /** - * @return the priority of the event annotation + * @return the priority of this handler * @since 0.0.1 + * @see Priority */ - int getPriority() { return annotation.priority(); } + int getPriority() { return priority; } /** * @return whether this handler is polymorphic @@ -126,10 +140,4 @@ final class EventHandler implements Comparable { * @see Polymorphic */ boolean isPolymorphic() { return polymorphic; } - - /** - * @return the event type this handler listens to - * @since 0.0.3 - */ - Class getEventType() { return eventType; } } diff --git a/event-bus-core/src/main/java/dev/kske/eventbus/core/Priority.java b/event-bus-core/src/main/java/dev/kske/eventbus/core/Priority.java new file mode 100644 index 0000000..1218df3 --- /dev/null +++ b/event-bus-core/src/main/java/dev/kske/eventbus/core/Priority.java @@ -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. + *

+ * Handlers without this annotation have the default priority of 100. + *

+ * 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(); +} diff --git a/event-bus-core/src/test/java/dev/kske/eventbus/core/CancelTest.java b/event-bus-core/src/test/java/dev/kske/eventbus/core/CancelTest.java index 0d25f93..a2da0bf 100644 --- a/event-bus-core/src/test/java/dev/kske/eventbus/core/CancelTest.java +++ b/event-bus-core/src/test/java/dev/kske/eventbus/core/CancelTest.java @@ -39,13 +39,15 @@ class CancelTest implements EventListener { assertEquals(1, hits); } - @Event(eventType = SimpleEvent.class, priority = 100) + @Event(eventType = SimpleEvent.class) + @Priority(100) void onSimpleFirst() { ++hits; bus.cancel(); } - @Event(eventType = SimpleEvent.class, priority = 50) + @Event(eventType = SimpleEvent.class) + @Priority(50) void onSimpleSecond() { ++hits; } diff --git a/event-bus-core/src/test/java/dev/kske/eventbus/core/DispatchTest.java b/event-bus-core/src/test/java/dev/kske/eventbus/core/DispatchTest.java index 0239a8c..c3a5a04 100644 --- a/event-bus-core/src/test/java/dev/kske/eventbus/core/DispatchTest.java +++ b/event-bus-core/src/test/java/dev/kske/eventbus/core/DispatchTest.java @@ -38,20 +38,22 @@ class DispatchTest implements EventListener { bus.dispatch(new SimpleEvent()); } - @Event(eventType = SimpleEvent.class, priority = 200) + @Event(eventType = SimpleEvent.class) + @Priority(200) @Polymorphic void onSimpleEventFirst() { ++hits; assertTrue(hits == 1 || hits == 2); } - @Event(eventType = SimpleEvent.class, priority = 150) + @Event(eventType = SimpleEvent.class) + @Priority(150) static void onSimpleEventSecond() { ++hits; assertEquals(3, hits); } - @Event(priority = 100) + @Event void onSimpleEventThird(SimpleEvent event) { ++hits; assertEquals(4, hits);