module EventHandler

Defined in:

event.cr
event_handler.cr:1
event_handler.cr:57
events.cr
macros.cr
subscription.cr
wrapper.cr

Constant Summary

EMIT_COPY_ON_WRITE = true

Compile-time switch for copy-on-write handler lists.

When true (default), the per-type handler array is immutable: #on/#off/ #remove_all_handlers build a fresh array and swap it in under the lock, rather than mutating the shared array in place. This lets _emit take its snapshot by reading the reference instead of duping on every emit — since emits vastly outnumber subscription changes, this moves the copy off the hot path.

Because the captured array is never mutated, _emit reads its snapshot without taking the lock — a single atomic pointer load. The mutex only serializes writers against each other (their dup→mutate→swap is a read-modify-write that would otherwise lose updates).

Correctness holds because no array is mutated in place while a concurrent (or reentrant) _emit might be iterating it: a writer always publishes a new array, and an in-flight emit keeps iterating its captured snapshot — the same semantics the previous dup provided. Relies on pointer-sized reference assignment being atomic (true on all supported targets).

Set to false to restore the original in-place mutation + per-emit dup; when disabled the copy-on-write code is not generated.

EMIT_SKIP_WHEN_NO_HANDLERS = true

Compile-time switch for the "skip emit when nothing is subscribed" fast path.

When true (default), #emit/_emit return immediately if the event has no registered handlers (neither its concrete type nor the catch-all AnyEvent), avoiding the per-emit reentrant-mutex lock and handler-array dup. Matters for emit-heavy workloads (e.g. a UI render loop) with no listeners.

The fast path reads Array#empty? without holding the lock — a benign race already inherent to the snapshot design (a handler added concurrently with an emit isn't guaranteed to observe that emit). Set to false to restore unconditional locking; a compile-time constant so the guard generates no code at all when disabled.

Log = ::Log.for("event_handler")

Logger used to report failures that occur while dispatching a handler asynchronously. See Wrapper#call_async for the async error contract.

Per Crystal's Log conventions, emits nothing until the application configures a backend (e.g. Log.setup_from_env). Applications that care about async handler failures should configure one to see these entries.

VERSION = "2.0.0"

Class Method Summary

Macro Summary

Instance Method Summary

Class Method Detail

def self.async=(async : Bool) #

Asynchronous execution flag; default false.

Controls whether event handlers execute synchronously one by one, or asynchronously in Fibers.

EventHandler.async? # => false
EventHandler.async = true

Only affects the default; can be overriden per-handler via the async argument when subscribing.


[View source]
def self.async? : Bool #

Asynchronous execution flag; default false.

Controls whether event handlers execute synchronously one by one, or asynchronously in Fibers.

EventHandler.async? # => false
EventHandler.async = true

Only affects the default; can be overriden per-handler via the async argument when subscribing.


[View source]
def self.async_send=(async_send : Bool) #

Asynchronous execution flag for #waited events; default false.

Controls whether implicitly created handlers that forward events through channels execute synchronously or asynchronously.

EventHandler.async_send? # => false
EventHandler.async_send = true

Only affects the default; can be overriden per-#wait via async_send.


[View source]
def self.async_send? : Bool #

Asynchronous execution flag for #waited events; default false.

Controls whether implicitly created handlers that forward events through channels execute synchronously or asynchronously.

EventHandler.async_send? # => false
EventHandler.async_send = true

Only affects the default; can be overriden per-#wait via async_send.


[View source]
def self.at_beginning : Int32 #

Default insertion index for a handler inserted at the beginning of the list; default 0.

Changing this can cause "Index out of bounds" exceptions if not done carefully; rarely needs changing.


[View source]
def self.at_beginning=(at_beginning : Int32) #

Default insertion index for a handler inserted at the beginning of the list; default 0.

Changing this can cause "Index out of bounds" exceptions if not done carefully; rarely needs changing.


[View source]
def self.at_end : Int32 #

Default insertion index for a handler inserted at the end of the list; default -1.

Changing this can cause "Index out of bounds" exceptions if not done carefully; rarely needs changing.


[View source]
def self.at_end=(at_end : Int32) #

Default insertion index for a handler inserted at the end of the list; default -1.

Changing this can cause "Index out of bounds" exceptions if not done carefully; rarely needs changing.


[View source]
def self.emit_on_remove_all=(emit_on_remove_all : Bool) #

RemoveHandlerEvent control flag for #remove_all; default true.

