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.

This commit is contained in:
Campbell Barton 2010-02-27 14:44:46 +00:00
parent b6acf0bb48
commit ddacff06f2
3 changed files with 43 additions and 8 deletions

View 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 */

View 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) {

View File

@ -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);