#include "bpy_compat.h"
#include "bpy_util.h"
+#include "../generic/bpy_internal_import.h" // our own imports
+
#define PYOP_ATTR_PROP "__props__"
#define PYOP_ATTR_UINAME "__label__"
#define PYOP_ATTR_IDNAME "__name__" /* use pythons class name */
PyObject *ret= NULL, *py_class_instance, *item= NULL;
int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED);
PointerRNA ptr_context;
- PyObject *py_context;
+ PointerRNA ptr_operator;
+ PyObject *py_operator;
PyGILState_STATE gilstate = PyGILState_Ensure();
+
+ bpy_import_main_set(CTX_data_main(C));
BPY_update_modules(); // XXX - the RNA pointers can change so update before running, would like a nicer solutuon for this.
RNA_property_collection_end(&iter);
}
-
+
+ /* set operator pointer RNA as instance "__operator__" attribute */
+ 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) {
item= PyObject_GetAttrString(py_class, "invoke");
- args = PyTuple_New(2);
- PyTuple_SET_ITEM(args, 1, pyop_dict_from_event(event));
+ args = PyTuple_New(3);
+
+ // PyTuple_SET_ITEM "steals" object reference, it is
+ // an object passed shouldn't be DECREF'ed
+ PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
+ PyTuple_SET_ITEM(args, 2, pyop_dict_from_event(event));
}
else if (mode==PYOP_EXEC) {
- item= PyObject_GetAttrString(py_class, "exec");
+ item= PyObject_GetAttrString(py_class, "execute");
args = PyTuple_New(2);
- RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context);
- py_context = pyrna_struct_CreatePyObject(&ptr_context);
- PyTuple_SET_ITEM(args, 1, py_context);
+ PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
}
else if (mode==PYOP_POLL) {
item= PyObject_GetAttrString(py_class, "poll");
} else if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) {
/* the returned value could not be converted into a flag */
BPy_errors_to_report(op->reports);
-
+
+ ret_flag = OPERATOR_CANCELLED;
}
/* there is no need to copy the py keyword dict modified by
* pyot->py_invoke(), back to the operator props since they are just
Py_DECREF(ret);
}
+ /* print operator return value */
+ if (mode != PYOP_POLL) {
+ char flag_str[100];
+ char class_name[100];
+ BPY_flag_def *flag_def = pyop_ret_flags;
+
+ strcpy(flag_str, "");
+
+ while(flag_def->name) {
+ if (ret_flag & flag_def->flag) {
+ if(flag_str[1])
+ sprintf(flag_str, "%s | %s", flag_str, flag_def->name);
+ else
+ strcpy(flag_str, flag_def->name);
+ }
+ flag_def++;
+ }
+
+ /* get class name */
+ item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
+ Py_DECREF(item);
+ strcpy(class_name, _PyUnicode_AsString(item));
+
+ fprintf(stderr, "%s's %s returned %s\n", class_name, mode == PYOP_EXEC ? "execute" : "invoke", flag_str);
+ }
+
PyGILState_Release(gilstate);
+ bpy_import_main_set(NULL);
return ret_flag;
}
/* api callbacks, detailed checks dont on adding */
if (PyObject_HasAttrString(py_class, "invoke"))
ot->invoke= PYTHON_OT_invoke;
- if (PyObject_HasAttrString(py_class, "exec"))
+ if (PyObject_HasAttrString(py_class, "execute"))
ot->exec= PYTHON_OT_exec;
if (PyObject_HasAttrString(py_class, "poll"))
ot->poll= PYTHON_OT_poll;
PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
{
PyObject *base_class, *item;
+ wmOperatorType *ot;
char *idname= NULL;
{PYOP_ATTR_UINAME, 's', 0, BPY_CLASS_ATTR_OPTIONAL},
{PYOP_ATTR_PROP, 'l', 0, BPY_CLASS_ATTR_OPTIONAL},
{PYOP_ATTR_DESCRIPTION, 's', 0, BPY_CLASS_ATTR_NONE_OK},
- {"exec", 'f', 2, BPY_CLASS_ATTR_OPTIONAL},
- {"invoke", 'f', 2, BPY_CLASS_ATTR_OPTIONAL},
+ {"execute", 'f', 2, BPY_CLASS_ATTR_OPTIONAL},
+ {"invoke", 'f', 3, BPY_CLASS_ATTR_OPTIONAL},
{"poll", 'f', 2, BPY_CLASS_ATTR_OPTIONAL},
{NULL, 0, 0, 0}
};
Py_DECREF(item);
idname = _PyUnicode_AsString(item);
- if (WM_operatortype_find(idname)) {
- PyErr_Format( PyExc_AttributeError, "Operator alredy exists with this name \"%s\"", idname);
- return NULL;
+ /* remove if it already exists */
+ if ((ot=WM_operatortype_find(idname))) {
+ Py_XDECREF((PyObject*)ot->pyop_data);
+ WM_operatortype_remove(idname);
}
/* If we have properties set, check its a list of dicts */