Controls whether handlers removed by #remove_all emit a RemoveHandlerEvent. Disabling can make sense at application shutdown when running those handlers no longer matters.

EventHandler.emit_on_remove_all? # => true
EventHandler.emit_on_remove_all = false

[View source]
def self.emit_on_remove_all? : Bool #

RemoveHandlerEvent control flag for #remove_all; default true.

Controls whether handlers removed by #remove_all emit a RemoveHandlerEvent. Disabling can make sense at application shutdown when running those handlers no longer matters.

EventHandler.emit_on_remove_all? # => true
EventHandler.emit_on_remove_all = false

[View source]

Macro Detail

macro event(e, *args) #

Creates events in a single line; every event is a class inheriting from EventHandler::Event.

Since events are classes, they can also be created manually. See EventHandler::Event for more details.

event MouseClick, x : ::Int32, y : ::Int32

[View source]

Instance Method Detail

def emit(type : EventHandler::AnyEvent.class, event : EventHandler::AnyEvent) #

Emits event of type.

When EMIT_SKIP_WHEN_NO_HANDLERS, #emit gains a fast path: if neither this concrete type nor the catch-all AnyEvent has any handler, it returns immediately. It's @[AlwaysInline] so, in the common no-subscriber case, the guard folds into the caller as two @size == 0 comparisons — no call into _emit, no lock, no allocation. With the constant off, neither the annotation nor the guard is generated and #emit is the original two-line dispatch.


def emit(type : EventHandler::AddHandlerEvent.class, event : EventHandler::AddHandlerEvent) #

Emits event of type.

When EMIT_SKIP_WHEN_NO_HANDLERS, #emit gains a fast path: if neither this concrete type nor the catch-all AnyEvent has any handler, it returns immediately. It's @[AlwaysInline] so, in the common no-subscriber case, the guard folds into the caller as two @size == 0 comparisons — no call into _emit, no lock, no allocation. With the constant off, neither the annotation nor the guard is generated and #emit is the original two-line dispatch.


def emit(type : EventHandler::RemoveHandlerEvent.class, event : EventHandler::RemoveHandlerEvent) #

Emits event of type.

When EMIT_SKIP_WHEN_NO_HANDLERS, #emit gains a fast path: if neither this concrete type nor the catch-all AnyEvent has any handler, it returns immediately. It's @[AlwaysInline] so, in the common no-subscriber case, the guard folds into the caller as two @size == 0 comparisons — no call into _emit, no lock, no allocation. With the constant off, neither the annotation nor the guard is generated and #emit is the original two-line dispatch.


def emit(event : EventHandler::Event) #

Emits event of type event.class


[View source]
def emit(type : EventHandler::AnyEvent.class, *args) #

Emits event of type.

When EMIT_SKIP_WHEN_NO_HANDLERS, #emit gains a fast path: if neither this concrete type nor the catch-all AnyEvent has any handler, it returns immediately. It's @[AlwaysInline] so, in the common no-subscriber case, the guard folds into the caller as two @size == 0 comparisons — no call into _emit, no lock, no allocation. With the constant off, neither the annotation nor the guard is generated and #emit is the original two-line dispatch.


def emit(type : EventHandler::AddHandlerEvent.class, *args) #

Emits event of type.

When EMIT_SKIP_WHEN_NO_HANDLERS, #emit gains a fast path: if neither this concrete type nor the catch-all AnyEvent has any handler, it returns immediately. It's @[AlwaysInline] so, in the common no-subscriber case, the guard folds into the caller as two @size == 0 comparisons — no call into _emit, no lock, no allocation. With the constant off, neither the annotation nor the guard is generated and #emit is the original two-line dispatch.


def emit(type : EventHandler::RemoveHandlerEvent.class, *args) #

Emits event of type.

When EMIT_SKIP_WHEN_NO_HANDLERS, #emit gains a fast path: if neither this concrete type nor the catch-all AnyEvent has any handler, it returns immediately. It's @[AlwaysInline] so, in the common no-subscriber case, the guard folds into the caller as two @size == 0 comparisons — no call into _emit, no lock, no allocation. With the constant off, neither the annotation nor the guard is generated and #emit is the original two-line dispatch.


def handlers(type : EventHandler::AnyEvent.class) #

Returns the list of handlers for event type.


def handlers(type : EventHandler::AddHandlerEvent.class) #

Returns the list of handlers for event type.


