In some of my add-ons I use a modal timer to read an input device or a socket. Fine, but is there a way to know if a modal timer is still “running” ? In some rare cases I noticed that the modal timer was interrupted and would need to check that with some code.
May be by accessing the return string (‘PASS_THROUGH’ , ‘RUNNING_MODAL’ or ‘CANCELLED’) of the various functions of the modal timer class ? But I don’t know how to do this.
had a play around with this a while back. Basically you can use the same sort of method as the modal timer template which changes the 3d view bg colour… visually pretty obvious when it has stopped.
I also found you could do this… in this case I’ve tacked the timer onto the operator class and added a class method to return it. You can also set up your own class and make the timer an attribute of the class or an instance.
I’ve used the driver_namespace as it’s a simple way to get output to the console.
import bpy
class ModalTimerOperator(bpy.types.Operator):
"""Operator which runs its self from a timer"""
bl_idname = "wm.modal_timer_operator"
bl_label = "Modal Timer Operator"
_timer = None
@classmethod
def running(cls, context):
return (cls._timer)
def modal(self, context, event):
if event.type in {'RIGHTMOUSE', 'ESC'}:
self.cancel(context)
return {'CANCELLED'}
if event.type == 'TIMER':
# change theme color, silly!
color = context.user_preferences.themes[0].view_3d.space.gradients.high_gradient
color.s = 1.0
color.h += 0.01
return {'PASS_THROUGH'}
def execute(self, context):
print(type(self))
wm = context.window_manager
type(self)._timer = wm.event_timer_add(0.1, context.window)
wm.modal_handler_add(self)
return {'RUNNING_MODAL'}
def cancel(self, context):
wm = context.window_manager
wm.event_timer_remove(type(self)._timer)
def register():
bpy.app.driver_namespace['mto'] = ModalTimerOperator
bpy.utils.register_class(ModalTimerOperator)
def unregister():
bpy.utils.unregister_class(ModalTimerOperator)
if __name__ == "__main__":
register()
# test call
bpy.ops.wm.modal_timer_operator()
Console output. t.time_duration resets to 0 when the modal operator is stopped.
>>> c = bpy.app.driver_namespace['mto']
>>> t = c.running(C)
>>> t.time_duration
229.5037384033203
>>> t.time_duration
231.70159912109375
>>> t.time_duration
233.20436096191406
>>> t.time_duration
0.0