Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h3
-rw-r--r--source/blender/python/intern/bpy_rna.c41
-rw-r--r--source/blender/windowmanager/intern/wm.c7
3 files changed, 43 insertions, 8 deletions
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 9df3e053d9f..a53645e7442 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -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 */
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index a5ada5f4218..6f36a7e12e2 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -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) {
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index e2b2c17beee..048487fcd68 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -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);