def handlers(type : EventHandler::RemoveHandlerEvent.class) #

Returns the list of handlers for event type.


def has_handlers?(type : EventHandler::AnyEvent.class) : Bool #

Whether any handler is registered for type. Allocation-free (unlike handlers(type).any?, which dups the COW list).


def has_handlers?(type : EventHandler::AddHandlerEvent.class) : Bool #

Whether any handler is registered for type. Allocation-free (unlike handlers(type).any?, which dups the COW list).


def has_handlers?(type : EventHandler::RemoveHandlerEvent.class) : Bool #

Whether any handler is registered for type. Allocation-free (unlike handlers(type).any?, which dups the COW list).


def off(type : EventHandler::AnyEvent.class, subscription : EventHandler::Subscription) #

Removes the handler behind subscription — the subscription-typed spelling of #off(type, wrapper); returns the removed wrapper, or nil when it was no longer registered (or the subscription carries no wrapper).


def off(type : EventHandler::AnyEvent.class, handler : Proc(EventHandler::AnyEvent, Nil)) #

Removes handler from the list of handlers for event type.


def off(type : EventHandler::AnyEvent.class, hash : UInt64) #

Removes handler from the list of handlers for event type.


def off(type : EventHandler::AnyEvent.class, wrapper : EventHandler::Wrapper(Proc(EventHandler::Event, Nil))) #

Removes handler from the list of handlers for event type.


def off(type : EventHandler::AnyEvent.class, at : Int) #

Removes handler from the list of handlers for event type.


def off(type : EventHandler::AnyEvent.class, emit = ::EventHandler.emit_on_remove_all?) #

Removes all handlers for event type.

If emit is false, RemoveHandlerEvents are not emitted.

If emit is true, a RemoveHandlerEvent is emitted once for every distinct Wrapper object removed. See README for details.


def off(type : EventHandler::AddHandlerEvent.class, subscription : EventHandler::Subscription) #

Removes the handler behind subscription — the subscription-typed spelling of #off(type, wrapper); returns the removed wrapper, or nil when it was no longer registered (or the subscription carries no wrapper).


def off(type : EventHandler::AddHandlerEvent.class, handler : Proc(EventHandler::AddHandlerEvent, Nil)) #

Removes handler from the list of handlers for event type.


def off(type : EventHandler::AddHandlerEvent.class, hash : UInt64) #

Removes handler from the list of handlers for event type.


def off(type : EventHandler::AddHandlerEvent.class, wrapper : EventHandler::Wrapper(Proc(EventHandler::Event, Nil))) #

Removes handler from the list of handlers for event type.


def off(type : EventHandler::AddHandlerEvent.class, at : Int) #

Removes handler from the list of handlers for event type.


def off(type : EventHandler::AddHandlerEvent.class, emit = ::EventHandler.emit_on_remove_all?) #

Removes all handlers for event type.

If emit is false, RemoveHandlerEvents are not emitted.

If emit is true, a RemoveHandlerEvent is emitted once for every distinct Wrapper object removed. See README for details.


def off(type : EventHandler::RemoveHandlerEvent.class, subscription : EventHandler::Subscription) #

Removes the handler behind subscription — the subscription-typed spelling of #off(type, wrapper); returns the removed wrapper, or nil when it was no longer registered (or the subscription carries no wrapper).


def off(type : EventHandler::RemoveHandlerEvent.class, handler : Proc(EventHandler::RemoveHandlerEvent, Nil)) #

Removes handler from the list of handlers for event type.


def off(type : EventHandler::RemoveHandlerEvent.class, hash : UInt64) #

Removes handler from the list of handlers for event type.


def off(type : EventHandler::RemoveHandlerEvent.class, wrapper : EventHandler::Wrapper(Proc(EventHandler::Event, Nil))) #

Removes handler from the list of handlers for event type.


def off(type : EventHandler::RemoveHandlerEvent.class, at : Int) #

Removes handler from the list of handlers for event type.


def off(type : EventHandler::RemoveHandlerEvent.class, emit = ::EventHandler.emit_on_remove_all?) #

Removes all handlers for event type.

If emit is false, RemoveHandlerEvents are not emitted.

If emit is true, a RemoveHandlerEvent is emitted once for every distinct Wrapper object removed. See README for details.


def on(type : EventHandler::AnyEvent.class, handler : Proc(EventHandler::AnyEvent, Nil), once = false, async = ::EventHandler.async?, at = ::EventHandler.at_end) : EventHandler::Subscription #

