Using a decorator in an Operator class. Notice the repeating code is defined once in the decorator and any* function which you want to wrap that code around can be decorated with the @mouse_change
import bpy
import time
# declare the decorator
def mouse_change(func):
def add_mouse_change(*args):
bpy.context.window.cursor_set("WAIT")
func(*args)
bpy.context.window.cursor_set("DEFAULT")
return add_mouse_change
class SimpleCBOperator(bpy.types.Operator):
bl_idname = "node.some_callback_identifier"
bl_label = "Short Name"
fn_name = bpy.props.StringProperty(default='')
@mouse_change
def dispatch(self, context, type_op):
if type_op == 'some_named_function':
time.sleep( 5 )
print(type_op)
elif type_op == 'some_named_other_function':
time.sleep( 5 )
print(type_op)
def execute(self, context):
self.dispatch(context, self.fn_name)
return {'FINISHED'}
def register():
bpy.utils.register_class(SimpleCBOperator)
def unregister():
bpy.utils.unregister_class(SimpleCBOperator)
if __name__ == "__main__":
register()
# test call
bpy.ops.node.some_callback_identifier(fn_name='some_named_function')
*The way I wrote the decorator function won't let you decorate the execute
function.
you would have less code, and arguably more understandable code, by dropping the decorator entirely and going with a dispatch-callback pattern..
class SimpleCBOperator(bpy.types.Operator):
bl_idname = "node.some_callback_identifier"
bl_label = "Short Name"
fn_name = bpy.props.StringProperty(default='')
def dispatch(self, context, type_op):
cursor_set = bpy.context.window.cursor_set
cursor_set("WAIT")
if type_op == 'some_named_function':
pass
elif type_op == 'some_named_other_function':
pass
cursor_set("DEFAULT")
def execute(self, context):
self.dispatch(context, self.fn_name)
return {'FINISHED'}
The drawback of using a single operator 'callback' with an internal dispatch, is that the tooltip wouldn't be unique per fn_name
. These are at least a few options to look into.