Events Reference#

OmniGraph events function as callbacks to state changes being committed to graphs, nodes, attributes, and the graph registry. These events are dispatched using carb::eventdispatcher::IEventDispatcher and provide a way to monitor and react to changes in the OmniGraph system.

Since all events exist in a global namespace, OmniGraph event descriptors are composed as follows:

omni.graph.core:<category>:<event name>

The <category> and <event name> components are listed below for each event.

Events#

Warning

OmniGraph events have a global name, but typically listeners care about a specific object (Graph, Node, etc.). Therefore it is very important to specify a filter when observing an event, otherwise your observer will be called for all objects of that type. Helper functions like INode::getEventKey() and IGraph::getEventKey() exist to provide easy means to filter these events.

Graph Registry Events#

Graph Registry Events have a <category> of graph_registry, producing an event composed as omni.graph.core:graph_registry:<event name>.

Note

Graph Registry Events are queued and dispatched only when the queue is pumped. Therefore each event has both immediate and deferred options. The immediate event is dispatched when the event occurs, but observing this event may have additional constraints and may be unsafe. It is generally recommended to instead observe the deferred event which is dispatched at a later time when conditions are safer.

Node Type Added#

A node type has been added to the registry.

Parameters:

  • node_type (string) - Name of the new node type

  • node_ptr (numeric) - Convertible to a omni::graph::core::NodeTypeDef pointer. NOTE! May be unsafe to access this on a deferred event.

Node Type Removed#

A node type has been removed from the registry.

Parameters:

  • node_type (string) - Name of the removed node type

  • node_ptr (numeric) - Convertible to a omni::graph::core::NodeTypeDef pointer. NOTE! May be unsafe to access this on a deferred event.

Node Type Namespace Changed#

A node type has had its namespace changed.

Parameters:

  • node_type (string) - New namespace

  • prev_type (string) - Previous namespace

Node Type Category Changed#

A node type has had its category changed.

Parameters:

  • node_type (string) - Node type whose category changed

  • prev_value (string) - Previous category value

Stage Pre Attach#

A stage is being attached.

Parameters:

  • has_og_prims_on_stage (bool) - Is true if the stage that is being loaded contains OmniGraph nodes, otherwise is false

Node Events#

Node Events have a <category> of node, producing an event composed as omni.graph.core:node:<event name>.

Warning

OmniGraph Node events have a global name, but typically listeners care about a specific Node instance. Therefore it is very important to specify a filter when observing an event, otherwise your observer will be called for all objects of that type. INode::getEventKey() exists as a helper to provide a filter for C++, and Node.get_event_key() for Python.

Note

Since Node handles can be reused, and to remain compatible with legacy Event Stream behavior, all observers for a Node handle are removed when a Node is destroyed.

Create Attribute#

A dynamic attribute has been added to a node.

Parameters:

  • node (string) - The node path where the attribute was created

  • attribute (string) - The name of the created attribute

  • nodeHandle (int) - The unique handle representing the node. This is typically used as an event filter key.

Remove Attribute#

A dynamic attribute has been removed from a node.

Parameters:

  • node (string) - The node path where the attribute was removed

  • attribute (string) - The name of the removed attribute

  • nodeHandle (int) - The unique handle representing the node. This is typically used as an event filter key.

Attribute Type Resolve#

An extended-type attribute resolution has changed.

Parameters:

  • node (string) - The node path where the attribute type resolution changed

  • attribute (string) - The name of the attribute whose type resolution changed

  • nodeHandle (int) - The unique handle representing the node. This is typically used as an event filter key.

Graph Events#

Graph Events have a <category> of graph, producing an event composed as omni.graph.core:graph:<event name>.

Warning

OmniGraph Graph events have a global name, but typically listeners care about a specific Graph instance. Therefore it is very important to specify a filter when observing an event, otherwise your observer will be called for all objects of that type. IGraph::getEventKey() exists as a helper to provide a filter for C++, and Graph.get_event_key() for Python.

Note

Since Graph handles can be reused, and to remain compatible with legacy Event Stream behavior, all observers for a Graph handle are removed when a Graph is destroyed.

Create Variable#

A variable has been added to the graph.

Parameters:

  • variable (string) - The name of the created variable

  • graphHandle (int) - The unique handle representing the graph. This is typically used as an event filter key.

Remove Variable#

A variable has been removed from the graph.

Parameters:

  • variable (string) - The name of the removed variable

  • graphHandle (int) - The unique handle representing the graph. This is typically used as an event filter key.

Closing#

The stage is closing.

Parameters:

  • graphHandle (int) - The unique handle representing the graph. This is typically used as an event filter key.

Compute Requested#

A compute request has been made on a contained node.

Parameters:

  • nodeHandle (NodeHandle) - The handle of the node for which compute was requested

  • graphHandle (int) - The unique handle representing the graph. This is typically used as an event filter key.

Node Attribute Change#

An input or state attribute changed outside of graph evaluation.

Parameters:

  • attrHandle (AttributeHandle) - The handle of the attribute that changed

  • graphHandle (int) - The unique handle representing the graph. This is typically used as an event filter key.

Variable Type Change#

A variable in the graph had its type changed.