Adds handler to the list of handlers for event type.

Returns an EventHandler::Subscription — a self-contained disconnect handle: sub.off removes exactly this handler, with no need to restate the event type or hold the Wrapper (cf. Qt's QMetaObject::Connection). The Wrapper itself still flows to AddHandlerEvent/RemoveHandlerEvent listeners, and the #off(type, handler/hash/at) forms keep working for callers that kept those instead.


def on(type : EventHandler::AnyEvent.class, subscription : EventHandler::Subscription) : EventHandler::Subscription #

Re-registers the Wrapper behind subscription — the subscription-typed spelling of #on(type, wrapper). Raises ArgumentError when the subscription carries no wrapper (see Subscription#wrapper).


def on(type : EventHandler::AnyEvent.class, *, once = false, async = ::EventHandler.async?, at = ::EventHandler.at_end, &handler : EventHandler::AnyEvent -> Nil) : EventHandler::Subscription #

Removes the handler behind subscription — the subscription-typed spelling of #off(type, wrapper); returns the removed wrapper, or nil when it was no longer registered (or the subscription carries no wrapper).


def on(type : EventHandler::AnyEvent.class, wrapper : EventHandler::Wrapper(Proc(EventHandler::Event, Nil))) : EventHandler::Subscription #

Removes the handler behind subscription — the subscription-typed spelling of #off(type, wrapper); returns the removed wrapper, or nil when it was no longer registered (or the subscription carries no wrapper).


def on(type : EventHandler::AnyEvent.class, channel : Channel(EventHandler::AnyEvent), once = false, async = ::EventHandler.async?, at = ::EventHandler.at_end) : EventHandler::Subscription #

Adds an autogenerated handler which sends emitted events to channel


def on(type : EventHandler::AddHandlerEvent.class, handler : Proc(EventHandler::AddHandlerEvent, Nil), once = false, async = ::EventHandler.async?, at = ::EventHandler.at_end) : EventHandler::Subscription #

Adds handler to the list of handlers for event type.

Returns an EventHandler::Subscription — a self-contained disconnect handle: sub.off removes exactly this handler, with no need to restate the event type or hold the Wrapper (cf. Qt's QMetaObject::Connection). The Wrapper itself still flows to AddHandlerEvent/RemoveHandlerEvent listeners, and the #off(type, handler/hash/at) forms keep working for callers that kept those instead.


def on(type : EventHandler::AddHandlerEvent.class, subscription : EventHandler::Subscription) : EventHandler::Subscription #

Re-registers the Wrapper behind subscription — the subscription-typed spelling of #on(type, wrapper). Raises ArgumentError when the subscription carries no wrapper (see Subscription#wrapper).


def on(type : EventHandler::AddHandlerEvent.class, *, once = false, async = ::EventHandler.async?, at = ::EventHandler.at_end, &handler : EventHandler::AddHandlerEvent -> Nil) : EventHandler::Subscription #

Removes the handler behind subscription — the subscription-typed spelling of #off(type, wrapper); returns the removed wrapper, or nil when it was no longer registered (or the subscription carries no wrapper).


def on(type : EventHandler::AddHandlerEvent.class, wrapper : EventHandler::Wrapper(Proc(EventHandler::Event, Nil))) : EventHandler::Subscription #

Removes the handler behind subscription — the subscription-typed spelling of #off(type, wrapper); returns the removed wrapper, or nil when it was no longer registered (or the subscription carries no wrapper).


def on(type : EventHandler::AddHandlerEvent.class, channel : Channel(EventHandler::AddHandlerEvent), once = false, async = ::EventHandler.async?, at = ::EventHandler.at_end) : EventHandler::Subscription #

Adds an autogenerated handler which sends emitted events to channel


def on(type : EventHandler::RemoveHandlerEvent.class, handler : Proc(EventHandler::RemoveHandlerEvent, Nil), once = false, async = ::EventHandler.async?, at = ::EventHandler.at_end) : EventHandler::Subscription #

Adds handler to the list of handlers for event type.

Returns an EventHandler::Subscription — a self-contained disconnect handle: sub.off removes exactly this handler, with no need to restate the event type or hold the Wrapper (cf. Qt's QMetaObject::Connection). The Wrapper itself still flows to AddHandlerEvent/RemoveHandlerEvent listeners, and the #off(type, handler/hash/at) forms keep working for callers that kept those instead.


def on(type : EventHandler::RemoveHandlerEvent.class, subscription : EventHandler::Subscription) : EventHandler::Subscription #

Re-registers the Wrapper behind subscription — the subscription-typed spelling of #on(type, wrapper). Raises ArgumentError when the subscription carries no wrapper (see Subscription#wrapper).


def on(type : EventHandler::RemoveHandlerEvent.class, *, once = false, async = ::EventHandler.async?, at = ::EventHandler.at_end, &handler : EventHandler::RemoveHandlerEvent -> Nil) : EventHandler::Subscription #

Removes the handler behind subscription — the subscription-typed spelling of #off(type, wrapper); returns the removed wrapper, or nil when it was no longer registered (or the subscription carries no wrapper).


def on(type : EventHandler::RemoveHandlerEvent.class, wrapper : EventHandler::Wrapper(Proc(EventHandler::Event, Nil))) : EventHandler::Subscription #

Removes the handler behind subscription — the subscription-typed spelling of #off(type, wrapper); returns the removed wrapper, or nil when it was no longer registered (or the subscription carries no wrapper).


def on(type : EventHandler::RemoveHandlerEvent.class, channel : Channel(EventHandler::RemoveHandlerEvent), once = false, async = ::EventHandler.async?, at = ::EventHandler.at_end) : EventHandler::Subscription #

Adds an autogenerated handler which sends emitted events to channel


def once(type : EventHandler::AnyEvent.class, handler : Proc(EventHandler::AnyEvent, Nil), async = ::EventHandler.async?, at = ::EventHandler.at_end) : EventHandler::Subscription #

Adds handler to the list of handlers for event type; removed automatically after it triggers once. Returns an EventHandler::Subscription (see #on); its #off is a no-op after the handler has auto-fired away.

Equivalent to #on with argument once.


def once(type : EventHandler::AnyEvent.class, async = ::EventHandler.async?, at = ::EventHandler.at_end, &handler : EventHandler::AnyEvent -> Nil) : EventHandler::Subscription #

Adds handler to the list of handlers for event type; removed automatically after it triggers once. Returns an EventHandler::Subscription (see #on); its #off is a no-op after the handler has auto-fired away.

Equivalent to #on with argument once.


def once(type : EventHandler::AnyEvent.class, channel : Channel(EventHandler::AnyEvent), async = ::EventHandler.async?, at = ::EventHandler.at_end) : EventHandler::Subscription #

Adds an autogenerated handler which sends emitted events to channel; removed automatically after it triggers once.

Equivalent to #on with argument once.


def once(type : EventHandler::AddHandlerEvent.class, handler : Proc(EventHandler::AddHandlerEvent, Nil), async = ::EventHandler.async?, at = ::EventHandler.at_end) : EventHandler::Subscription #

Adds handler to the list of handlers for event type; removed automatically after it triggers once. Returns an EventHandler::Subscription (see #on); its #off is a no-op after the handler has auto-fired away.

Equivalent to #on with argument once.


def once(type : EventHandler::AddHandlerEvent.class, async = ::EventHandler.async?, at = ::EventHandler.at_end, &handler : EventHandler::AddHandlerEvent -> Nil) : EventHandler::Subscription #

Adds handler to the list of handlers for event type; removed automatically after it triggers once. Returns an EventHandler::Subscription (see #on); its #off is a no-op after the handler has auto-fired away.

Equivalent to #on with argument once.


def once(type : EventHandler::AddHandlerEvent.class, channel : Channel(EventHandler::AddHandlerEvent), async = ::EventHandler.async?, at = ::EventHandler.at_end) : EventHandler::Subscription #

Adds an autogenerated handler which sends emitted events to channel; removed automatically after it triggers once.

Equivalent to #on with argument once.


def once(type : EventHandler::RemoveHandlerEvent.class, handler : Proc(EventHandler::RemoveHandlerEvent, Nil), async = ::EventHandler.async?, at = ::EventHandler.at_end) : EventHandler::Subscription #

Adds handler to the list of handlers for event type; removed automatically after it triggers once. Returns an EventHandler::Subscription (see #on); its #off is a no-op after the handler has auto-fired away.

Equivalent to #on with argument once.


def once(type : EventHandler::RemoveHandlerEvent.class, async = ::EventHandler.async?, at = ::EventHandler.at_end, &handler : EventHandler::RemoveHandlerEvent -> Nil) : EventHandler::Subscription #

Adds handler to the list of handlers for event type; removed automatically after it triggers once. Returns an EventHandler::Subscription (see #on); its #off is a no-op after the handler has auto-fired away.

Equivalent to #on with argument once.


def once(type : EventHandler::RemoveHandlerEvent.class, channel : Channel(EventHandler::RemoveHandlerEvent), async = ::EventHandler.async?, at = ::EventHandler.at_end) : EventHandler::Subscription #

Adds an autogenerated handler which sends emitted events to channel; removed automatically after it triggers once.

Equivalent to #on with argument once.


def remove_all_handlers(type : EventHandler::AnyEvent.class, emit = ::EventHandler.emit_on_remove_all?) #

Removes all handlers for event type.

If emit is false, RemoveHandlerEvents are not emitted.

If emit is true, a RemoveHandlerEvent is emitted once for every distinct Wrapper object removed. See README for details.


def remove_all_handlers(type : EventHandler::AddHandlerEvent.class, emit = ::EventHandler.emit_on_remove_all?) #

Removes all handlers for event type.

If emit is false, RemoveHandlerEvents are not emitted.

If emit is true, a RemoveHandlerEvent is emitted once for every distinct Wrapper object removed. See README for details.


def remove_all_handlers(type : EventHandler::RemoveHandlerEvent.class, emit = ::EventHandler.emit_on_remove_all?) #

Removes all handlers for event type.

If emit is false, RemoveHandlerEvents are not emitted.

If emit is true, a RemoveHandlerEvent is emitted once for every distinct Wrapper object removed. See README for details.


def wait(type : EventHandler::AnyEvent.class, handler : Proc(EventHandler::AnyEvent, Nil) | Nil, async = ::EventHandler.async?, at = ::EventHandler.at_end, async_send = ::EventHandler.async_send?) #

Blocks until event type is emitted and executes handler.

handler may be nil, in which case #wait blocks until the event arrives and returns it without running any handler.


def wait(type : EventHandler::AnyEvent.class, async = ::EventHandler.async?, at = ::EventHandler.at_end, async_send = ::EventHandler.async_send?, &handler : EventHandler::AnyEvent -> Nil) #

Blocks until event type is emitted and executes handler.

handler may be nil, in which case #wait blocks until the event arrives and returns it without running any handler.


def wait(type : EventHandler::AnyEvent.class, async_send = ::EventHandler.async_send?, at = ::EventHandler.at_end) #

Blocks until event type is emitted and returns emitted event.


def wait(type : EventHandler::AddHandlerEvent.class, handler : Proc(EventHandler::AddHandlerEvent, Nil) | Nil, async = ::EventHandler.async?, at = ::EventHandler.at_end, async_send = ::EventHandler.async_send?) #

Blocks until event type is emitted and executes handler.

handler may be nil, in which case #wait blocks until the event arrives and returns it without running any handler.


def wait(type : EventHandler::AddHandlerEvent.class, async = ::EventHandler.async?, at = ::EventHandler.at_end, async_send = ::EventHandler.async_send?, &handler : EventHandler::AddHandlerEvent -> Nil) #

Blocks until event type is emitted and executes handler.

handler may be nil, in which case #wait blocks until the event arrives and returns it without running any handler.


def wait(type : EventHandler::AddHandlerEvent.class, async_send = ::EventHandler.async_send?, at = ::EventHandler.at_end) #

Blocks until event type is emitted and returns emitted event.


def wait(type : EventHandler::RemoveHandlerEvent.class, handler : Proc(EventHandler::RemoveHandlerEvent, Nil) | Nil, async = ::EventHandler.async?, at = ::EventHandler.at_end, async_send = ::EventHandler.async_send?) #

Blocks until event type is emitted and executes handler.

handler may be nil, in which case #wait blocks until the event arrives and returns it without running any handler.


def wait(type : EventHandler::RemoveHandlerEvent.class, async = ::EventHandler.async?, at = ::EventHandler.at_end, async_send = ::EventHandler.async_send?, &handler : EventHandler::RemoveHandlerEvent -> Nil) #

Blocks until event type is emitted and executes handler.

handler may be nil, in which case #wait blocks until the event arrives and returns it without running any handler.


def wait(type : EventHandler::RemoveHandlerEvent.class, async_send = ::EventHandler.async_send?, at = ::EventHandler.at_end) #

Blocks until event type is emitted and returns emitted event.