IEventDispatcher#
Fully qualified name: carb::eventdispatcher::IEventDispatcher
Defined in carb/eventdispatcher/IEventDispatcher.h
-
struct IEventDispatcher#
Interface for carb.eventdispatcher.plugin.
Public Functions
-
template<class Invocable, class ...Args>
ObserverGuard observeEvent( - RStringKey observerName,
- Order order,
- RString eventName,
- Invocable &&invocable,
- Args&&... filterArgs,
Registers an observer with the Event Dispatcher system.
An observer is an invocable object (function, functor, lambda, etc.) that is called whenever dispatchEvent() is called. The observers are invoked in the thread that calls dispatchEvent(), and multiple threads could be calling dispatchEvent() simultaneously, so observers must be thread-safe unless the application can ensure synchronization around dispatchEvent() calls.
The
invocable
callback will always see theeventName
that matches theeventName
thatobserveEvent
was called with, even if the event was dispatched as an alias. The sameinvocable
callback can observe multiple events; different calls may be differentiated with the Event::eventName property.Observers can pass zero or any number of
filterArgs
parameters. ThesefilterArgs
cause an observer to only be invoked for a dispatchEvent() call that contains at least the same values. For instance, having a filter pair for key “WindowID” with a specific value will only cause the observer to be called if dispatchEvent() is given the same value as a “WindowID” parameter.Observers can be added inside of an observer notification (i.e. during a call to dispatchEvent()), however these new observers will not be called for the currently dispatching event. A subsequent recursive call to dispatchEvent() will also call the new observer. The new observer will be available to all other threads potentially before
observeEvent()
returns. WARNING: this means that the return value may not be available before the observer’sinvocable
is called. If this is an issue, it is recommended to acquire a mutex before the call toobserveEvent()
and release it after the ObserverGuard is returned. Any access to the ObserverGuard should acquire the same mutex.- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher. NOTE: the
invocable
callback can be invoked simultaneously by multiple threads if the event is dispatched simultaneously from multiple threads.
- Parameters:
observerName – A name for this observer, used in profiling and debugging.
order – A value determining call order. Observers with lower order values are called earlier. Observers with the same order value will be called in the order they are registered, regardless of filter arguments.
eventName – The name of the event to observe.
invocable – An object that is invoked when an event matching the
eventName
andfilterArgs
is dispatched. The object must be callable asvoid(const Event&)
.filterArgs – Zero or more arguments that filter observer invocations. Each argument must be of type
std::pair<RStringKey, T>
where the first parameter is the key and the second is the value. The value must be of a type understood by a variant::Translator specialization.
- Returns:
An ObserverGuard representing the lifetime of the observer. When the ObserverGuard is reset or destroyed, the observer is unregistered as with stopObserving().
-
template<class Invocable, class InIter>
ObserverGuard observeEventIter( - RStringKey observerName,
- Order order,
- RString eventName,
- Invocable &&invocable,
- InIter begin,
- InIter end,
Registers an observer with the Event Dispatcher system.
An observer is an invocable object (function, functor, lambda, etc.) that is called whenever dispatchEvent() is called. The observers are invoked in the thread that calls dispatchEvent(), and multiple threads could be calling dispatchEvent() simultaneously, so observers must be thread-safe unless the application can ensure synchronization around dispatchEvent() calls.
The
invocable
callback will always see theeventName
that matches theeventName
thatobserveEventIter
was called with, even if the event was dispatched as an alias. The sameinvocable
callback can observe multiple events; different calls may be differentiated with the Event::eventName property.Observers can pass zero or any number of
filterArgs
parameters. ThesefilterArgs
cause an observer to only be invoked for a dispatchEvent() call that contains at least the same values. For instance, having a filter pair for key “WindowID” with a specific value will only cause the observer to be called if dispatchEvent() is given the same value as a “WindowID” parameter.Observers can be added inside of an observer notification (i.e. during a call to dispatchEvent()), however these new observers will not be called for the currently dispatching event. A subsequent recursive call to dispatchEvent() will also call the new observer. The new observer will be available to all other threads potentially before
observeEventIter()
returns. WARNING: this means that the return value may not be available before the observer’sinvocable
is called. If this is an issue, it is recommended to acquire a mutex before the call toobserveEventIter()
and release it after the ObserverGuard is returned. Any access to the ObserverGuard should acquire the same mutex.- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher. NOTE: the
invocable
callback can be invoked simultaneously by multiple threads if the event is dispatched simultaneously from multiple threads.
- Parameters:
observerName – A name for this observer, used in profiling and debugging.
order – A value determining call order. Observers with lower order values are called earlier. Observers with the same order value will be called in the order they are registered, regardless of filter arguments.
eventName – The name of the event to observe.
invocable – An object that is invoked when an event matching the
eventName
andfilterArgs
is dispatched. The object must be callable asvoid(const Event&)
.begin – An InputIterator representing the start of the filter parameters.
end – A past-the-end InputIterator representing the end of the filter parameters.
- Template Parameters:
InIter – An InputIterator that is forward-iterable and resolves to a NamedVariant when dereferenced.
- Returns:
An ObserverGuard representing the lifetime of the observer. When the ObserverGuard is reset or destroyed, the observer is unregistered as with stopObserving().
-
template<class R, class Invocable>
inline ObserverGuard observeEventRange( - RStringKey observerName,
- Order order,
- RString eventName,
- Invocable &&invocable,
- R &&range,
Registers an observer with the Event Dispatcher system.
An observer is an invocable object (function, functor, lambda, etc.) that is called whenever dispatchEvent() is called. The observers are invoked in the thread that calls dispatchEvent(), and multiple threads could be calling dispatchEvent() simultaneously, so observers must be thread-safe unless the application can ensure synchronization around dispatchEvent() calls.
The
invocable
callback will always see theeventName
that matches theeventName
thatobserveEventRange
was called with, even if the event was dispatched as an alias. The sameinvocable
callback can observe multiple events; different calls may be differentiated with the Event::eventName property.Observers can pass zero or any number of
filterArgs
parameters. ThesefilterArgs
cause an observer to only be invoked for a dispatchEvent() call that contains at least the same values. For instance, having a filter pair for key “WindowID” with a specific value will only cause the observer to be called if dispatchEvent() is given the same value as a “WindowID” parameter.Observers can be added inside of an observer notification (i.e. during a call to dispatchEvent()), however these new observers will not be called for the currently dispatching event. A subsequent recursive call to dispatchEvent() will also call the new observer. The new observer will be available to all other threads potentially before
observeEventRange()
returns. WARNING: this means that the return value may not be available before the observer’sinvocable
is called. If this is an issue, it is recommended to acquire a mutex before the call toobserveEventRange()
and release it after the ObserverGuard is returned. Any access to the ObserverGuard should acquire the same mutex.- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher. NOTE: the
invocable
callback can be invoked simultaneously by multiple threads if the event is dispatched simultaneously from multiple threads.
- Parameters:
observerName – A name for this observer, used in profiling and debugging.
order – A value determining call order. Observers with lower order values are called earlier. Observers with the same order value will be called in the order they are registered, regardless of filter arguments.
eventName – The name of the event to observe.
invocable – An object that is invoked when an event matching the
eventName
andfilterArgs
is dispatched. The object must be callable asvoid(const Event&)
.range – The range to use as message parameters. See explanation of the
R
type above.
- Template Parameters:
R – A range type. Since this implementation is for pre-C++20 and C++20 ranges are not available, this is an approximation: this type must work with
std::begin()
andstd::end()
to produce an iterator type that conforms to InputIterator. The iterator must resolve to astd::pair<RStringKey, T>
when dereferenced, where the first parameter is the key and the second parameter is the value and must be a type understood by a variant::Translator specialization. Each key must be unique, otherwise it is not defined which non-unique value is obtained when the key is queried.- Returns:
An ObserverGuard representing the lifetime of the observer. When the ObserverGuard is reset or destroyed, the observer is unregistered as with stopObserving().
-
template<class ...Args>
bool hasObservers(
)# Queries the Event Dispatcher whether any observers are listening to a specific event signature.
Emulates a call to dispatchEvent() (without actually calling any observers) and returns
true
if any observers would be called.- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
- Parameters:
eventName – The name of the event to query.
filterArgs – Zero or more key/value pairs that would be used for observer filtering as in a call to dispatchEvent(). Each argument must be of type
std::pair<RStringKey, T>
where the first parameter is the key and the second is the value. The value must be of a type understood by a variant::Translator specialization.
- Returns:
true
if at least one observer would be called if the same arguments were passed to dispatchEvent();false
otherwise.
-
template<class InIter>
bool hasObserversIter(
)# Queries the Event Dispatcher whether any observers are listening to a specific event signature.
Emulates a call to dispatchEvent() (without actually calling any observers) and returns
true
if any observers would be called.- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
- Template Parameters:
InIter – An InputIterator that is forward-iterable and resolves to a NamedVariant when dereferenced. The entries are used for observer filtering.
- Parameters:
eventName – The name of the event to query.
begin – An InputIterator representing the start of the event key/value pairs.
end – A past-the-end InputIterator representing the end of the event key/value pairs.
- Returns:
true
if at least one observer would be called if the same arguments were passed to dispatchEvent();false
otherwise.
-
template<class R>
inline bool hasObserversRange(
)# Queries the Event Dispatcher whether any observers are listening to a specific event signature.
Emulates a call to dispatchEvent() (without actually calling any observers) and returns
true
if any observers would be called.- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
- Template Parameters:
R – A range type. Since this implementation is for pre-C++20 and C++20 ranges are not available, this is an approximation: this type must work with
std::begin()
andstd::end()
to produce an iterator type that conforms to InputIterator. The iterator must resolve to astd::pair<RStringKey, T>
when dereferenced, where the first parameter is the key and the second parameter is the value and must be a type understood by a variant::Translator specialization. Each key must be unique, otherwise it is not defined which non-unique value is obtained when the key is queried.- Parameters:
eventName – The name of the event to query.
range – The range to use as observer parameters. See explanation of the
R
type above.
- Returns:
true
if at least one observer would be called if the same arguments were passed to dispatchEvent();false
otherwise.
- size_t dispatchEvent( )#
Re-dispatch an Event potentially as a different eventName.
This can also be combined with a IMessageQueue to dispatch queued events.
- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
Warning
While it is safe to recursively dispatch events, this call can lead to endless recursion if the event name is unchanged.
- Parameters:
event – The event to re-dispatch.
newEventName – The event name to override Event::eventName from
event
. Only used if notnullptr
.
- Returns:
The count of observers that were called. Recursive dispatch calls are not included.
-
template<class ...Args>
size_t dispatchEvent(
)# Dispatches an event and immediately calls all observers that would observe this particular event.
Finds and calls all observers (in the current thread) that observe the given event signature.
It is safe to recursively dispatch events (i.e. call dispatchEvent() from a called observer), but care must be taken to avoid endless recursion. See the rules in observeEvent() for observers added during a dispatchEvent() call.
- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
- Parameters:
eventName – The name of the event to dispatch.
payload – Zero or more key/value pairs that are used as the event payload and may be queried by observers or used to filter observers. Each argument must be of type
std::pair<RStringKey, T>
where the first parameter is the key and the second is the value. The value must be of a type understood by a variant::Translator specialization.
- Returns:
The count of observers that were called. Recursive dispatch calls are not included.
-
template<class InIter>
size_t dispatchEventIter(
)# Dispatches an event and immediately calls all observers that would observe this particular event.
Finds and calls all observers (in the current thread) that observe the given event signature.
It is safe to recursively dispatch events (i.e. call dispatchEvent() from a called observer), but care must be taken to avoid endless recursion. See the rules in observeEvent() for observers added during a dispatchEvent() call.
- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
- Template Parameters:
InIter – An InputIterator that is forward-iterable and resolves to a NamedVariant when dereferenced. The entries are used as the event payload and may be queried by observers or used to filter observers.
- Parameters:
eventName – The name of the event to dispatch.
begin – An InputIterator representing the start of the event key/value pairs.
end – A past-the-end InputIterator representing the end of the event key/value pairs.
- Returns:
The count of observers that were called. Recursive dispatch calls are not included.
-
template<class R>
inline size_t dispatchEventRange(
)# Dispatches an event and immediately calls all observers that would observe this particular event.
Finds and calls all observers (in the current thread) that observe the given event signature.
It is safe to recursively dispatch events (i.e. call dispatchEvent() from a called observer), but care must be taken to avoid endless recursion. See the rules in observeEvent() for observers added during a dispatchEvent() call.
- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
- Template Parameters:
R – A range type. Since this implementation is for pre-C++20 and C++20 ranges are not available, this is an approximation: this type must work with
std::begin()
andstd::end()
to produce an iterator type that conforms to InputIterator. The iterator must resolve to astd::pair<RStringKey, T>
when dereferenced, where the first parameter is the key and the second parameter is the value and must be a type understood by a variant::Translator specialization. Each key must be unique, otherwise it is not defined which non-unique value is obtained when the key is queried.- Parameters:
eventName – The name of the event to dispatch.
range – The range to use for key/value pairs. See explanation of the
R
type above.
- Returns:
The count of observers that were called. Recursive dispatch calls are not included.
Public Members
-
bool (*stopObserving)(Observer ob)#
Stops the given observer.
Safe to perform while dispatching.
Since observers can be in use by this thread or any thread, this function is carefully synchronized with all other IEventDispatcher operations.
During stopObserving(), further calls to the observer are prevented, even if other threads are currently dispatching an event that would be observed by the observer in question.
If any other thread is currently calling the observer in question, stopObserving() will wait until all other threads have left the observer function.
If the observer function is not in the callstack of the current thread, the cleanup function provided to
internalObserveEvent()
is called and any variant::Variant objects captured to filter events are destroyed.If the observer function is in the callstack of the current thread, stopObserving() will return without waiting, without calling the cleanup function and without destroying variant::Variant objects. Instead, this cleanup will be performed when the dispatchEvent() call in the current thread finishes.
Except when the observer function is in the callstack of the current thread, the following guarantee is made: when stopObserving() returns, the observer function will no longer be called, all calls to it have completed, and the Invocable and any filter arguments passed to observeEvent() (or similar) have been destroyed.
See also
- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
Warning
This function must be called exactly once per Observer created by observeEvent(). The ObserverGuard calls this function automatically upon destruction or by ObserverGuard::reset().
- Param ob:
The Observer to stop.
- Return:
true
if the Observer was found and stopped;false
otherwise.
-
bool (*isDispatching)(bool currentThread)#
Queries to see if the system is currently dispatching an event.
- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
- Param currentThread:
If
false
, checks to see if any thread is currently dispatching. However, the return value should be used for debugging purposes only as it is a transient value and could be stale by the time it is read by the application. Iftrue
, checks to see if the current thread is dispatching (that is, the callstack includes a call to dispatchEvent()).- Return:
true
if any thread or the current thread is dispatching based on the value ofcurrentThread
;false
otherwise.
-
bool (*getObserverName)(Observer ob, RStringKey &nameOut)#
Retrieves the name of an observer.
- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
- Param ob:
The observer to query, typically accessed from ObserverGuard::get.
- Param nameOut:
Receives the name of the observer, originally passed to observeEvent or similar.
- Return:
true
if the observer was valid and the name was retrieved;false
otherwise.
-
bool (*getObserverOrder)(Observer ob, Order &orderOut)#
Gets the ‘order’ value of an observer.
- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
- Param ob:
The observer to query, typically accessed from ObserverGuard::get.
- Param orderOut:
Receives the order value of the observer.
- Return:
true
if the observer was valid and the order was retrieved;false
otherwise.
-
bool (*setObserverOrder)(Observer ob, Order newOrder)#
Changes the ‘order’ value of an observer.
- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
- Param ob:
The observer to change, typically accessed from ObserverGuard::get.
- Param newOrder:
The new order value to set.
- Return:
true
if the observer was valid and the order was set;false
otherwise.
-
bool (*getObserverEnabled)(Observer ob, bool &enabledOut)#
Gets the ‘enabled’ state of an observer.
- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
- Param ob:
The observer to query, typically accessed from ObserverGuard::get.
- Param enabledOut:
Receives the enabled state of the observer.
- Return:
true
if the observer was valid and the enabled state was retrieved;false
otherwise.
-
bool (*setObserverEnabled)(Observer ob, bool enabled)#
Changes the ‘enabled’ state of an observer.
- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
- Param ob:
The observer to query, typically accessed from ObserverGuard::get.
- Param enabled:
The new enabled state to set.
- Return:
true
if the observer was valid and the enabled state was set;false
otherwise.
-
size_t (*removeAllObserversFor)(RString eventName)#
Removes all observers for the given event.
Typically a system might do this when it will never send a particular event again, such at shutdown. After calling this, hasObservers() for
eventName
will returnfalse
. Observers with filter arguments foreventName
will also be removed. Observers are removed in the reverse of the registration order. ObserverGuard destruction may still occur but will not have an effect. Calls to stopObserving() for observers of this event will returnfalse
.- Thread Safety
It is safe to call this from multiple threads, and safe to call from event handlers.
Warning
This will forcibly remove all observers, which will receive no notification that they have been removed.
Warning
Unlike stopObserving(), this function does not have a strong guarantee to wait for the event function to be complete and the observer to be cleaned up before returning. If this is problematic, explicitly call stopObserving() for the observer in question.
- Param eventName:
The event to remove all observers for.
- Return:
The number of observers that were removed.
-
bool (*addEventAlias)(RString target, RString alias)#
Adds an alias that can be used to observe and dispatch as a different event.
Event aliases are a powerful tool. An alias target may have as many aliases as necessary, but an alias may not have any aliases of its own. Similarly, an alias target may not function as an alias for any other alias target.
Thus an alias target is considered a primary event, and any aliases that it is known by can also be used to dispatch or receive events.
Dispatching to an alias acts the same as dispatching to an alias target directly: Any observers of any aliases for that alias target will observe the event, as well as the alias target itself. However, the Event::eventName property will be the same as the alias they’re observing, not the alias target and potentially not even the alias that was dispatched. See observeEvent() for more information.
Aliases can be removed with removeEventAlias() or removeAllEventAliasesFor().
While it is possible to add or remove an alias from an observer callback, it will not affect the current event dispatch.
- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
- Param target:
The target event to create an alias for.
- Param alias:
The alias that will refer to
target
.- Retval true:
A new alias was created.
- Retval false:
target
andalias
are the same,target
oralias
are already used as aliases or targets respectively, oralias
already exists as an alias oftarget
.
-
bool (*removeEventAlias)(RString target, RString alias)#
Removes a previously-added alias.
Aliases are added with addEventAlias().
Once
alias
is removed as an alias, thealias
event can be added as an alias for a different target, or used as a target itself. Similarly, oncetarget
has all aliases removed, it can be used as an alias or as a target in the future.While it is possible to add or remove an alias from an observer callback, it will not affect the current event dispatch.
- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
- Param target:
The target event to remove an alias from.
- Param alias:
The alias to remove from
target
.- Retval true:
An existing alias was found and removed.
- Retval false:
target
andalias
are the same;target
is not an event target, oralias
is not an event alias; ortarget
does not have an aliasalias
.
-
size_t (*removeAllEventAliasesFor)(RString target)#
Removes all aliases for a given event target.
Aliases are added with addEventAlias().
Once an alias is removed from a target, any former alias event can be added as an alias for a different target, or used as a target itself. Similarly, once
target
has all aliases removed, it can be used as an alias or as a target in the future.While it is possible to add or remove an alias from an observer callback, it will not affect the current event dispatch.
- Thread Safety
Safe to perform while any thread is performing any operation against IEventDispatcher.
- Param target:
The target event to remove all aliases from.
- Return:
The number of aliases removed. A value of 0 indicates that
target
is not actually an event target or currently has no aliases.
Public Static Functions
- static inline constexpr carb::InterfaceDesc getInterfaceDesc(
Returns information about this interface.
Auto-generated by CARB_PLUGIN_INTERFACE() or CARB_PLUGIN_INTERFACE_EX.
- Returns:
The carb::InterfaceDesc struct with information about this interface.
- static inline constexpr carb::InterfaceDesc getLatestInterfaceDesc(
Returns information about the latest version of this interface.
Auto-generated by CARB_PLUGIN_INTERFACE() or CARB_PLUGIN_INTERFACE_EX.
- Returns:
The carb::InterfaceDesc struct with information about the latest version of this interface.
-
template<class Invocable, class ...Args>