Periodically running Python code

I want to periodically run a function in a way similar to what setInterval() does in JavaScript. I tried using a Timer but I was getting multithreading errors since the function tries to access a TouchDesigner object (it seems we can’t do that).

I finally got it working by using run() but it feels very clunky. I have defined this function (which calls itself every second):

def doStuff():
	myOp = args[0]
	# do stuff with myOp
	run("doStuff()", myOp, delayFrames = 60, fromOP = me)

To start the process, I must first call the function like this:

run("doStuff()", myOperator, delayFrames = 60, fromOP = me)

Is there a better way to do it? Is there anything similar to setInterval() that would work inside TouchDesigner ?

I would use a TimerCHOP that restarts on finish. Then modify the onDone callback inside the timer’s callback DAT.

run can be useful but is unpopular in some circles.

If you’re going to use it at all, try this style instead

movie = op('moviefilein1')
run("args[0].par.play = False", movie, delayFrames=60)

Alternatively you could have a dat titled my_script containing that text:
args[0].par.play = False

Then you could do:

movie = op('moviefilein1')
op('my_script').run(movie, delayFrames=60)
1 Like

Thanks a lot for your input David. Using your suggestions, I was able so simplify my code a little:

def doStuff(myOp):
	# here, I do stuff with myOp
	# then, I queue the function for next time
	run("doStuff(args[0])", myOp, delayFrames = 60, fromOP = me)

I can start the whole process with this, which is much simpler:

doStuff(myOP)

I tried doing it with the TimerCHOP but the problem is that, by using a different DAT, I lose access to variables that I need. I guess I could put those variables somewhere that is accessible to both operators but, again, this feels clunky.

Okay, I discovered how I can access members I created inside one operator from other operators:

op("webserver_callbacks").module.myMember

So, I guess I could use the TimerCHOP. I just feel weird having to use a separate operator to do something that I was expecting to be quite simple… I guess that’s why this post belongs in the beginner section…

I’m still open to other suggestions though!

I highly suggest that you checkout extensions. You can create complete logic on component level and call the logic. My way to do it nowerdays is to have all logic in extensions and only use callbacks to trigger behavior and pass the data. The rest is done on comp level.

3 Likes

I did not know about extensions. I will have to look it up. Thanks!