forked from bartvdbraak/blender
bpy_context_set and bpy_context_clear to replace a number of functions (some were not always called causing bugs).
fix for a leak when trying to run a text with a syntax error too.
This commit is contained in:
parent
ce273aee08
commit
70f011bbce
@ -45,6 +45,50 @@
|
|||||||
#include "../generic/BGL.h"
|
#include "../generic/BGL.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* for internal use, when starting and ending python scripts */
|
||||||
|
|
||||||
|
/* incase a python script triggers another python call, stop bpy_context_clear from invalidating */
|
||||||
|
static int py_call_level= 0;
|
||||||
|
|
||||||
|
void bpy_context_set(bContext *C, PyGILState_STATE *gilstate)
|
||||||
|
{
|
||||||
|
py_call_level++;
|
||||||
|
|
||||||
|
if(gilstate)
|
||||||
|
*gilstate = PyGILState_Ensure();
|
||||||
|
|
||||||
|
if(py_call_level==1) {
|
||||||
|
|
||||||
|
BPY_update_modules(); /* can give really bad results if this isnt here */
|
||||||
|
|
||||||
|
if(C) { // XXX - should always be true.
|
||||||
|
BPy_SetContext(C);
|
||||||
|
bpy_import_main_set(CTX_data_main(C));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "ERROR: Python context called with a NULL Context. this should not happen!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void bpy_context_clear(bContext *C, PyGILState_STATE *gilstate)
|
||||||
|
{
|
||||||
|
py_call_level--;
|
||||||
|
|
||||||
|
if(gilstate)
|
||||||
|
PyGILState_Release(*gilstate);
|
||||||
|
|
||||||
|
if(py_call_level < 0) {
|
||||||
|
fprintf(stderr, "ERROR: Python context internal state bug. this should not happen!\n");
|
||||||
|
}
|
||||||
|
else if(py_call_level==0) {
|
||||||
|
// XXX - Calling classes currently wont store the context :\, cant set NULL because of this. but this is very flakey still.
|
||||||
|
//BPy_SetContext(NULL);
|
||||||
|
//bpy_import_main_set(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void BPY_free_compiled_text( struct Text *text )
|
void BPY_free_compiled_text( struct Text *text )
|
||||||
{
|
{
|
||||||
if( text->compiled ) {
|
if( text->compiled ) {
|
||||||
@ -106,9 +150,6 @@ static PyObject *CreateGlobalDictionary( bContext *C )
|
|||||||
PyDict_SetItemString( dict, "__name__", item );
|
PyDict_SetItemString( dict, "__name__", item );
|
||||||
Py_DECREF(item);
|
Py_DECREF(item);
|
||||||
|
|
||||||
// XXX - evil, need to access context
|
|
||||||
BPy_SetContext(C);
|
|
||||||
|
|
||||||
// XXX - put somewhere more logical
|
// XXX - put somewhere more logical
|
||||||
{
|
{
|
||||||
PyMethodDef *ml;
|
PyMethodDef *ml;
|
||||||
@ -224,19 +265,14 @@ void BPY_end_python( void )
|
|||||||
/* Can run a file or text block */
|
/* Can run a file or text block */
|
||||||
int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struct ReportList *reports)
|
int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struct ReportList *reports)
|
||||||
{
|
{
|
||||||
PyObject *py_dict, *py_result;
|
PyObject *py_dict, *py_result= NULL;
|
||||||
PyGILState_STATE gilstate;
|
PyGILState_STATE gilstate;
|
||||||
|
|
||||||
if (fn==NULL && text==NULL) {
|
if (fn==NULL && text==NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//BPY_start_python();
|
bpy_context_set(C, &gilstate);
|
||||||
|
|
||||||
gilstate = PyGILState_Ensure();
|
|
||||||
|
|
||||||
BPY_update_modules(); /* can give really bad results if this isnt here */
|
|
||||||
bpy_import_main_set(CTX_data_main(C));
|
|
||||||
|
|
||||||
py_dict = CreateGlobalDictionary(C);
|
py_dict = CreateGlobalDictionary(C);
|
||||||
|
|
||||||
@ -251,13 +287,11 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
|
|||||||
MEM_freeN( buf );
|
MEM_freeN( buf );
|
||||||
|
|
||||||
if( PyErr_Occurred( ) ) {
|
if( PyErr_Occurred( ) ) {
|
||||||
BPy_errors_to_report(reports);
|
|
||||||
BPY_free_compiled_text( text );
|
BPY_free_compiled_text( text );
|
||||||
PyGILState_Release(gilstate);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
py_result = PyEval_EvalCode( text->compiled, py_dict, py_dict );
|
if(text->compiled)
|
||||||
|
py_result = PyEval_EvalCode( text->compiled, py_dict, py_dict );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
#if 0
|
#if 0
|
||||||
@ -287,10 +321,9 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
|
|||||||
}
|
}
|
||||||
|
|
||||||
Py_DECREF(py_dict);
|
Py_DECREF(py_dict);
|
||||||
PyGILState_Release(gilstate);
|
|
||||||
bpy_import_main_set(NULL);
|
|
||||||
|
|
||||||
//BPY_end_python();
|
bpy_context_clear(C, &gilstate);
|
||||||
|
|
||||||
return py_result ? 1:0;
|
return py_result ? 1:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,12 +506,7 @@ void BPY_run_ui_scripts(bContext *C, int reload)
|
|||||||
PyGILState_STATE gilstate;
|
PyGILState_STATE gilstate;
|
||||||
PyObject *sys_path;
|
PyObject *sys_path;
|
||||||
|
|
||||||
gilstate = PyGILState_Ensure();
|
bpy_context_set(C, &gilstate);
|
||||||
|
|
||||||
// XXX - evil, need to access context
|
|
||||||
BPy_SetContext(C);
|
|
||||||
bpy_import_main_set(CTX_data_main(C));
|
|
||||||
|
|
||||||
|
|
||||||
sys_path= PySys_GetObject("path"); /* borrow */
|
sys_path= PySys_GetObject("path"); /* borrow */
|
||||||
PyList_Insert(sys_path, 0, Py_None); /* place holder, resizes the list */
|
PyList_Insert(sys_path, 0, Py_None); /* place holder, resizes the list */
|
||||||
@ -537,9 +565,8 @@ void BPY_run_ui_scripts(bContext *C, int reload)
|
|||||||
|
|
||||||
PyList_SetSlice(sys_path, 0, 1, NULL); /* remove the first item */
|
PyList_SetSlice(sys_path, 0, 1, NULL); /* remove the first item */
|
||||||
|
|
||||||
bpy_import_main_set(NULL);
|
bpy_context_clear(C, &gilstate);
|
||||||
|
|
||||||
PyGILState_Release(gilstate);
|
|
||||||
#ifdef TIME_REGISTRATION
|
#ifdef TIME_REGISTRATION
|
||||||
printf("script time %f\n", (PIL_check_seconds_timer()-time));
|
printf("script time %f\n", (PIL_check_seconds_timer()-time));
|
||||||
#endif
|
#endif
|
||||||
|
@ -93,11 +93,9 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
|
|||||||
PointerRNA ptr_event;
|
PointerRNA ptr_event;
|
||||||
PyObject *py_operator;
|
PyObject *py_operator;
|
||||||
|
|
||||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
PyGILState_STATE gilstate;
|
||||||
|
|
||||||
bpy_import_main_set(CTX_data_main(C));
|
bpy_context_set(C, &gilstate);
|
||||||
|
|
||||||
BPY_update_modules(); // XXX - the RNA pointers can change so update before running, would like a nicer solutuon for this.
|
|
||||||
|
|
||||||
args = PyTuple_New(1);
|
args = PyTuple_New(1);
|
||||||
PyTuple_SET_ITEM(args, 0, PyObject_GetAttrString(py_class, "__rna__")); // need to use an rna instance as the first arg
|
PyTuple_SET_ITEM(args, 0, PyObject_GetAttrString(py_class, "__rna__")); // need to use an rna instance as the first arg
|
||||||
@ -221,8 +219,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PyGILState_Release(gilstate);
|
bpy_context_clear(C, &gilstate);
|
||||||
bpy_import_main_set(NULL);
|
|
||||||
|
|
||||||
return ret_flag;
|
return ret_flag;
|
||||||
}
|
}
|
||||||
|
@ -2918,9 +2918,10 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
|
|||||||
void *retdata= NULL;
|
void *retdata= NULL;
|
||||||
int err= 0, i, flag;
|
int err= 0, i, flag;
|
||||||
|
|
||||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
PyGILState_STATE gilstate;
|
||||||
|
|
||||||
BPY_update_modules(); // XXX - the RNA pointers can change so update before running, would like a nicer solution for this.
|
bContext *C= BPy_GetContext(); // XXX - NEEDS FIXING, QUITE BAD.
|
||||||
|
bpy_context_set(C, &gilstate);
|
||||||
|
|
||||||
py_class= RNA_struct_py_type_get(ptr->type);
|
py_class= RNA_struct_py_type_get(ptr->type);
|
||||||
|
|
||||||
@ -2996,7 +2997,7 @@ static int bpy_class_call(PointerRNA *ptr, FunctionRNA *func, ParameterList *par
|
|||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
PyGILState_Release(gilstate);
|
bpy_context_clear(C, &gilstate);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -82,4 +82,8 @@ int BPy_errors_to_report(struct ReportList *reports);
|
|||||||
struct bContext *BPy_GetContext(void);
|
struct bContext *BPy_GetContext(void);
|
||||||
void BPy_SetContext(struct bContext *C);
|
void BPy_SetContext(struct bContext *C);
|
||||||
|
|
||||||
|
extern void bpy_context_set(struct bContext *C, PyGILState_STATE *gilstate);
|
||||||
|
extern void bpy_context_clear(struct bContext *C, PyGILState_STATE *gilstate);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user