Add subtype inclusion for event handlers
This commit is contained in:
parent
7a3debe444
commit
ba06b49368
11
README.md
11
README.md
@ -51,6 +51,15 @@ public class SimpleEventListener implements EventListener {
|
|||||||
In this case, an event bus is created and used locally.
|
In this case, an event bus is created and used locally.
|
||||||
In a more sophisticated example the class would acquire an external event bus that is used by multiple classes.
|
In a more sophisticated example the class would acquire an external event bus that is used by multiple classes.
|
||||||
|
|
||||||
|
## Event handlers for subtypes
|
||||||
|
|
||||||
|
On certain occasions its practical for an event handler to accept both events of the specified type, as well as subclasses of that event.
|
||||||
|
To include subtypes for an event handler, use the `includeSubtypes` parameter as follows:
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Event(includeSubtypes = true)
|
||||||
|
```
|
||||||
|
|
||||||
## Parameter-less event handlers
|
## Parameter-less event handlers
|
||||||
|
|
||||||
In some cases an event handler is not interested in the dispatched event instance.
|
In some cases an event handler is not interested in the dispatched event instance.
|
||||||
@ -82,7 +91,7 @@ To include it inside your project, just add the Maven repository and the depende
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>dev.kske</groupId>
|
<groupId>dev.kske</groupId>
|
||||||
<artifactId>event-bus</artifactId>
|
<artifactId>event-bus</artifactId>
|
||||||
<version>0.0.3</version>
|
<version>0.0.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
```
|
```
|
||||||
|
2
pom.xml
2
pom.xml
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<groupId>dev.kske</groupId>
|
<groupId>dev.kske</groupId>
|
||||||
<artifactId>event-bus</artifactId>
|
<artifactId>event-bus</artifactId>
|
||||||
<version>0.0.3</version>
|
<version>0.0.4</version>
|
||||||
|
|
||||||
<name>Event Bus</name>
|
<name>Event Bus</name>
|
||||||
<description>An event handling framework for Java utilizing annotations.</description>
|
<description>An event handling framework for Java utilizing annotations.</description>
|
||||||
|
@ -36,6 +36,13 @@ public @interface Event {
|
|||||||
*/
|
*/
|
||||||
int priority() default 100;
|
int priority() default 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines whether instances of subtypes of the event type are dispatched to the event handler.
|
||||||
|
*
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
boolean includeSubtypes() default false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
|
@ -31,7 +31,7 @@ public final class EventBus {
|
|||||||
return singletonInstance;
|
return singletonInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<Class<? extends IEvent>, Collection<EventHandler>> bindings
|
private final Map<Class<? extends IEvent>, TreeSet<EventHandler>> bindings
|
||||||
= new ConcurrentHashMap<>();
|
= new ConcurrentHashMap<>();
|
||||||
private final Set<EventListener> registeredListeners = ConcurrentHashMap.newKeySet();
|
private final Set<EventListener> registeredListeners = ConcurrentHashMap.newKeySet();
|
||||||
|
|
||||||
@ -55,8 +55,20 @@ public final class EventBus {
|
|||||||
* @since 0.0.1
|
* @since 0.0.1
|
||||||
*/
|
*/
|
||||||
private List<EventHandler> getHandlersFor(Class<? extends IEvent> eventClass) {
|
private List<EventHandler> getHandlersFor(Class<? extends IEvent> eventClass) {
|
||||||
return bindings.containsKey(eventClass) ? new ArrayList<>(bindings.get(eventClass))
|
|
||||||
: new ArrayList<>();
|
// Get handlers defined for the event class
|
||||||
|
Set<EventHandler> handlers
|
||||||
|
= bindings.containsKey(eventClass) ? bindings.get(eventClass)
|
||||||
|
: new TreeSet<>();
|
||||||
|
|
||||||
|
// Get subtype handlers
|
||||||
|
for (var binding : bindings.entrySet())
|
||||||
|
if (binding.getKey().isAssignableFrom(eventClass))
|
||||||
|
for (var handler : binding.getValue())
|
||||||
|
if (handler.includeSubtypes())
|
||||||
|
handlers.add(handler);
|
||||||
|
|
||||||
|
return new ArrayList<>(handlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,6 +117,12 @@ final class EventHandler implements Comparable<EventHandler> {
|
|||||||
*/
|
*/
|
||||||
int getPriority() { return annotation.priority(); }
|
int getPriority() { return annotation.priority(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return whether this handler includes subtypes
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
boolean includeSubtypes() { return annotation.includeSubtypes(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the event type this handler listens to
|
* @return the event type this handler listens to
|
||||||
* @since 0.0.3
|
* @since 0.0.3
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package dev.kske.eventbus;
|
package dev.kske.eventbus;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.*;
|
||||||
|
|
||||||
@ -21,18 +21,29 @@ class EventBusTest implements EventListener {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testDispatch() {
|
void testDispatch() {
|
||||||
|
EventBus.getInstance().dispatch(new SimpleEventSub());
|
||||||
EventBus.getInstance().dispatch(new SimpleEvent());
|
EventBus.getInstance().dispatch(new SimpleEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Event(priority = 50)
|
@Event(
|
||||||
private void onSimpleEventSecond(SimpleEvent event) {
|
eventType = SimpleEvent.class,
|
||||||
|
includeSubtypes = true,
|
||||||
|
priority = 200
|
||||||
|
)
|
||||||
|
private void onSimpleEventFirst() {
|
||||||
++hits;
|
++hits;
|
||||||
assertEquals(2, hits);
|
assertTrue(hits == 1 || hits == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Event(eventType = SimpleEvent.class, priority = 150)
|
@Event(eventType = SimpleEvent.class, priority = 150)
|
||||||
private void onSimpleEventFirst() {
|
private void onSimpleEventSecond() {
|
||||||
++hits;
|
++hits;
|
||||||
assertEquals(1, hits);
|
assertEquals(3, hits);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Event(priority = 50)
|
||||||
|
private void onSimpleEventThird(SimpleEvent event) {
|
||||||
|
++hits;
|
||||||
|
assertEquals(4, hits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
9
src/test/java/dev/kske/eventbus/SimpleEventSub.java
Normal file
9
src/test/java/dev/kske/eventbus/SimpleEventSub.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package dev.kske.eventbus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclass of {@link SimpleEvent} for testing purposes.
|
||||||
|
*
|
||||||
|
* @author Kai S. K. Engelbart
|
||||||
|
* @since 0.0.4
|
||||||
|
*/
|
||||||
|
public class SimpleEventSub extends SimpleEvent {}
|
Loading…
Reference in New Issue
Block a user