abstract class Athena::EventDispatcher::Event
- Athena::EventDispatcher::Event
- Reference
- Object
Overview
An event consists of a subclass of this type, usually with extra context specific information.
The metaclass of the event type is used as a unique identifier, which generally should end in a verb that indicates what action has been taken.
The AED::GenericEvent
type may be used for simple use cases, but dedicated event types are still considered a best practice.
# Define a custom event
class ExceptionRaisedEvent < AED::Event
getter exception : Exception
def initialize(@exception : Exception); end
end
# Dispatch a custom event
exception = ArgumentError.new "Value cannot be negative"
dispatcher.dispatch ExceptionRaisedEvent.new exception
Abstract event classes may also be used to share common data/methods between a group of related events. However they cannot be used as a catchall to listen on all events that extend it.
Stopping Propagation
In some cases it may make sense for a listener to prevent any other listeners from being called for a specific event.
In order to do this, the listener needs a way to tell the dispatcher that it should stop propagation, i.e. do not notify any more listeners.
The base event type includes AED::StoppableEvent
that enables this behavior.
Checkout the related module for more information.
Generics
Events with generic type variables are also supported, the AED::GenericEvent
event is an example of this.
Listeners on events with generics are a bit unique in how they behave in that each unique instantiation is treated as its own event.
For example:
class Foo; end
subject = Foo.new
dispatcher.listener AED::GenericEvent(Foo, Int32) do |e|
e["counter"] += 1
end
dispatcher.listener AED::GenericEvent(String, String) do |e|
e["class"] = e.subject.upcase
end
dispatcher.dispatch AED::GenericEvent.new subject, data = {"counter" => 0}
data["counter"] # => 1
dispatcher.dispatch AED::GenericEvent.new "foo", data = {"bar" => "baz"}
data["class"] # => "FOO"
Notice that the listeners are registered with the generic types included.
This allows the component to treat AED::GenericEvent(String, Int32)
differently than AED::GenericEvent(String, String)
.
The added benefit of this is that the listener is also aware of the type returned by the related methods, so no manual casting is required.
TIP: Use type aliases to give better names to commonly used generic types.
alias UserCreatedEvent = AED::GenericEvent(User, String)
Included Modules
Direct Known Subclasses
Defined in:
event.crClass Method Summary
-
.callable(*, priority : Int32 = 0, name : String | Nil = nil, &block : self, AED::EventDispatcherInterface -> Nil) : AED::Callable
Returns an
AED::Callable
based on the event class the method was called on.
Instance methods inherited from module Athena::EventDispatcher::StoppableEvent
propagate? : Bool
propagate?,
stop_propagation : Nil
stop_propagation
Class Method Detail
Returns an AED::Callable
based on the event class the method was called on.
Optionally allows customizing the priority and name of the listener.
class MyEvent < AED::Event; end
callable = MyEvent.callable do |event, dispatcher|
# Do something with the event, and/or dispatcher
end
dispatcher.listener callable
Essentially the same as using [AED::EventDispatcherInterface#listener(event_class,,priority,&)][Athena::EventDispatcher::EventDispatcherInterface#listener(callable,,priority)], but removes the need to pass the event_class.