Using Dispatchers
As mentioned previously, in order to capture standalone notices during a transaction, it needs to be sent via the Broker. owever, notices are rarely sent directly within the transaction like in our examples. Most of the time, we want standalone notices to be triggered by other incoming notices.
This is therefore preferable to send standalone notices using a Dispatcher. A dispatcher is an object which triggers notices when incoming notices are received. It can be retrieved from the Broker via its identifier:
auto stage = PXR_NS::UsdStage::CreateInMemory();
auto broker = unf::Broker::Create(stage);
auto dispatcher = broker->GetDispatcher("...");
Listeners registered by any dispatcher can be revoked and re-registered as follows:
// Revoke all registered listeners.
dispatcher->Revoke();
// Re-register listeners.
dispatcher->Register();
Warning
Dispatchers cannot be manipulated in Python.
Stage Dispatcher
By default, the Broker only contains the StageDispatcher, which is in charge of emitting a default standalone notice for each USD notice received.
Its identifier is “StageDispatcher”:
auto stage = PXR_NS::UsdStage::CreateInMemory();
auto broker = unf::Broker::Create(stage);
auto dispatcher = broker->GetDispatcher("StageDispatcher");
Note
The Stage Dispatcher can be overriden by adding a new dispatcher with the same identifier.
Creating a Dispatcher
The Dispatcher interface can be used to create a new dispatcher. The “Register” method must be implemented to register the listeners in charge of emitting the new notices.
A convenient “_Register” protected method is provided to trigger a new notice from one specific notice type. The new notice will be created by passing the notice received to its constructor:
class NewDispatcher : public unf::Dispatcher {
public:
NewDispatcher(const unf::BrokerWeakPtr& broker)
: unf::Dispatcher(broker) {}
std::string GetIdentifier() const override { return "NewDispatcher"; };
void Register() {
// Register listener to create and emit 'OutputNotice' when
// 'InputNotice' is received.
_Register<InputNotice, OutputNotice>();
}
};
Otherwise, the listener can be registered as follows:
class NewDispatcher : public unf::Dispatcher {
public:
NewDispatcher(const unf::BrokerWeakPtr& broker)
: unf::Dispatcher(broker) {}
std::string GetIdentifier() const override { return "NewDispatcher"; };
void Register() {
auto self = PXR_NS::TfCreateWeakPtr(this);
auto cb = &NewDispatcher::_OnReceiving;
_keys.push_back(
PXR_NS::TfNotice::Register(self, cb, _broker->GetStage()));
}
void _OnReceiving(const InputNotice& notice)
{
_broker->Send<OutputNotice>(/* arguments to create notice */);
}
};
The new dispatcher can be added to the Broker as follows:
auto stage = PXR_NS::UsdStage::CreateInMemory();
auto broker = unf::Broker::Create(stage);
broker->AddDispatcher<NewDispatcher>();
Creating a plugin
The new dispatcher can be automatically discovered and registered when the Broker is created using the Plug framework.
First, a corresponding runtime TfType must be defined:
TF_REGISTRY_FUNCTION(TfType)
{
unf::DispatcherDefine<NewDispatcher, unf::Dispatcher>();
}
Then a plugInfo.json
configuration must be created. It should be in
the form of:
{
"Plugins": [
{
"Info": {
"Types" : {
"NewDispatcher" : {
"bases": [ "Dispatcher" ]
}
}
},
"LibraryPath": "libNewDispatcher.so",
"Name": "NewDispatcher",
"Type": "library"
}
]
}
The path to this configuration file must be included in the
PXR_PLUGINPATH_NAME
environment variable.