SimpleEventBus.java
package space.sunqian.fs.eventbus;
import space.sunqian.annotation.Nonnull;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
* This interface is a simplified event bus interface. It provides simple methods to register and unregister event
* subscribers with the specified event type, and post methods to post events with the specified event type.
*
* @author sunqian
*/
public interface SimpleEventBus {
/**
* Creates a new event bus, all event consuming will be executed in the post thread. It is same as
* {@link #newEventBus(Executor)} with the executor: {@code Runnable::run}.
*
* @return a new event bus
*/
static @Nonnull SimpleEventBus newEventBus() {
return newEventBus(Runnable::run);
}
/**
* Creates a new event bus with the specified executor.
*
* @param executor the executor to execute event subscribers
* @return a new event bus
*/
static @Nonnull SimpleEventBus newEventBus(@Nonnull Executor executor) {
return new SimpleEventBusImpl(executor);
}
/**
* Registers an event subscriber for the specified event type.
* <p>
* The default implementations use copy-on-write to add subscribers, so it is recommended to use
* {@link #register(Map)} for registering multiple event subscribers at once.
*
* @param type the event type
* @param subscriber the event subscriber
* @param <T> the event type
*/
<T> void register(@Nonnull Type type, @Nonnull Consumer<@Nonnull T> subscriber);
/**
* Registers event subscribers with the specified event types, the keys of the map are the event types, and the
* values are the event subscribers.
*
* @param subscribers the event subscribers
*/
void register(@Nonnull Map<@Nonnull Type, @Nonnull List<@Nonnull Consumer<@Nonnull ?>>> subscribers);
/**
* Unregisters an event subscriber which is registered via {@code register} methods. The subscriber object is the
* same object that is passed to {@code register} methods.
* <p>
* The default implementations use copy-on-write to remove subscribers, so it is recommended to use
* {@link #unregister(Iterable)} for unregistering multiple event subscribers at once.
*
* @param subscriber the event subscriber, which is the same object that is passed to {@code register} methods
*/
void unregister(@Nonnull Object subscriber);
/**
* Unregisters event subscribers which are registered via {@code register} methods. The subscriber objects are the
* same objects that are passed to {@code register} methods.
*
* @param subscribers the event subscribers, which are the same objects that are passed to {@code register} methods
*/
void unregister(@Nonnull Iterable<?> subscribers);
/**
* Posts an event. This method will call {@link #post(Object, Type)} with {@code event} and
* {@code event.getClass()}.
*
* @param event the event to post
*/
default void post(@Nonnull Object event) {
post(event, event.getClass());
}
/**
* Posts an event with the specified type. This method will call {@link #post(Object, Type, DispatchMode)} with
* {@code event}, {@code eventType}, and {@link DispatchMode#BROADCAST}.
*
* @param event the event to post
* @param eventType the event type
*/
default void post(@Nonnull Object event, @Nonnull Type eventType) {
post(event, eventType, DispatchMode.BROADCAST);
}
/**
* Posts an event with the specified dispatch mode. This method will call {@link #post(Object, Type, DispatchMode)}
* with {@code event}, {@code event.getClass()}, and {@code dispatchMode}.
*
* @param event the event to post
* @param dispatchMode the dispatch mode
*/
default void post(@Nonnull Object event, @Nonnull DispatchMode dispatchMode) {
post(event, event.getClass(), dispatchMode);
}
/**
* Posts an event with the specified type and dispatch mode.
*
* @param event the event to post
* @param eventType the event type
* @param dispatchMode the dispatch mode
*/
void post(@Nonnull Object event, @Nonnull Type eventType, @Nonnull DispatchMode dispatchMode);
/**
* The dispatch mode for posting events.
*/
enum DispatchMode {
/**
* The broadcast mode: subscribers which subscribe the event type will receive the event.
* <p>
* This is the default mode.
*/
BROADCAST,
/**
* The chain dispatch mode: subscribers which subscribe the event type will receive the event in the order they
* are registered, and the event propagation can be prevented by any subscriber.
* <p>
* In this mode, if a subscriber throws an exception, the event propagation will be stopped.
*/
CHAIN
}
}