I’m working on a stateful node where adding or removing connections to it makes it crash. This seems to be an issue which requires an implementation of the InstanceTrigger functions. I’ve added them, but don’t really know how to make use of them. I think I understand to a degree *why * they are there, but is it possible to get a more eli5 explanation of what exactly it is they do, and how I for instance can use them to block inputs changing while “IsTriggerStopped = false”?


Maybe a little background on how the composition starts and stops will help…

When a composition starts, first nodeInstanceInit() is called for each stateful node. Then, nodeInstanceTriggerStart() is called for each stateful node that implements it.

Both of these functions are involved in initializing / setting up the node. nodeInstanceInit() is responsible for creating the node’s instance data. nodeInstanceTriggerStart() is responsible for starting any background threads that can potentially fire a trigger.

The reason that the initialization is split into two phases — why you can’t just do it all in nodeInstanceInit — is that all nodes need to have their instance data ready before any nodes start firing triggers. Otherwise a trigger might fire an event into a node that hasn’t been set up yet.

When the composition stops, the two phases happen in reverse. First, nodeInstanceTriggerStop() is called for each stateful node that has it, and the composition waits for all the triggers to stop and all events in progress to trickle through the composition. Then, nodeInstanceFini() is called for each stateful node.

Now, nodeInstanceTriggerUpdate()… This is called when you edit an input port value on a node while the composition is running. For example, if you have a Fire Periodically node and you double-click on Seconds and change it from 1 to 2, that prompts a call to the Fire Periodically node’s nodeInstanceTriggerUpdate().

Actually, walking through all the steps with Fire Periodically might be instructive…

So you have a composition with a Fire Periodically node in it, with Seconds set to 1. When you start the composition, first the nodeInstanceInit() function is called and then the nodeInstanceTriggerStart() function is called. nodeInstanceTriggerStart() starts a timer that runs in the background. Every 1 second, the timer goes off and the Fired trigger port fires an event.

When you double-click on the Seconds port and change it from 1 to 2, the nodeInstanceTriggerUpdate() function is called. This function cancels the 1-second timer and starts a 2-second timer. So now the Fired trigger fires every 2 seconds.

When you stop the composition, nodeInstanceTriggerStop() is called. It cancels the 2-second timer (and waits for it to really stop). Finally, nodeInstanceFini() is called.

Does that make sense? Looking back at the source code of nodes that use the isTriggerStopped variable/pattern, do you now understand it?

Great, thanks! Yes, this seems to explain quite a few things! :) Now it’s just a matter of getting to grips with the implementation, but I’ll give it a go looking at the “Fire Periodically” node to see if I can wrangle it in the right direction!