playSoundClip Repeatedly

Ya, that took care of it. Both

not initialChange

and

previousValue.value is not None

worked and produced the same result. I didn't think to put the initial change back in there, since I had to remove it previously to get it to start working.

Thanks

1 Like

So, I went with the recursion solution here, but I've seen that there is a Java max recursion depth. Assuming that the alarms are never acknowledged and the count remains non-0 "forever" - what would be the best way to handle that?

I've added a try, except to my recursive call, but what happens at the point that the last call hits that max recursion error? I'd imagine that it just stops.

if EN and area == 0:
		if count > 0:
			fileNames = options.getColumnAsList(1)
			if selection and selection in fileNames:
				wavFile = path + '\\' + selection + '.wav'
				system.util.playSoundClip(wavFile, volume/100.0, True)
				
				try:
					playAlarmSoundLoop()
				except:
					system.gui.errorBox(count+' Unacked Alarms. Please Ack', 'Unacked Alarms Error')
					return
				
			else:
				return
		else:
			return
	else:
		return

Simple solution for now, is just throw an error box.

Whenever in doubt, I think review any post that PTurmel has given you.

It is efficient, eliminates waits.

I believe you need to be calling the playAlarmSoundLoop function asynchronously instead of synchronously/directly like you're doing. I would think that would escape this recursion, but I personally don't know that for certain.

system.util.invokeAsynchronous(playAlarmSoundLoop)

The first call is async. Does each successive call need to be async as well?

Each async call will reset the stack depth. Recursive calls on the same thread = the same stack.

Yes, as that should essentially put that call on a separate thread and the current thread would close out.

How does the current thread close out if the recursive call never returns? Is the thread able to detect the recursion and close?

I would negate the if statements to reduce nesting depth:

if not EN or area != 0:
	return
elif count <= 0:
	return
fileNames = options.getColumnAsList(1)
if selection and selection in fileNames:
	wavFile [...]
2 Likes

When you call something asynchronously, the current thread/script doesn't wait for a return. If you needed it to return something you'd have to pass a return function that would be called separately once the called function returns, but in this case, you just need to fire and forget, so it fires off the call and exits/returns.

I understand that the thread doesn't wait for the return. I guess I don't understand threading. Wouldn't you end up with thousands of threads that are waiting to close? How does the thread know when to close?

The thread dies when whatever function it was executing stops (when execution reaches the end).

Why choose asynchronous and recursion over triggers?

You could reduce the overhead, eliminate race conditions, and never risk overflow by triggering the next at the end.

and where would that "end" be?

When the code runs out? You're passing a defined function to system.util.invokeAsynchronous. When it's run out of instructions to run, it'll stop. As long as you're not doing something like while(True): inside your script, it'll die as normal.

ok, so the invokeAsync call will start the new call but the thread that called it will just continue on in the code, not waiting for the return to continue execution - so it'll hit the end of the script in this case.

Yes. That's the whole point of the "asynchronous" part - it doesn't block the flow of execution through the calling script.

1 Like