Ensure order of operations when your script does something with nodes

Hey! This is one feature in TD that I really miss. Normally with every programming language you can be sure that next line of code won’t execute until the previous one is done. Unless it’s of course some kind of async operation. So I really miss this confidence when dealing with python in touch.

Consider a simple example: I have a list of 3 ip address and I need to send a message to all of them. With vanilla python I can do just a simple for loop changing the ip argument of socket.sendto method.

Now with td it’s not as straightforward. It will look something like this:

  1. Change ip on the udpoutdat
  2. Wait 1 frame for your changes to apply (wait for cook)
  3. Send your message
  4. Wait 1 frame before changing to new ip (not sure if needed)
  5. Repeat for the rest of the list…
    Which means creating a lot of awkward run scripts and managing the delay time for all of them. This is very confusing.

Even simpler example would be to do a while loop involving any td operator. Python will wait until op cooks which it never would because it would be forever waiting for python code to fully execute.

My suggestion would be to somehow have a way to ensure the order of operation when going back and forth between python and td.

Maybe it can be something like having a special method on an op that either stalls python until it cooks or maybe something similar to web when the function returns a promise which gets resolved when it’s done.

1 Like

Either use 3 UDP-OutDATs or use the op(“udpout”).cook(force = True) command to ensure cooking.

Thanks for your reply! I don’t think using three nodes is practical because next time I can have a list of 100 ip’s
As for force cooking, I believe it will still happen after all python code is done executing

Someone can correct me if I’m wrong…

EDIT: I was wrong ¯_(ツ)_/¯

Nodes can certainly cook within a Python script execution. Any time you ask for data from a node during a Python script, if that node hasn’t cooked yet, then it’ll cook and then return the value to the currently executing script.
Similarly, if you do cook(force=True), it’ll cook right then, before the next line of Python code executes. So the suggestion from @alphamoonbase should do the trick for your case, although it may be quite expensive since you are destroing/creating sockets constantly.

Ok, I stand corrected. Thx for your input @alphamoonbase @malcolm

It’s one of those things that when you read it you like “no way, I remember it was never working like that” and now I tried again and it is really working :slight_smile:

Sorry to revive this topic, but I am also surprised to learn that this is the case, as through experience I’ve learned to not rely on it being true:

For example, could you clarify it in the following example:
image
Here, I have my scripts print to textport: (f is timeline frame, t is absolute time)

First, the script force cooks an Engine Comp, as indicated by the first line seen here.
The “Pilot frame n done” print line follows the line that force cooks in the same script, however in here the “engine” precook and postcook print lines appear after that entire script has finished executing (triggered by op execute dat).

Is it still actually cooking within the script, and maybe only the order of print lines by the Op Execute DAT are misleading?
So far in this project of mine and this particular case it appears the python script doesn’t “wait” for the engine to actually cook and executes asynchronously.