A simple, thread safe, and fast event dispatcher for Kotlin/JVM and Java.
Simple setup, and easy to learn, logical API
Non locking event posting, and minimally locking registering/subscribing make this event dispatcher fit for use in highly concurrent applications.
Because there is no reflection during event posting, and subscribers are cached after the first use of reflection, this event dispatcher is much faster than other reflection based alternatives.
This event dispatcher supports third party events, such as those used in MinecraftForge, and uses the Unsafe API to get the value of a "cancelled" property at the same speed as direct access.
Listeners can be parallel, and they will be called on a Coroutine in the background. This is useful for heavy operations that may slow down the posting thread.
If you have not already, add Jitpack as a repository:
repositories {
maven { url 'https://jitpack.io' }
}Add the release of your choice in the dependencies block:
dependencies {
implementation 'com.github.therealbush:eventbus-kotlin:v1.0.1'
}EventBus can take a Config as an argument, however it is not required.
Config has four parameters. The following are the default arguments:
Config(
logger = LogManager.getLogger("Eventbus"),
parallelScope = CoroutineScope(Dispatchers.Default),
thirdPartyCompatibility = true,
annotationRequired = false
)The Logger this EventBus will use to log errors, or EventBus#debug
The CoroutineScope to use when posting events to parallel listeners. The default value will work just fine, but you
can specify a custom scope if desired.
Whether this EventBus should try to find a "cancelled" field in events being listened for that are not a subclass
of Event. This is experimental, and should be set to false if problems arise.
Whether listeners need to be annotated with @EventListener to be subscribed to this
EventBus. This has no effect on anything else, and is just to improve code readability.
Any class can be posted to an EventBus, but if you wish to use the base event class, extend Event, and implement the
property cancellable.
class SimpleEvent : Event() {
override val cancellable = true
}public class SimpleEvent extends Event {
@Override
protected boolean getCancellable() {
return false;
}
}Listeners are created by using the listener function:
listener<EventType>(priority = 0, parallel = false, receiveCancelled = false) {
...listener body ...
}listener(EventType.class, 0, false, false, event -> {
...listener body...
});Listeners can be registered either directly with EventBus#register, or subscribed by returning them from a function or
property and subscribing the object they belong to with EventBus#subscribe.
The following are all valid. Listeners should be public, but they don't need to be.
val listener0 = listener<EventType> {
...listener body ...
}
val listener1 get() = listener<EventType> {
...listener body ...
}
fun listener2() = listener<EventType> {
...listener body ...
}public Listener listener0 = listener(EventType.class, event -> {
...listener body...
});
public Listener listener1() {
return listener(EventType.class, event -> {
...listener body...
});
}The priority of this Listener. Listeners with a higher priority will receive events before listeners with a lower
priority.
Whether this Listener should be called on the thread that called EventBus#post, or on the
CoroutineScope in Config#parallelScope. EventBus#post will not wait for parallel listeners to complete.
Currently, there is no way to get a reference to the Job created by launch when posting to parallel listeners, and
listeners are not suspend lambdas. This may change in the future.
Whether this Listener should receive events that have been cancelled. This will work on third party events
if Config#thirdPartyCompatibility is enabled.
Calling EventBus#subscribe and EventBus#unsubscribe with an object will add and remove listeners belonging to that
object from the EventBus. Only listeners in subscribed objects will receive events.
Companion objects and singleton object classes can be subscribed, but subscribing a KClass will not work.
Calling EventBus#post will post an event to every listener with an exactly matching event type. For example, if
event B extends event A, and event A is posted, B listeners will not receive it.
Events are not queued: only listeners currently subscribed will be called.
EventBus#post will return true if the posted event is cancelled after posting it to sequential listeners. Event cancel
state is checked once before posting to parallel listeners, because order is not guaranteed.
Read this for usage examples.