minor changes and error checking.
authorCampbell Barton <ideasman42@gmail.com>
Sun, 28 Dec 2008 13:03:37 +0000 (13:03 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sun, 28 Dec 2008 13:03:37 +0000 (13:03 +0000)
tested first PyOperator, basics work now, invoke/exec can be used to make an operator that edits RNA or calls other operators.

source/blender/python/intern/bpy_operator.c
source/blender/python/intern/bpy_opwrapper.c

index 7d3a253980d5d33d512603e378174788ebdc0bbb..2765a59ce42cf660204404d1acacc092159fc498 100644 (file)
@@ -188,10 +188,9 @@ static PyObject * pyop_func_call(BPy_OperatorFunc * self, PyObject *args, PyObje
        
        RNA_pointer_create(NULL, NULL, ot->srna, &properties, &ptr);
        
-       PYOP_props_from_dict(&ptr, kw);
+       error_val= PYOP_props_from_dict(&ptr, kw);
        
        if (error_val==0) {
-               //WM_operator_name_call(self->C, self->name, WM_OP_INVOKE_DEFAULT, properties);
                WM_operator_name_call(self->C, self->name, WM_OP_EXEC_DEFAULT, properties);
        }
 
@@ -200,7 +199,21 @@ static PyObject * pyop_func_call(BPy_OperatorFunc * self, PyObject *args, PyObje
                MEM_freeN(properties);
        }
 
-       if (error_val) {
+
+#if 0
+       /* if there is some way to know an operator takes args we should use this */
+       {
+               /* no props */
+               if (kw != NULL) {
+                       PyErr_Format(PyExc_AttributeError, "Operator \"%s\" does not take any args", self->name);
+                       return NULL;
+               }
+
+               WM_operator_name_call(self->C, self->name, WM_OP_EXEC_DEFAULT, NULL);
+       }
+#endif
+
+       if (error_val==-1) {
                return NULL;
        }
 
index 46ec0f9873e95a5aa9bf0ec01084ab640247891b..aca340df01a41cf6e1bc801fea64072fd538bba9 100644 (file)
@@ -38,7 +38,6 @@
 #include "bpy_rna.h"
 #include "bpy_compat.h"
 #include "bpy_util.h"
-#include "bpy_operator.h" /* for PYOP_props_from_dict() */
 
 typedef struct PyOperatorType {
        void *next, *prev;
@@ -177,6 +176,7 @@ static struct BPY_flag_def pyop_ret_flags[] = {
        {NULL, 0}
 };
 
+/* exec only - no user input */
 static int PYTHON_OT_exec(bContext *C, wmOperator *op)
 {
        PyOperatorType *pyot = op->type->pyop_data;
@@ -200,19 +200,34 @@ static int PYTHON_OT_exec(bContext *C, wmOperator *op)
        Py_DECREF(args);
        Py_DECREF(kw);
 
-       return OPERATOR_FINISHED;
+       return ret_flag;
 }
 
+/* This invoke function can take events and
+ *
+ * It is up to the pyot->py_invoke() python func to run pyot->py_exec()
+ * the invoke function gets the keyword props as a dict, but can parse them
+ * to py_exec like this...
+ *
+ * def op_exec(x=-1, y=-1, text=""):
+ *     ...
+ *
+ * def op_invoke(event, prop_defs):
+ *     prop_defs['x'] = event['x']
+ *     ...
+ *     op_exec(**prop_defs)
+ *
+ * when there is no invoke function, C calls exec and sets the props.
+ */
 static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
        PyOperatorType *pyot = op->type->pyop_data;
        PyObject *args= PyTuple_New(2);
-       PyObject *kw= pyop_kwargs_from_operator(op);
        PyObject *ret;
        int ret_flag;
 
        PyTuple_SET_ITEM(args, 0, pyop_dict_from_event(event));
-       PyTuple_SET_ITEM(args, 1, kw);
+       PyTuple_SET_ITEM(args, 1, pyop_kwargs_from_operator(op));
 
        ret = PyObject_Call(pyot->py_invoke, args, NULL);
 
@@ -224,13 +239,13 @@ static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
                         /* the returned value could not be converted into a flag */
                        PyErr_Print();
                }
-               else {
-                       /* copy the args back to the prop */
-                       if (PYOP_props_from_dict(op->ptr, kw) == -1) {
-                               /* one of the dict items didnt convert back to the prop */
-                               PyErr_Print();
-                       }
-               }
+               /* there is no need to copy the py keyword dict modified by
+                * pyot->py_invoke(), back to the operator props since they are just
+                * thrown away anyway
+                *
+                * If we ever want to do this and use the props again,
+                * it can be done with - PYOP_props_from_dict(op->ptr, kw)
+                */
        }