diff options
Diffstat (limited to 'source/blender/python/intern/bpy_operator_wrap.c')
-rw-r--r-- | source/blender/python/intern/bpy_operator_wrap.c | 106 |
1 files changed, 30 insertions, 76 deletions
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 769a8336d4a..779a27639a4 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -41,13 +41,12 @@ #include "../generic/bpy_internal_import.h" // our own imports -#define PYOP_ATTR_PROP "__props__" -#define PYOP_ATTR_UINAME "__label__" -#define PYOP_ATTR_IDNAME "__idname__" /* the name given by python */ -#define PYOP_ATTR_IDNAME_BL "__idname_bl__" /* our own name converted into blender syntax, users wont see this */ +#define PYOP_ATTR_UINAME "bl_label" +#define PYOP_ATTR_IDNAME "bl_idname" /* the name given by python */ +#define PYOP_ATTR_IDNAME_BL "_bl_idname" /* our own name converted into blender syntax, users wont see this */ #define PYOP_ATTR_DESCRIPTION "__doc__" /* use pythons docstring */ -#define PYOP_ATTR_REGISTER "__register__" /* True/False. if this python operator should be registered */ -#define PYOP_ATTR_UNDO "__undo__" /* True/False. if this python operator should be undone */ +#define PYOP_ATTR_REGISTER "bl_register" /* True/False. if this python operator should be registered */ +#define PYOP_ATTR_UNDO "bl_undo" /* True/False. if this python operator should be undone */ static struct BPY_flag_def pyop_ret_flags[] = { {"RUNNING_MODAL", OPERATOR_RUNNING_MODAL}, @@ -91,19 +90,23 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperat PointerRNA ptr_context; PointerRNA ptr_operator; PointerRNA ptr_event; - PyObject *py_operator; PyGILState_STATE gilstate; bpy_context_set(C, &gilstate); args = PyTuple_New(1); - PyTuple_SET_ITEM(args, 0, PyObject_GetAttrString(py_class, "__rna__")); // need to use an rna instance as the first arg + + /* poll has no 'op', should be ok still */ + /* use an rna instance as the first arg */ + RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator); + PyTuple_SET_ITEM(args, 0, pyrna_struct_CreatePyObject(&ptr_operator)); + py_class_instance = PyObject_Call(py_class, args, NULL); Py_DECREF(args); if (py_class_instance) { /* Initializing the class worked, now run its invoke function */ - + PyObject *class_dict= PyObject_GetAttrString(py_class_instance, "__dict__"); /* Assign instance attributes from operator properties */ if(op) { @@ -115,20 +118,12 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperat if (strcmp(arg_name, "rna_type")==0) continue; item = pyrna_prop_to_py(op->ptr, prop); - PyObject_SetAttrString(py_class_instance, arg_name, item); + PyDict_SetItemString(class_dict, arg_name, item); Py_DECREF(item); } RNA_STRUCT_END; } - /* set operator pointer RNA as instance "__operator__" attribute */ - if(op) { - RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator); - py_operator= pyrna_struct_CreatePyObject(&ptr_operator); - PyObject_SetAttrString(py_class_instance, "__operator__", py_operator); - Py_DECREF(py_operator); - } - RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context); if (mode==PYOP_INVOKE) { @@ -159,6 +154,11 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperat Py_DECREF(args); Py_DECREF(item); + Py_DECREF(class_dict); + } + else { + PyErr_Print(); + PyErr_Clear(); } if (ret == NULL) { /* covers py_class_instance failing too */ @@ -178,8 +178,10 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperat } else if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) { /* the returned value could not be converted into a flag */ - if(op) + if(op) { + fprintf(stderr, "error using return value from \"%s\"\n", op->idname); // for some reason the error raised doesnt include file:line... this helps BPy_errors_to_report(op->reports); + } ret_flag = OPERATOR_CANCELLED; } @@ -246,7 +248,7 @@ static int PYTHON_OT_poll(bContext *C, wmOperatorType *ot) void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata) { PyObject *py_class = (PyObject *)userdata; - PyObject *props, *item; + PyObject *item; /* identifiers */ item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME_BL); @@ -300,46 +302,18 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata) PyErr_Clear(); } - - - props= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP); - - if (props) { - PyObject *dummy_args = PyTuple_New(0); - int i; - - for(i=0; i<PyList_Size(props); i++) { - PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret; - item = PyList_GET_ITEM(props, i); - - if (PyArg_ParseTuple(item, "O!O!:PYTHON_OT_wrapper", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) { - - PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *); - pyfunc = PyCObject_AsVoidPtr(py_func_ptr); - py_srna_cobject = PyCObject_FromVoidPtr(ot->srna, NULL); - - py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw); - if (py_ret) { - Py_DECREF(py_ret); - } else { - fprintf(stderr, "BPy Operator \"%s\" registration error: %s item %d could not run\n", ot->idname, PYOP_ATTR_PROP, i); - PyLineSpit(); + /* Can't use this because it returns a dict proxy + * + * item= PyObject_GetAttrString(py_class, "__dict__"); + */ + item= ((PyTypeObject*)py_class)->tp_dict; + if(item) { + if(pyrna_deferred_register_props(ot->srna, item)!=0) { PyErr_Print(); PyErr_Clear(); } - Py_DECREF(py_srna_cobject); - - } else { - /* cant return NULL from here */ // XXX a bit ugly - PyErr_Print(); - PyErr_Clear(); } - - // expect a tuple with a CObject and a dict - } - Py_DECREF(dummy_args); - Py_DECREF(props); - } else { + else { PyErr_Clear(); } } @@ -354,12 +328,10 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class) char *idname= NULL; char idname_bl[OP_MAX_TYPENAME]; /* converted to blender syntax */ - int i; static struct BPY_class_attr_check pyop_class_attr_values[]= { {PYOP_ATTR_IDNAME, 's', -1, OP_MAX_TYPENAME-3, 0}, /* -3 because a.b -> A_OT_b */ {PYOP_ATTR_UINAME, 's', -1,-1, BPY_CLASS_ATTR_OPTIONAL}, - {PYOP_ATTR_PROP, 'l', -1,-1, BPY_CLASS_ATTR_OPTIONAL}, {PYOP_ATTR_DESCRIPTION, 's', -1,-1, BPY_CLASS_ATTR_NONE_OK}, {"execute", 'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL}, {"invoke", 'f', 3, -1, BPY_CLASS_ATTR_OPTIONAL}, @@ -400,24 +372,6 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class) WM_operatortype_remove(idname); } - /* If we have properties set, check its a list of dicts */ - item= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP); - if (item) { - for(i=0; i<PyList_Size(item); i++) { - PyObject *py_args = PyList_GET_ITEM(item, i); - PyObject *py_func_ptr, *py_kw; /* place holders */ - - if (!PyArg_ParseTuple(py_args, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) { - PyErr_Format(PyExc_ValueError, "Cant register operator class - %s.properties must contain values from FloatProperty", idname); - return NULL; - } - } - Py_DECREF(item); - } - else { - PyErr_Clear(); - } - Py_INCREF(py_class); WM_operatortype_append_ptr(PYTHON_OT_wrapper, py_class); |