From 79855d1c16eb34a7a64c1640cec3b5b0bee03344 Mon Sep 17 00:00:00 2001 From: azjezz Date: Sat, 9 May 2020 12:45:00 +0100 Subject: [PATCH] [EventDispatcher] initial commit --- .../EventDispatcher/Event/IEvent.hack | 10 +++++++++ .../Event/IStoppableEvent.hack | 22 +++++++++++++++++++ .../EventListener/IEventListener.hack | 13 +++++++++++ .../EventDispatcher/IEventDispatcher.hack | 15 +++++++++++++ .../ListenerProvider/IListenerProvider.hack | 21 ++++++++++++++++++ 5 files changed, 81 insertions(+) create mode 100644 src/Nuxed/Contract/EventDispatcher/Event/IEvent.hack create mode 100644 src/Nuxed/Contract/EventDispatcher/Event/IStoppableEvent.hack create mode 100644 src/Nuxed/Contract/EventDispatcher/EventListener/IEventListener.hack create mode 100644 src/Nuxed/Contract/EventDispatcher/IEventDispatcher.hack create mode 100644 src/Nuxed/Contract/EventDispatcher/ListenerProvider/IListenerProvider.hack diff --git a/src/Nuxed/Contract/EventDispatcher/Event/IEvent.hack b/src/Nuxed/Contract/EventDispatcher/Event/IEvent.hack new file mode 100644 index 0000000..6575f10 --- /dev/null +++ b/src/Nuxed/Contract/EventDispatcher/Event/IEvent.hack @@ -0,0 +1,10 @@ +namespace Nuxed\EventDispatcher\Event; + +/** + * Marker interface indicating an event instance. + * + * Event instances may contain zero methods, or as many methods as they + * want. The interface MUST be implemented, however, to provide type-safety + * to both listeners as well as the dispatcher. + */ +interface IEvent {} diff --git a/src/Nuxed/Contract/EventDispatcher/Event/IStoppableEvent.hack b/src/Nuxed/Contract/EventDispatcher/Event/IStoppableEvent.hack new file mode 100644 index 0000000..9b421f8 --- /dev/null +++ b/src/Nuxed/Contract/EventDispatcher/Event/IStoppableEvent.hack @@ -0,0 +1,22 @@ +namespace Nuxed\EventDispatcher\Event; + +/** + * An Event whose processing may be interrupted when the event has been handled. + * + * A Dispatcher implementation MUST check to determine an Event + * is marked as stopped after each listener is called. If it is then it should + * return immediately without calling any further Listeners. + */ +interface IStoppableEvent extends IEvent { + /** + * Is propagation stopped? + * + * This will typically only be used by the Dispatcher to determine if the + * previous listener halted propagation. + * + * @return bool + * True if the Event is complete and no further listeners should be called. + * False to continue calling listeners. + */ + public function isPropagationStopped(): bool; +} diff --git a/src/Nuxed/Contract/EventDispatcher/EventListener/IEventListener.hack b/src/Nuxed/Contract/EventDispatcher/EventListener/IEventListener.hack new file mode 100644 index 0000000..6a3ba09 --- /dev/null +++ b/src/Nuxed/Contract/EventDispatcher/EventListener/IEventListener.hack @@ -0,0 +1,13 @@ +namespace Nuxed\EventDispatcher\EventListener; + +use namespace Nuxed\EventDispatcher\Event; + +/** + * Defines a listener for an event. + */ +interface IEventListener { + /** + * Process the given event. + */ + public function process(T $event): Awaitable; +} diff --git a/src/Nuxed/Contract/EventDispatcher/IEventDispatcher.hack b/src/Nuxed/Contract/EventDispatcher/IEventDispatcher.hack new file mode 100644 index 0000000..ff70d84 --- /dev/null +++ b/src/Nuxed/Contract/EventDispatcher/IEventDispatcher.hack @@ -0,0 +1,15 @@ +namespace Nuxed\EventDispatcher; + +/** + * Defines a dispatcher for events. + */ +interface IEventDispatcher { + /** + * Provide all relevant listeners with an event to process. + * + * @template T as IEvent + * + * @return T The Event that was passed, now modified by listeners. + */ + public function dispatch(T $event): Awaitable; +} diff --git a/src/Nuxed/Contract/EventDispatcher/ListenerProvider/IListenerProvider.hack b/src/Nuxed/Contract/EventDispatcher/ListenerProvider/IListenerProvider.hack new file mode 100644 index 0000000..3181bb1 --- /dev/null +++ b/src/Nuxed/Contract/EventDispatcher/ListenerProvider/IListenerProvider.hack @@ -0,0 +1,21 @@ +namespace Nuxed\EventDispatcher\ListenerProvider; + +use namespace Nuxed\EventDispatcher\{Event, EventListener}; + +/** + * Mapper from an event to the listeners that are applicable to that event. + */ +interface IListenerProvider { + /** + * Retrieve all listeners for the given event. + * + * @param T $event + * An event for which to return the relevant listeners. + * @return AsyncIterator> + * An async iterator (usually an async generator) of listeners. Each + * listener MUST be type-compatible with $event. + */ + public function getListeners( + T $event, + ): AsyncIterator>; +}