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,
int 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.

Observers can pass zero or any number of filterArgs parameters. These filterArgs 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() (on the current thread only) will also call the new observer. The new observer will be available to all other threads once the dispatchEvent() call&#8212;in which it was added&#8212;returns.

Thread Safety

Safe to perform while any thread is performing any operation against IEventDispatcher.

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 and same filter argument values will be called in the order they are registered. Observers with the same order value with different filter argument values are called in an indeterminate order.

  • eventName – The name of the event to observe.

  • invocable – An object that is invoked when an event matching the eventName and filterArgs is dispatched. The object must be callable as void(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,
int 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.

Observers can pass zero or any number of filterArgs parameters. These filterArgs 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. However, a recursive call to dispatchEvent() (on the current thread only) will also call the new observer. The new observer will be available to all other threads once the dispatchEvent() call&#8212;in which it was added&#8212;returns.

Thread Safety

Safe to perform while any thread is performing any operation against IEventDispatcher.

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 and same filter argument values will be called in the order they are registered. Observers with the same order value with different filter argument values are called in an indeterminate order.

  • eventName – The name of the event to observe.

  • invocable – An object that is invoked when an event matching the eventName and filterArgs is dispatched. The object must be callable as void(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,
int 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.

Observers can pass zero or any number of filterArgs parameters. These filterArgs 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. However, a recursive call to dispatchEvent() (on the current thread only) will also call the new observer. The new observer will be available to all other threads once the dispatchEvent() call&#8212;in which it was added&#8212;returns.

Thread Safety

Safe to perform while any thread is performing any operation against IEventDispatcher.

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 and same filter argument values will be called in the order they are registered. Observers with the same order value with different filter argument values are called in an indeterminate order.

  • eventName – The name of the event to observe.

  • invocable – An object that is invoked when an event matching the eventName and filterArgs is dispatched. The object must be callable as void(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() and std::end() to produce an iterator type that conforms to InputIterator. The iterator must resolve to a std::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(
RString eventName,
Args&&... filterArgs,
)#

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(
RString eventName,
InIter begin,
InIter end,
)#

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(
RString eventName,
R &&range,
)#

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() and std::end() to produce an iterator type that conforms to InputIterator. The iterator must resolve to a std::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(
const Event &event,
RString *newEventName = nullptr,
)#

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 not nullptr.

Returns:

The count of observers that were called. Recursive dispatch calls are not included.

template<class ...Args>
size_t dispatchEvent(
RString eventName,
Args&&... payload,
)#

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(
RString eventName,
InIter begin,
InIter end,
)#

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(
RString eventName,
R &&range,
)#

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() and std::end() to produce an iterator type that conforms to InputIterator. The iterator must resolve to a std::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, calling the cleanup function or destroying variant::Variant objects. Instead, this cleanup will be performed when the dispatchEvent() call in the current thread finishes.

When stopObserving() returns, it is guaranteed that the observer function will no longer be called and all calls to it have completed (except if the calling thread is dispatching).

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.

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. If true, 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 of currentThread; 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, int &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, int 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.

Public Static Functions

static inline constexpr carb::InterfaceDesc getInterfaceDesc(
) noexcept#

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(
) noexcept#

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.