IEventsAdapter#
Fully qualified name: carb::events::IEventsAdapter
Defined in carb/events/IEventsAdapter.h
-
class IEventsAdapter#
Interface for creating IEventStream objects that adapt IEventStream functionality to carb::eventdispatcher systems.
The IEventsAdapter interface can be used similarly to IEvents to create a specialized type of IEventStream that can be used to map and redirect events through the newer carb::eventdispatcher::IEventDispatcher system.
IEventsAdapter is meant to ease the transition from using IEventStream by switching to eventdispatcher::IEventDispatcher. The IEventStream created by IEventsAdapter can be used by existing APIs (Python and C++) and it will translate events to-and-from IEvents.
- Typical Transition Case
Assume that you have current code which uses IEventStream, but the desire is to convert it to eventdispatcher::IEventDispatcher. Of course, this could be done but is likely to break any existing extensions or plugins that use the current IEventStream API.
Instead, code can switch to using eventdispatcher::IEventDispatcher but also use IEventsAdapter to create a special IEventStream that observes eventdispatcher::Event distribution, but translates them back to a IEvent for existing code. Conversely, if existing code pushes or dispatches events using IEventStream, the adapter will translate these to eventdispatcher::Event and notify observers.
IEventStream is complicated and used in a variety of ways. The following AdapterType values correspond to the typical IEventStream uses:
- AdapterType::eDispatch
AdapterType::eDispatch - The simplest adapter type. Most functionality for IEventStream is disabled. This is for adapting IEventStream instances that only call IEventStream::dispatch; IEventStream::push and IEventStream::pop functionality is disabled and will result in error logging. Push-side subscribers will never be called.
Conversion to use this mode simply requires using eventdispatcher::IEventDispatcher::dispatchEvent to dispatch events. The AdapterDesc::mappings should contain entries for all event names that should be converted to IEvent by the adapter.
- AdapterType::ePushPump
Another common use case for IEventStream is a stream to which objects are pushed and then immediately pumped from the same thread. From the eventdispatcher::IEventDispatcher perspective, this is likely to convert to a single eventdispatcher::IEventDispatcher::dispatchEvent call. However, this mode correctly supports both push- and pop-side subscribers as they would be correctly called in legacy code.
In this mode, when eventdispatcher::IEventDispatcher::dispatchEvent is called, if any push-side subscribers exist on the IEventStream, they are notified prior to pop-side subscribers (and event observers).
WARNING: If multiple events were pushed before pumping, changing to single dispatchEvent calls will change the push-side notification order from multiple push notifications in a row, to push, pop, push, pop notification instead. If this is problematic, consider using the adapter to push multiple events before pumping or switch to the more complex AdapterType::eFull type.
If instead the adapter IEventStream is used to push and pump, eventdispatcher::IEventDispatcher observers are only called during the pop-side phase (i.e. pump) to maintain compatibility.
- AdapterType::eFull
The most complex use of legacy IEventStream is as both a message queue and event dispatcher. In this case, IEventStream::push is called for potentially several events, but IEventStream::pump (or IEventStream::pop) is called later and possibly even from a different thread. Converting to eventdispatcher::IEventDispatcher is a bit more complex as a queue must now be involved. This adapter type can be combined with eventdispatcher::IMessageQueue to provide the message queuing.
For conversion, the paradigm is typically:
When an event is queued, call eventdispatcher::IEventDispatcher::dispatchEvent with a pre-delivery notification event. This should be specified as MappingEntry::pushName during adapter creation and will function as the push-side IEventStream notification. Typically the name of this event will be similar to the MappingEntry::dispatchName (such as adding
:push
or:pre
for instance).Immediately after the above event is dispatched, push a message with the corresponding MappingEntry::dispatchName to the eventdispatcher::IMessageQueue in use (this must also be given to adapter creation via AdapterDesc::messageQueue).
At a later point, pop entries from the eventdispatcher::IMessageQueue and dispatch them via eventdispatcher::IEventDispatcher::dispatchEvent.
The adapter will observe the pre-delivery event and call push-side IEventListener subscribers when notified. When the event is dequeued and dispatched, the adapter will call pop-side IEventListener subscribers.
Conversely, if IEventStream::push is called, the adapter dispatches the pre-delivery notification and adds the event to the eventdispatcher::IMessageQueue. If the adapter’s IEventStream::pump is called (or IEventStream::pop), the event is popped from the eventdispatcher::IMessageQueue and immediately dispatched.
- Event Variants -> IEvent Payload Translation
The RStringKey is converted to a string via RStringKey::toString and used as the child item name in the payload.
variant::Variant of
bool
-> dictionary::ItemType::eBoolvariant::Variant of integer types -> dictionary::ItemType::eInt
variant::Variant of
float
,double
-> dictionary::ItemType::eFloatvariant::Variant of
const char*
,std::string
,omni::string
-> dictionary::ItemType::eStringvariant::Variant of
dictionary::Item*
-> copied into a new dictionary::ItemVariant
of variant::VariantArray, variant::VariantMap -> recursively copied into a new dictionary::Itemvariant::Variant of
carb::IObject*
-> attached as an object and retrievable via IEvent::retrieveObjectAnything else: result of variant::Variant::toString stored in the payload as a string
- IEvent Payload -> Event Variants Translation
If the item name is numeric only, then it is used as the number portion of RStringKey. Otherwise, the string name is converted directly to RStringKey and used as the key.
Any objects attached to the IEvent as via IEvent::attachObject are directly converted to variant::Variant of
carb::IObjectPtr
and stored as their attached object name.dictionary::ItemType::eBool -> variant::Variant of
bool
dictionary::ItemType::eFloat -> variant::Variant of
double
dictionary::ItemType::eInt -> variant::Variant of
int64_t
dictionary::ItemType::eString -> variant::Variant of
omni::string
dictionary::ItemType::eDictionary -> variant::Variant of dictionary::Item*. Note that this variant type does not manage the underlying dictionary::Item* or hold a reference to it in any way. If this value is used beyond the lifetime of the eventdispatcher::Event that delivered it, it should be copied using a method such as dictionary::IDictionary::update.
Public Functions
- inline omni::expected<IEventStreamPtr, omni::core::Result> createAdapter(
- const AdapterDesc &desc,
Creates an IEventStream that is used for simple event dispatch streams.
- Thread Safety
This function is thread-safe.
- Errors
Accessible via the omni::unexpected return value.
omni::core::kResultOutOfMemory - Memory could not be allocated for the IEventStream.
omni::core::kResultVersionCheckFailure - The AdapterDesc has an invalid
sizeOf
field.omni::core::kResultInvalidArgument - The AdapterDesc is missing
mappings
orpushMappings
, or the uniqueness constraints are not met; AdapterType::eFull was specified and AdapterDesc::messageQueue is missing. More information may be available with verbose logging.
- Parameters:
desc – The AdapterDesc describing the adapter type.
- Returns:
An omni::expected type containing the pointer to the created IEventStream, or if the IEventStream could not be created, a omni::unexpected containing the error.
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.