Revision: 27167
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=27167
Author:   campbellbarton
Date:     2010-02-27 15:44:46 +0100 (Sat, 27 Feb 2010)

Log Message:
-----------
hold the python operator instance in the operator, otherwise the handelers need 
to be stored in the operator type or in the module which isnt nice for modal 
operators.

Modified Paths:
--------------
    trunk/blender/source/blender/makesdna/DNA_windowmanager_types.h
    trunk/blender/source/blender/python/intern/bpy_rna.c
    trunk/blender/source/blender/windowmanager/intern/wm.c

Modified: trunk/blender/source/blender/makesdna/DNA_windowmanager_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_windowmanager_types.h     
2010-02-27 13:27:06 UTC (rev 27166)
+++ trunk/blender/source/blender/makesdna/DNA_windowmanager_types.h     
2010-02-27 14:44:46 UTC (rev 27167)
@@ -271,8 +271,9 @@
        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 */

Modified: trunk/blender/source/blender/python/intern/bpy_rna.c
===================================================================
--- trunk/blender/source/blender/python/intern/bpy_rna.c        2010-02-27 
13:27:06 UTC (rev 27166)
+++ trunk/blender/source/blender/python/intern/bpy_rna.c        2010-02-27 
14:44:46 UTC (rev 27167)
@@ -4149,7 +4149,8 @@
 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 @@
 
        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) {

Modified: trunk/blender/source/blender/windowmanager/intern/wm.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm.c      2010-02-27 
13:27:06 UTC (rev 27166)
+++ trunk/blender/source/blender/windowmanager/intern/wm.c      2010-02-27 
14:44:46 UTC (rev 27167)
@@ -54,6 +54,7 @@
 #include "wm.h"
 
 #include "ED_screen.h"
+#include "BPY_extern.h"
 
 #include "RNA_types.h"
 
@@ -63,6 +64,12 @@
 
 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);


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to