hold the python operator instance in the operator, otherwise the handelers need to...
authorCampbell Barton <ideasman42@gmail.com>
Sat, 27 Feb 2010 14:44:46 +0000 (14:44 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 27 Feb 2010 14:44:46 +0000 (14:44 +0000)
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/python/intern/bpy_rna.c
source/blender/windowmanager/intern/wm.c

index 9df3e053d9fbd8a699b05e7bfa99062c57b1583a..a53645e744237b418694d718a0e3d9b47febc531 100644 (file)
@@ -271,8 +271,9 @@ typedef struct wmOperator {
        IDProperty *properties;         /* saved, user-settable properties */
 
        /* runtime */
-       struct wmOperatorType *type;            /* operator type definition from idname */
+       struct wmOperatorType *type;/* operator type definition from idname */
        void *customdata;                       /* custom storage, only while operator runs */
+       void *py_instance;                      /* python stores the class instance here */
 
        struct PointerRNA *ptr;         /* rna pointer to access properties */
        struct ReportList *reports;     /* errors and warnings storage */
index a5ada5f4218618c8a5a4c63ac569d78a6332f6e1..6f36a7e12e2308a80a9277f8d3977dc87685cc92 100644 (file)
@@ -4149,7 +4149,8 @@ extern void BPY_update_modules( void ); //XXX temp solution
 static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
 {
        PyObject *args;
-       PyObject *ret= NULL, *py_class, *py_class_instance, *item, *parmitem;
+       PyObject *ret= NULL, *py_srna= NULL, *py_class, *py_class_instance= NULL, *parmitem;
+       void **py_class_instance_store= NULL;
        PropertyRNA *parm;
        ParameterIterator iter;
        PointerRNA funcptr;
@@ -4165,23 +4166,49 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
 
        py_class= RNA_struct_py_type_get(ptr->type);
        
-       item = pyrna_struct_CreatePyObject(ptr);
-       if(item == NULL) {
+       /* exception, operators store their PyObjects for re-use */
+       if(ptr->data) {
+               if(RNA_struct_is_a(ptr->type, &RNA_Operator)) {
+                       wmOperator *op= ptr->data;
+                       if(op->py_instance) {
+                               py_class_instance= op->py_instance;
+                               Py_INCREF(py_class_instance);
+                       }
+                       else {
+                               /* store the instance here once its created */
+                               py_class_instance_store= &op->py_instance;
+                       }
+               }
+       }
+       /* end exception */
+
+       if(py_class_instance==NULL)
+               py_srna= pyrna_struct_CreatePyObject(ptr);
+
+       if(py_class_instance) {
+               /* special case, instance is cached */
+       }
+       else if(py_srna == NULL) {
                py_class_instance = NULL;
        }
-       else if(item == Py_None) { /* probably wont ever happen but possible */
-               Py_DECREF(item);
+       else if(py_srna == Py_None) { /* probably wont ever happen but possible */
+               Py_DECREF(py_srna);
                py_class_instance = NULL;
        }
        else {
                args = PyTuple_New(1);
-               PyTuple_SET_ITEM(args, 0, item);
+               PyTuple_SET_ITEM(args, 0, py_srna);
                py_class_instance = PyObject_Call(py_class, args, NULL);
                Py_DECREF(args);
+
+               if(py_class_instance_store) {
+                       *py_class_instance_store = py_class_instance;
+                       Py_INCREF(py_class_instance);
+               }
        }
 
        if (py_class_instance) { /* Initializing the class worked, now run its invoke function */
-               item= PyObject_GetAttrString(py_class, RNA_function_identifier(func));
+               PyObject *item= PyObject_GetAttrString(py_class, RNA_function_identifier(func));
 //             flag= RNA_function_flag(func);
 
                if(item) {
index e2b2c17beeefff168379ff1701b3e5528367252c..048487fcd6800c95117134ebaecbd686cf02a9ea 100644 (file)
@@ -54,6 +54,7 @@
 #include "wm.h"
 
 #include "ED_screen.h"
+#include "BPY_extern.h"
 
 #include "RNA_types.h"
 
 
 void WM_operator_free(wmOperator *op)
 {
+       if(op->py_instance) {
+               /* do this first incase there are any __del__ functions or
+                * similar that use properties */
+               BPY_DECREF(op->py_instance);
+       }
+
        if(op->ptr) {
                op->properties= op->ptr->data;
                MEM_freeN(op->ptr);