Timers / How to Start/Stop/Resume Properly?

Hello!

I’ve been trying to figure out how to use Timers properly in Bpy, but haven’t had any good luck.
I’ve seen/tried many examples, but in all cases, I usually end up with the Timer either not Stopping, or not being able to re-start…

Usually the ones I find are using Threading, which sounds like maybe isn’t the way to go?

Basically I’m trying to find a way, to Start/Stop something, where I can run a Def, every X milliseconds, until I Stop/Uncheck a UI Button. Then when Clicking it again/ it would Resume/Start the processes again…

I’ve looked into Modal operators as well, but I don’t want to block the UI. I want the user to be able to Model/Navigate like normal, but be doing processing in the BG, every so often, modifying the Geo they have selected/are working on. If they De-Selected/Changed the Selection, I’d break the Timer/Loop as well and want to Stop.

Any ideas?

Thank you!

No one really using timers/BG worker stuff?

I was able to use a Callback for one my scripts now, to update per Frame/Timeline Frame.
I have to turn on /play Animation, to get it working, but is something I guess.

https://docs.blender.org/api/2.79/bpy.app.handlers.html

bpy.app.handlers.frame_change_pre.append(Def_To_Run)
bpy.ops.screen.animation_play()

It seems like Blender doesn’t really support Threading/Async Timers as I’d want… Or maybe in some other way I’m not used to.

Modal is the way to go,
return {‘PASS_THROUGH’} in the modal method let events bubble further so it is not blocking.
The only side effect is autosave not working while any modal is running.

Interesting. I looked into Modal as well/wondered about that.
OK, I will have to test some things out!

Although, does that mess with hotkeys then/normal workflows?

The way I have my tool now, is maybe not ideal with the anim callback stuff.
However, it looks like normal Undo/normal actions work fine.

I am basically running a Raycast/VoxelGrid Check per “Tick”. For a custom ShrinkWrap/Tool I am making.

Why not just write your own timer? Here’s a simple example. check_clock() and reset_clock() are the relevant functions.