Parameters:

  • variable (string) - The variable name.

  • graphHandle (int) - The unique handle representing the graph. This is typically used as an event filter key.

Converting Legacy Events#

Previously, event streams could be retrieved from various objects but this is now deprecated in favor of using carb::eventdispatcher::IEventDispatcher. Select the tab below to see conversion examples for C++ or Python.

Main differences:

  • For Node and Graph objects, use of a filter parameter to observeEvent() is required to ensure that only events for the desired object are delivered to your observer.

  • Event Streams allowed generic subscriptions that would receive every event. This promoted time-wasting behavior where only one event was desired but the handler would still be called for every event. IEventDispatcher requires a separate observeEvent call for each event name.

  • Event Streams could have push-side subscribers, or pop-side subscribers. The new names for these are immediate and deferred, respectively (applies only to Graph Registry Events).

Old:

// carb::events::ISubscriptionPtr m_nodeSub;
m_nodeSub = carb::events::createSubscriptionToPop( // push => immediate; pop => deferred
    getCachedInterface<omni::graph::core::INode>()->getEventStream(node),
    [this](carb::events::IEvents* e) {
        if (e->type == static_cast<int>(omni::graph::core::INodeEvent::eCreateAttribute))
            handleCreateAttribute();
        else if (e->type == static_cast<int>(omni::graph::core::INodeEvent::eRemoveAttribute))
            handleRemoveAttribute();
        // Other events were still called, but ignored
    },
    carb::events::kDefaultOrder,
    "My subscription name"
);

New:

using FuncType = void (MyClass::*)(const carb::eventdispatcher::Event&);
static std::pair<carb::RString, FuncType> kEvents[] = {
    { omni::graph::core::kGlobalEventCreateAttribute, &MyClass::handleCreateAttribute },
    { omni::graph::core::kGlobalEventRemoveAttribute, &MyClass::handleRemoveAttribute },
};

// carb::eventdispatcher::ObserverGuard m_nodeSub[CARB_COUNTOF(kEvents)];
for (size_t i = 0; i != CARB_COUNTOF(kEvents); ++i)
{
    m_nodeSub[i] = carb::getCachedInterface<carb::eventdispatcher::IEventDispatcher>()->observeEvent(
        carb::RStringKey("My observer name"),
        carb::eventdispatcher::kDefaultOrder,
        kEvents[i].first,
        [this, func = kEvents[i].second](const auto& event) {
            (this->*func)(event);
        },
        iNode->getEventKey(node), // Important to have this filter
    );
}

Old:

import omni.graph.core as og
import carb.events

# ...

def _on_node_event(self, e: carb.events.IEvent):
    if e.type == int(og.INodeEvent.CREATE_ATTRIBUTE):
        self._handle_create_attribute()
    elif e.type == int(og.INodeEvent.REMOVE_ATTRIBUTE):
        self._handle_remove_attribute()
    # Other events were still called, but ignored

# ...

self._node_sub = self._node.get_event_stream().create_subscription_to_pop(
    self._on_node_event,
    0,
    "My subscriber name"
)

New:

import omni.graph.core as og
import carb.eventdispatcher

# ...

self._node_subs = [
    carb.eventdispatcher.get_eventdispatcher().observe_event(
        observer_name="My observer name",
        filter = self._node.get_event_key(), # important to have this filter
        event_name=name,
        on_event=func
    )
    for name, func in (
        (og.GLOBAL_EVENT_CREATE_ATTRIBUTE, self._handle_create_attribute),
        (og.GLOBAL_EVENT_REMOVE_ATTRIBUTE, self._handle_remove_attribute),
    )
]

Usage Examples#

Observing Node Attribute Changes#

import omni.graph.core as og
import carb.eventdispatcher

def on_attribute_created(event):
    node_path = event.get("node")
    attr_name = event.get("attribute")
    print(f"Attribute {attr_name} created on node {node_path}")

# Observe attribute creation events for a specific node
subscription = carb.eventdispatcher.get_eventdispatcher().observe_event(
    observer_name="Attribute Creation Observer",
    filter=node.get_event_key(),
    event_name=og.GLOBAL_EVENT_CREATE_ATTRIBUTE,
    on_event=on_attribute_created
)

Observing Graph Variable Changes#

import omni.graph.core as og
import carb.eventdispatcher

def on_variable_created(event):
    var_name = event.get("variable")
    print(f"Variable {var_name} created")

# Observe variable creation events for a specific graph
subscription = carb.eventdispatcher.get_eventdispatcher().observe_event(
    observer_name="Variable Creation Observer",
    filter=graph.get_event_key(),
    event_name=og.GLOBAL_EVENT_CREATE_VARIABLE,
    on_event=on_variable_created
)

Observing Registry Changes#

import omni.graph.core as og
import carb.eventdispatcher

def on_node_type_added(event):
    node_type = event.get("node_type")
    print(f"Node type {node_type} added to registry")

# Observe node type addition events (no filter needed for registry events)
subscription = carb.eventdispatcher.get_eventdispatcher().observe_event(
    observer_name="Node Type Observer",
    event_name=og.GLOBAL_EVENT_NODE_TYPE_ADDED,
    on_event=on_node_type_added
)