Add subtype inclusion for event handlers

This commit is contained in:
2020-09-20 12:20:29 +02:00
parent 7a3debe444
commit ba06b49368
7 changed files with 65 additions and 11 deletions

View File

@ -36,6 +36,13 @@ public @interface Event {
*/
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
* allowed to declare parameters.

View File

@ -31,7 +31,7 @@ public final class EventBus {
return singletonInstance;
}
private final Map<Class<? extends IEvent>, Collection<EventHandler>> bindings
private final Map<Class<? extends IEvent>, TreeSet<EventHandler>> bindings
= new ConcurrentHashMap<>();
private final Set<EventListener> registeredListeners = ConcurrentHashMap.newKeySet();
@ -55,8 +55,20 @@ public final class EventBus {
* @since 0.0.1
*/
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);
}
/**

View File

@ -117,6 +117,12 @@ final class EventHandler implements Comparable<EventHandler> {
*/
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
* @since 0.0.3

View File

@ -1,6 +1,6 @@
package dev.kske.eventbus;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.*;
@ -21,18 +21,29 @@ class EventBusTest implements EventListener {
@Test
void testDispatch() {
EventBus.getInstance().dispatch(new SimpleEventSub());
EventBus.getInstance().dispatch(new SimpleEvent());
}
@Event(priority = 50)
private void onSimpleEventSecond(SimpleEvent event) {
@Event(
eventType = SimpleEvent.class,
includeSubtypes = true,
priority = 200
)
private void onSimpleEventFirst() {
++hits;
assertEquals(2, hits);
assertTrue(hits == 1 || hits == 2);
}
@Event(eventType = SimpleEvent.class, priority = 150)
private void onSimpleEventFirst() {
private void onSimpleEventSecond() {
++hits;
assertEquals(1, hits);
assertEquals(3, hits);
}
@Event(priority = 50)
private void onSimpleEventThird(SimpleEvent event) {
++hits;
assertEquals(4, hits);
}
}

View 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 {}