Skip to main content
added 182 characters in body
Source Link
zeffii
  • 39.9k
  • 9
  • 106
  • 189

Using a decorator in an Operator class. Notice the repeating code is defined once in the decorator and anyany* function which you want to wrap that code around can be decorated with the @mouse_change

The*The way I wrote the decorator function won't let you decorate the execute function. So 

you would have less code, and arguably more understandable code, by dropping the decorator entirely and going with a dispatch-callback pattern..

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.

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

The way I wrote the decorator function won't let you decorate the execute function. So you would have less code, and arguably more understandable code, by dropping the decorator entirely and going with a dispatch-callback pattern..

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

*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..

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.

added 917 characters in body
Source Link
zeffii
  • 39.9k
  • 9
  • 106
  • 189

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. So 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'}

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')

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. So 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'}
Source Link
zeffii
  • 39.9k
  • 9
  • 106
  • 189

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')