diff options
author | Martin Poirier <theeth@yahoo.com> | 2009-12-31 01:14:32 +0300 |
---|---|---|
committer | Martin Poirier <theeth@yahoo.com> | 2009-12-31 01:14:32 +0300 |
commit | b00cddeb66f2b9f51cad15ed597a6ca975bd31dd (patch) | |
tree | bd686691ecde5cd24abd2330dea086e275d07635 | |
parent | 3702998fec6d237eb567bb8353ac93c8d4a68d4c (diff) |
Macro registration using the normal rna registration methods (like operators).
bpy.types.register(MacroClass)
instead of
bpy.ops.add_macro(MacroClass)
The rest is unchanged.
Also remove some now unused code for the old registration methods (there's still some remaining).
-rw-r--r-- | release/scripts/modules/bpy/ops.py | 7 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_internal.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_wm.c | 96 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_wm_api.c | 29 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_operator.c | 4 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_operator_wrap.c | 61 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 6 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.h | 3 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 1 |
10 files changed, 179 insertions, 30 deletions
diff --git a/release/scripts/modules/bpy/ops.py b/release/scripts/modules/bpy/ops.py index 268189b2db4..ba5eeff7a0e 100644 --- a/release/scripts/modules/bpy/ops.py +++ b/release/scripts/modules/bpy/ops.py @@ -23,7 +23,6 @@ from _bpy import ops as ops_module # op_add = ops_module.add op_remove = ops_module.remove -op_add_macro = ops_module.add_macro op_dir = ops_module.dir op_call = ops_module.call op_as_string = ops_module.as_string @@ -57,12 +56,6 @@ class bpy_ops(object): raise AttributeError(module) return bpy_ops_submodule(module) - def add(self, pyop): - op_add(pyop) - - def add_macro(self, pyop): - op_add_macro(pyop) - def remove(self, pyop): op_remove(pyop) diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 2528af6b57a..908d832daf1 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -319,6 +319,7 @@ extern StructRNA RNA_Object; extern StructRNA RNA_ObjectBase; extern StructRNA RNA_ObstacleFluidSettings; extern StructRNA RNA_Operator; +extern StructRNA RNA_Macro; extern StructRNA RNA_OperatorFileListElement; extern StructRNA RNA_OperatorMousePath; extern StructRNA RNA_OperatorProperties; diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 5bb3c82395d..22b8388f693 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -211,6 +211,7 @@ void RNA_api_armature_edit_bone(StructRNA *srna); void RNA_api_drivers(StructRNA *srna); void RNA_api_image(struct StructRNA *srna); void RNA_api_operator(struct StructRNA *srna); +void RNA_api_macro(struct StructRNA *srna); void RNA_api_keyconfig(struct StructRNA *srna); void RNA_api_keyingset(struct StructRNA *srna); void RNA_api_keymap(struct StructRNA *srna); diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 7abba3c004a..e68681919eb 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -692,6 +692,7 @@ static void operator_draw(bContext *C, wmOperator *op) } void operator_wrapper(wmOperatorType *ot, void *userdata); +void macro_wrapper(wmOperatorType *ot, void *userdata); static char _operator_idname[OP_MAX_TYPENAME]; static char _operator_name[OP_MAX_TYPENAME]; @@ -763,12 +764,84 @@ static StructRNA *rna_Operator_register(const bContext *C, ReportList *reports, return dummyot.ext.srna; } + +static StructRNA *rna_MacroOperator_register(const bContext *C, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) +{ + wmOperatorType dummyot = {0}; + wmOperator dummyop= {0}; + PointerRNA dummyotr; + int have_function[4]; + + /* setup dummy operator & operator type to store static properties in */ + dummyop.type= &dummyot; + dummyot.idname= _operator_idname; /* only assigne the pointer, string is NULL'd */ + dummyot.name= _operator_name; /* only assigne the pointer, string is NULL'd */ + dummyot.description= _operator_descr; /* only assigne the pointer, string is NULL'd */ + RNA_pointer_create(NULL, &RNA_Macro, &dummyop, &dummyotr); + + /* validate the python class */ + if(validate(&dummyotr, data, have_function) != 0) + return NULL; + + { /* convert foo.bar to FOO_OT_bar + * allocate the description and the idname in 1 go */ + int idlen = strlen(_operator_idname) + 4; + int namelen = strlen(_operator_name) + 1; + int desclen = strlen(_operator_descr) + 1; + char *ch, *ch_arr; + ch_arr= ch= MEM_callocN(sizeof(char) * (idlen + namelen + desclen), "_operator_idname"); /* 2 terminators and 3 to convert a.b -> A_OT_b */ + WM_operator_bl_idname(ch, _operator_idname); /* convert the idname from python */ + dummyot.idname= ch; + ch += idlen; + strcpy(ch, _operator_name); + dummyot.name = ch; + ch += namelen; + strcpy(ch, _operator_descr); + dummyot.description = ch; + } + + if(strlen(identifier) >= sizeof(dummyop.idname)) { + BKE_reportf(reports, RPT_ERROR, "registering operator class: '%s' is too long, maximum length is %d.", identifier, sizeof(dummyop.idname)); + return NULL; + } + + /* check if we have registered this operator type before, and remove it */ + { + wmOperatorType *ot= WM_operatortype_exists(dummyot.idname); + if(ot && ot->ext.srna) + rna_Operator_unregister(C, ot->ext.srna); + } + + /* create a new menu type */ + dummyot.ext.srna= RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator"); + dummyot.ext.data= data; + dummyot.ext.call= call; + dummyot.ext.free= free; + + dummyot.pyop_poll= (have_function[0])? operator_poll: NULL; + dummyot.ui= (have_function[3])? operator_draw: NULL; + + WM_operatortype_append_macro_ptr(macro_wrapper, (void *)&dummyot); + + /* update while blender is running */ + if(C) + WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL); + + return dummyot.ext.srna; +} + static StructRNA* rna_Operator_refine(PointerRNA *opr) { wmOperator *op= (wmOperator*)opr->data; return (op->type && op->type->ext.srna)? op->type->ext.srna: &RNA_Operator; } +static StructRNA* rna_MacroOperator_refine(PointerRNA *opr) +{ + wmOperator *op= (wmOperator*)opr->data; + return (op->type && op->type->ext.srna)? op->type->ext.srna: &RNA_Macro; +} + #else static void rna_def_operator(BlenderRNA *brna) @@ -832,6 +905,8 @@ static void rna_def_macro_operator(BlenderRNA *brna) srna= RNA_def_struct(brna, "Macro", NULL); RNA_def_struct_ui_text(srna, "Macro Operator", "Storage of a macro operator being executed, or registered after execution."); RNA_def_struct_sdna(srna, "wmOperator"); + RNA_def_struct_refine_func(srna, "rna_MacroOperator_refine"); + RNA_def_struct_register_funcs(srna, "rna_MacroOperator_register", "rna_Operator_unregister"); prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); @@ -844,6 +919,27 @@ static void rna_def_macro_operator(BlenderRNA *brna) RNA_def_property_struct_type(prop, "OperatorProperties"); RNA_def_property_ui_text(prop, "Properties", ""); RNA_def_property_pointer_funcs(prop, "rna_Operator_properties_get", NULL, NULL); + + /* Registration */ + prop= RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "type->idname"); + RNA_def_property_string_maxlength(prop, OP_MAX_TYPENAME); /* else it uses the pointer size! */ + RNA_def_property_flag(prop, PROP_REGISTER); + + prop= RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "type->name"); + RNA_def_property_string_maxlength(prop, 1024); /* else it uses the pointer size! */ + RNA_def_property_flag(prop, PROP_REGISTER); + + prop= RNA_def_property(srna, "bl_register", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "type->flag", OPTYPE_REGISTER); + RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); + + prop= RNA_def_property(srna, "bl_undo", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "type->flag", OPTYPE_UNDO); + RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); + + RNA_api_macro(srna); } static void rna_def_operator_type_macro(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c index 1afedf1c6a6..9ed6046ecd0 100644 --- a/source/blender/makesrna/intern/rna_wm_api.c +++ b/source/blender/makesrna/intern/rna_wm_api.c @@ -237,6 +237,35 @@ void RNA_api_operator(StructRNA *srna) RNA_def_pointer(func, "context", "Context", "", ""); } +void RNA_api_macro(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + + /* utility, not for registering */ + func= RNA_def_function(srna, "report", "rna_Operator_report"); + parm= RNA_def_enum(func, "type", wm_report_items, 0, "Type", ""); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_ENUM_FLAG); + parm= RNA_def_string(func, "message", "", 0, "Report Message", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + + + /* Registration */ + + /* poll */ + func= RNA_def_function(srna, "poll", NULL); + RNA_def_function_ui_description(func, "Test if the operator can be called or not."); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); + RNA_def_function_return(func, RNA_def_boolean(func, "visible", 1, "", "")); + RNA_def_pointer(func, "context", "Context", "", ""); + + /* draw */ + func= RNA_def_function(srna, "draw", NULL); + RNA_def_function_ui_description(func, "Draw function for the operator."); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); + RNA_def_pointer(func, "context", "Context", "", ""); +} + void RNA_api_keyconfig(StructRNA *srna) { FunctionRNA *func; diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 101f3619da4..e7cce8e7812 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -245,7 +245,7 @@ PyObject *BPY_operator_module( void ) static PyMethodDef pyop_dir_meth = {"dir", (PyCFunction) pyop_dir, METH_NOARGS, NULL}; static PyMethodDef pyop_getrna_meth = {"get_rna", (PyCFunction) pyop_getrna, METH_O, NULL}; // static PyMethodDef pyop_add_meth = {"add", (PyCFunction) PYOP_wrap_add, METH_O, NULL}; - static PyMethodDef pyop_add_macro_meth ={"add_macro", (PyCFunction) PYOP_wrap_add_macro, METH_O, NULL}; +// static PyMethodDef pyop_add_macro_meth ={"add_macro", (PyCFunction) PYOP_wrap_add_macro, METH_O, NULL}; static PyMethodDef pyop_macro_def_meth ={"macro_define", (PyCFunction) PYOP_wrap_macro_define, METH_VARARGS, NULL}; static PyMethodDef pyop_remove_meth = {"remove", (PyCFunction) PYOP_wrap_remove, METH_O, NULL}; @@ -257,7 +257,7 @@ PyObject *BPY_operator_module( void ) PyModule_AddObject( submodule, "dir", PyCFunction_New(&pyop_dir_meth, NULL) ); PyModule_AddObject( submodule, "get_rna", PyCFunction_New(&pyop_getrna_meth, NULL) ); // PyModule_AddObject( submodule, "add", PyCFunction_New(&pyop_add_meth, NULL) ); - PyModule_AddObject( submodule, "add_macro", PyCFunction_New(&pyop_add_macro_meth, NULL) ); +// PyModule_AddObject( submodule, "add_macro", PyCFunction_New(&pyop_add_macro_meth, NULL) ); PyModule_AddObject( submodule, "macro_define",PyCFunction_New(&pyop_macro_def_meth, NULL) ); PyModule_AddObject( submodule, "remove", PyCFunction_New(&pyop_remove_meth, NULL) ); diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index b3f281b4b3f..0a468f2de73 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -299,7 +299,47 @@ void operator_wrapper(wmOperatorType *ot, void *userdata) } } +void macro_wrapper(wmOperatorType *ot, void *userdata) +{ + wmOperatorType *data = (wmOperatorType *)userdata; + /* only copy a couple of things, the rest is set by the macro registration */ + ot->name = data->name; + ot->idname = data->idname; + ot->description = data->description; + ot->flag |= data->flag; /* append flags to the one set by registration */ + ot->pyop_poll = data->pyop_poll; + ot->ui = data->ui; + ot->ext = data->ext; + + RNA_struct_blender_type_set(ot->ext.srna, ot); + + + /* Can't use this because it returns a dict proxy + * + * item= PyObject_GetAttrString(py_class, "__dict__"); + */ + { + PyObject *py_class = ot->ext.data; + PyObject *item= ((PyTypeObject*)py_class)->tp_dict; + if(item) { + /* only call this so pyrna_deferred_register_props gives a useful error + * WM_operatortype_append_ptr will call RNA_def_struct_identifier + * later */ + RNA_def_struct_identifier(ot->srna, ot->idname); + + if(pyrna_deferred_register_props(ot->srna, item)!=0) { + /* failed to register operator props */ + PyErr_Print(); + PyErr_Clear(); + + } + } + else { + PyErr_Clear(); + } + } +} @@ -588,11 +628,11 @@ PyObject *PYOP_wrap_macro_define(PyObject *self, PyObject *args) wmOperatorType *ot; wmOperatorTypeMacro *otmacro; PyObject *macro; - PyObject *item; PointerRNA ptr_otmacro; + StructRNA *srna; char *opname; - char *macroname; + const char *macroname; if (!PyArg_ParseTuple(args, "Os:_bpy.ops.macro_define", ¯o, &opname)) return NULL; @@ -603,21 +643,8 @@ PyObject *PYOP_wrap_macro_define(PyObject *self, PyObject *args) } /* identifiers */ - item= PyObject_GetAttrString(macro, PYOP_ATTR_IDNAME_BL); - - if (!item) { - item= PyObject_GetAttrString(macro, PYOP_ATTR_IDNAME); - - if (!item) { - PyErr_Format(PyExc_ValueError, "Macro Define: not a valid Macro class"); - } else { - macroname= _PyUnicode_AsString(item); - PyErr_Format(PyExc_ValueError, "Macro Define: '%s' hasn't been registered yet", macroname); - } - return NULL; - } - - macroname= _PyUnicode_AsString(item); + srna= srna_from_self(macro); + macroname = RNA_struct_identifier(srna); ot = WM_operatortype_exists(macroname); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 7c4e49e93e3..c8f0a29ca64 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -244,8 +244,6 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) #endif -static StructRNA *pyrna_struct_as_srna(PyObject *self); - static int pyrna_struct_compare( BPy_StructRNA * a, BPy_StructRNA * b ) { return (a->ptr.data==b->ptr.data) ? 0 : -1; @@ -3354,7 +3352,7 @@ PyObject *BPY_rna_props( void ) return submodule; } -static StructRNA *pyrna_struct_as_srna(PyObject *self) +StructRNA *pyrna_struct_as_srna(PyObject *self) { BPy_StructRNA *py_srna = NULL; StructRNA *srna; @@ -3395,7 +3393,7 @@ static StructRNA *pyrna_struct_as_srna(PyObject *self) /* Orphan functions, not sure where they should go */ /* get the srna for methods attached to types */ /* */ -static StructRNA *srna_from_self(PyObject *self) +StructRNA *srna_from_self(PyObject *self) { /* a bit sloppy but would cause a very confusing bug if * an error happened to be set here */ diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index 37f6af36726..74a16b43dc1 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -62,6 +62,9 @@ typedef struct { /* cheap trick */ #define BPy_BaseTypeRNA BPy_PropertyRNA +StructRNA *srna_from_self(PyObject *self); +StructRNA *pyrna_struct_as_srna(PyObject *self); + void BPY_rna_init( void ); PyObject *BPY_rna_module( void ); void BPY_update_rna_module( void ); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index f7054af9443..e9bf1be5861 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -360,6 +360,7 @@ void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType*, void*), vo ot= MEM_callocN(sizeof(wmOperatorType), "operatortype"); ot->srna= RNA_def_struct(&BLENDER_RNA, "", "OperatorProperties"); + ot->flag= OPTYPE_MACRO; ot->exec= wm_macro_exec; ot->invoke= wm_macro_invoke; ot->modal= wm_macro_modal; |