2020-09-03 10:05:00 +02:00
|
|
|
# Event Bus
|
2020-09-02 11:25:13 +02:00
|
|
|
|
2020-09-06 14:57:17 +02:00
|
|
|
## Introduction
|
|
|
|
|
2020-09-03 10:05:00 +02:00
|
|
|
This library allows passing events between different objects without them having a direct reference to each other.
|
|
|
|
Any class can be made an event by implementing the `IEvent` interface.
|
|
|
|
|
|
|
|
Using an instance of the `EventBus` class, an instant of the event class can be dispatched.
|
|
|
|
This means that it will be forwarded to all listeners registered for it at the event bus.
|
|
|
|
|
2020-09-08 09:38:46 +02:00
|
|
|
In addition, a singleton instance of the event bus is provided by the `EventBus#getInstance()` method.
|
|
|
|
|
2020-09-03 10:05:00 +02:00
|
|
|
To listen to events, register event handling methods using the `Event` annotation.
|
|
|
|
For this to work, the method must have a return type of `void` and declare a single parameter of the desired event type.
|
2020-09-08 19:47:21 +02:00
|
|
|
Alternatively, a parameter-less event handler can be declared as shown [below](#parameter-less-event-handlers).
|
2020-09-03 10:05:00 +02:00
|
|
|
Additionally, the class containing the method must implement the `EventListener` interface.
|
|
|
|
|
2020-09-06 14:57:17 +02:00
|
|
|
## A Simple Example
|
|
|
|
|
2020-09-03 10:05:00 +02:00
|
|
|
Lets look at a simple example: we declare the empty class `SimpleEvent` that implements `IEvent` and can thus be used as an event.
|
|
|
|
|
|
|
|
```java
|
|
|
|
import dev.kske.eventbus.IEvent;
|
|
|
|
|
|
|
|
public class SimpleEvent implements IEvent {}
|
|
|
|
```
|
|
|
|
|
|
|
|
Next, an event listener for the `SimpleEvent` is declared:
|
|
|
|
|
|
|
|
```java
|
|
|
|
import dev.kske.eventbus.*;
|
|
|
|
|
|
|
|
public class SimpleEventListener implements EventListener {
|
|
|
|
|
|
|
|
public SimpleEventListener() {
|
|
|
|
|
|
|
|
// Register this listener at the event bus
|
2020-09-08 09:38:46 +02:00
|
|
|
EventBus.getInstance().register(this);
|
2020-09-03 10:05:00 +02:00
|
|
|
|
|
|
|
// Dispatch a SimpleEvent
|
2020-09-08 09:38:46 +02:00
|
|
|
EventBus.getInstance().dispatch(new SimpleEvent());
|
2020-09-03 10:05:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Event
|
|
|
|
private void onSimpleEvent(SimpleEvent event) {
|
|
|
|
System.out.println("SimpleEvent received!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2020-09-08 19:47:21 +02:00
|
|
|
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.
|
|
|
|
|
2020-09-26 09:59:08 +02:00
|
|
|
Note that creating static event handlers like this
|
|
|
|
|
|
|
|
```java
|
|
|
|
@Event
|
|
|
|
private static void onSimpleEvent(SimpleEvent event) ...
|
|
|
|
```
|
|
|
|
|
|
|
|
is technically possible, however you would still have to create an instance of the event listener to register it at an event bus.
|
|
|
|
|
2020-09-20 12:20:29 +02:00
|
|
|
## 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)
|
|
|
|
```
|
|
|
|
|
2020-09-20 14:35:50 +02:00
|
|
|
## 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`.
|
|
|
|
|
|
|
|
Priority can be set on the `@Event` annotation like that:
|
|
|
|
```java
|
|
|
|
@Event(priority=100)
|
|
|
|
```
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
2020-09-08 19:47:21 +02:00
|
|
|
## Parameter-less event handlers
|
|
|
|
|
|
|
|
In some cases an event handler is not interested in the dispatched event instance.
|
|
|
|
To avoid declaring a useless parameter just to specify the event type of the handler, there is an alternative:
|
|
|
|
|
|
|
|
```java
|
|
|
|
@Event(eventType = 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.
|
2020-09-06 14:57:17 +02:00
|
|
|
|
2020-10-11 11:25:18 +02:00
|
|
|
## Event consumption
|
|
|
|
|
2021-01-03 17:00:20 +01:00
|
|
|
In some cases it might be useful to stop the propagation of an event.
|
|
|
|
Event Bus makes this possible with event consumption:
|
2020-10-11 11:25:18 +02:00
|
|
|
|
|
|
|
```java
|
2021-01-03 17:00:20 +01:00
|
|
|
@Event(eventType = SimpleEvent.class, priority=100)
|
2020-10-11 11:25:18 +02:00
|
|
|
private void onSimpleEvent() {
|
|
|
|
EventBus.getInstance().cancel();
|
|
|
|
}
|
|
|
|
|
2021-01-03 17:00:20 +01:00
|
|
|
@Event(eventType = SimpleEvent.class, priority=50)
|
2020-10-11 11:25:18 +02:00
|
|
|
private void onSimpleEvent2() {
|
|
|
|
System.out.println("Will not be printed!");
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2021-01-03 17:00:20 +01:00
|
|
|
In this example, the second method will not be executed as it has a lower priority and the event will not be propagated after consumption.
|
|
|
|
This applies to all event handlers that would have been executed after the one consuming the event.
|
2020-10-11 11:25:18 +02:00
|
|
|
|
|
|
|
**Important:**
|
2021-01-03 17:00:20 +01:00
|
|
|
Avoid cancelling events while using multiple event handlers with the same priority.
|
|
|
|
As event handlers are ordered by priority, it is not defined which of them will be executed after the event has been consumed.
|
2020-10-11 11:25:18 +02:00
|
|
|
|
2020-09-06 14:57:17 +02:00
|
|
|
## Installation
|
|
|
|
|
|
|
|
Event Bus is currently hosted at [kske.dev](https://kske.dev).
|
|
|
|
To include it inside your project, just add the Maven repository and the dependency to your `pom.xml`:
|
|
|
|
|
|
|
|
```xml
|
|
|
|
<repositories>
|
|
|
|
<repository>
|
|
|
|
<id>kske-repo</id>
|
|
|
|
<url>https://kske.dev/maven-repo</url>
|
|
|
|
</repository>
|
|
|
|
</repositories>
|
|
|
|
|
|
|
|
<dependencies>
|
|
|
|
<dependency>
|
|
|
|
<groupId>dev.kske</groupId>
|
|
|
|
<artifactId>event-bus</artifactId>
|
2020-09-20 15:27:51 +02:00
|
|
|
<version>0.1.0</version>
|
2020-09-06 14:57:17 +02:00
|
|
|
</dependency>
|
|
|
|
</dependencies>
|
|
|
|
```
|