Added back importing UI scripts rather then running,
The bug was todo with bpy.data and bpy.types becoming invalid, temporary fix is to re-assign them to the bpy module before running python operators or panels. will look into a nicer way to get this working.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# import bpy
|
import bpy
|
||||||
|
|
||||||
class OBJECT_PT_transform(bpy.types.Panel):
|
class OBJECT_PT_transform(bpy.types.Panel):
|
||||||
__label__ = "Transform"
|
__label__ = "Transform"
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ extern "C" {
|
|||||||
int BPY_run_script_space_draw(struct bContext *C, struct SpaceScript * sc); // 2.5 working
|
int BPY_run_script_space_draw(struct bContext *C, struct SpaceScript * sc); // 2.5 working
|
||||||
void BPY_run_ui_scripts(struct bContext *C);
|
void BPY_run_ui_scripts(struct bContext *C);
|
||||||
// int BPY_run_script_space_listener(struct bContext *C, struct SpaceScript * sc, struct ARegion *ar, struct wmNotifier *wmn); // 2.5 working
|
// int BPY_run_script_space_listener(struct bContext *C, struct SpaceScript * sc, struct ARegion *ar, struct wmNotifier *wmn); // 2.5 working
|
||||||
|
void BPY_update_modules( void ); // XXX - annoying, need this for pointers that get out of date
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
#include "BLI_util.h"
|
#include "BLI_util.h"
|
||||||
|
#include "BLI_string.h"
|
||||||
|
|
||||||
#include "BKE_context.h"
|
#include "BKE_context.h"
|
||||||
#include "BKE_text.h"
|
#include "BKE_text.h"
|
||||||
@@ -38,10 +39,36 @@ void BPY_free_compiled_text( struct Text *text )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Description: Creates the bpy module and adds it to sys.modules for importing
|
||||||
|
*****************************************************************************/
|
||||||
|
static void bpy_init_modules( void )
|
||||||
|
{
|
||||||
|
PyObject *mod;
|
||||||
|
|
||||||
|
mod = PyModule_New("bpy");
|
||||||
|
|
||||||
|
PyModule_AddObject( mod, "data", BPY_rna_module() );
|
||||||
|
/* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */
|
||||||
|
PyModule_AddObject( mod, "types", BPY_rna_types() );
|
||||||
|
PyModule_AddObject( mod, "ops", BPY_operator_module() );
|
||||||
|
PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experemental, consider this a test, especially PyCObject is not meant to be perminant
|
||||||
|
|
||||||
|
/* add the module so we can import it */
|
||||||
|
PyDict_SetItemString(PySys_GetObject("modules"), "bpy", mod);
|
||||||
|
Py_DECREF(mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BPY_update_modules( void )
|
||||||
|
{
|
||||||
|
PyObject *mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
|
||||||
|
PyModule_AddObject( mod, "data", BPY_rna_module() );
|
||||||
|
PyModule_AddObject( mod, "types", BPY_rna_types() );
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Description: This function creates a new Python dictionary object.
|
* Description: This function creates a new Python dictionary object.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
static PyObject *CreateGlobalDictionary( bContext *C )
|
static PyObject *CreateGlobalDictionary( bContext *C )
|
||||||
{
|
{
|
||||||
PyObject *mod;
|
PyObject *mod;
|
||||||
@@ -51,23 +78,11 @@ static PyObject *CreateGlobalDictionary( bContext *C )
|
|||||||
PyDict_SetItemString( dict, "__name__", item );
|
PyDict_SetItemString( dict, "__name__", item );
|
||||||
Py_DECREF(item);
|
Py_DECREF(item);
|
||||||
|
|
||||||
/* add bpy to global namespace */
|
|
||||||
mod = PyModule_New("bpy");
|
|
||||||
PyDict_SetItemString( dict, "bpy", mod );
|
|
||||||
Py_DECREF(mod);
|
|
||||||
|
|
||||||
PyModule_AddObject( mod, "data", BPY_rna_module() );
|
|
||||||
/* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */
|
|
||||||
PyModule_AddObject( mod, "types", BPY_rna_types() );
|
|
||||||
PyModule_AddObject( mod, "ops", BPY_operator_module() );
|
|
||||||
PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experemental, consider this a test, especially PyCObject is not meant to be perminant
|
|
||||||
|
|
||||||
// XXX - evil, need to access context
|
// XXX - evil, need to access context
|
||||||
item = PyCObject_FromVoidPtr( C, NULL );
|
item = PyCObject_FromVoidPtr( C, NULL );
|
||||||
PyDict_SetItemString( dict, "__bpy_context__", item );
|
PyDict_SetItemString( dict, "__bpy_context__", item );
|
||||||
Py_DECREF(item);
|
Py_DECREF(item);
|
||||||
|
|
||||||
|
|
||||||
// XXX - put somewhere more logical
|
// XXX - put somewhere more logical
|
||||||
{
|
{
|
||||||
PyMethodDef *ml;
|
PyMethodDef *ml;
|
||||||
@@ -83,6 +98,11 @@ static PyObject *CreateGlobalDictionary( bContext *C )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* add bpy to global namespace */
|
||||||
|
mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
|
||||||
|
PyDict_SetItemString( dict, "bpy", mod );
|
||||||
|
Py_DECREF(mod);
|
||||||
|
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +117,10 @@ void BPY_start_python( void )
|
|||||||
/* Initialize thread support (also acquires lock) */
|
/* Initialize thread support (also acquires lock) */
|
||||||
PyEval_InitThreads();
|
PyEval_InitThreads();
|
||||||
|
|
||||||
// todo - sys paths - our own imports
|
|
||||||
|
/* bpy.* and lets us import it */
|
||||||
|
bpy_init_modules();
|
||||||
|
|
||||||
|
|
||||||
py_tstate = PyGILState_GetThisThreadState();
|
py_tstate = PyGILState_GetThisThreadState();
|
||||||
PyEval_ReleaseThread(py_tstate);
|
PyEval_ReleaseThread(py_tstate);
|
||||||
@@ -304,15 +327,29 @@ int BPY_run_python_script_space(const char *modulename, const char *func)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// #define TIME_REGISTRATION
|
||||||
|
|
||||||
|
#ifdef TIME_REGISTRATION
|
||||||
|
#include "PIL_time.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* XXX this is temporary, need a proper script registration system for 2.5 */
|
/* XXX this is temporary, need a proper script registration system for 2.5 */
|
||||||
void BPY_run_ui_scripts(bContext *C)
|
void BPY_run_ui_scripts(void)
|
||||||
{
|
{
|
||||||
|
#ifdef TIME_REGISTRATION
|
||||||
|
double time = PIL_check_seconds_timer();
|
||||||
|
#endif
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
struct stat status;
|
|
||||||
char *file_extension;
|
char *file_extension;
|
||||||
char path[FILE_MAX];
|
char path[FILE_MAX];
|
||||||
char *dirname= BLI_gethome_folder("ui");
|
char *dirname= BLI_gethome_folder("ui");
|
||||||
|
int filelen; /* filename length */
|
||||||
|
|
||||||
|
PyGILState_STATE gilstate;
|
||||||
|
PyObject *mod;
|
||||||
|
PyObject *sys_path_orig;
|
||||||
|
PyObject *sys_path_new;
|
||||||
|
|
||||||
if(!dirname)
|
if(!dirname)
|
||||||
return;
|
return;
|
||||||
@@ -322,22 +359,48 @@ void BPY_run_ui_scripts(bContext *C)
|
|||||||
if(!dir)
|
if(!dir)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (dir != NULL) {
|
gilstate = PyGILState_Ensure();
|
||||||
|
|
||||||
|
/* backup sys.path */
|
||||||
|
sys_path_orig= PySys_GetObject("path");
|
||||||
|
Py_INCREF(sys_path_orig); /* dont free it */
|
||||||
|
|
||||||
|
sys_path_new= PyList_New(1);
|
||||||
|
PyList_SET_ITEM(sys_path_new, 0, PyUnicode_FromString(dirname));
|
||||||
|
PySys_SetObject("path", sys_path_new);
|
||||||
|
Py_DECREF(sys_path_new);
|
||||||
|
|
||||||
|
|
||||||
while((de = readdir(dir)) != NULL) {
|
while((de = readdir(dir)) != NULL) {
|
||||||
BLI_make_file_string("/", path, dirname, de->d_name);
|
/* We could stat the file but easier just to let python
|
||||||
|
* import it and complain if theres a problem */
|
||||||
|
|
||||||
stat(path, &status);
|
|
||||||
|
|
||||||
/* run if it is a .py file */
|
|
||||||
if(S_ISREG(status.st_mode)) {
|
|
||||||
file_extension = strstr(de->d_name, ".py");
|
file_extension = strstr(de->d_name, ".py");
|
||||||
|
|
||||||
if(file_extension && *(file_extension + 3) == '\0')
|
if(file_extension && *(file_extension + 3) == '\0') {
|
||||||
BPY_run_python_script(C, path, NULL);
|
filelen = strlen(de->d_name);
|
||||||
|
BLI_strncpy(path, de->d_name, filelen-2); /* cut off the .py on copy */
|
||||||
|
|
||||||
|
mod= PyImport_ImportModuleLevel(path, NULL, NULL, NULL, 0);
|
||||||
|
if (mod) {
|
||||||
|
Py_DECREF(mod);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyErr_Print();
|
||||||
|
fprintf(stderr, "unable to import \"%s\" %s/%s\n", path, dirname, de->d_name);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
|
||||||
|
PySys_SetObject("path", sys_path_orig);
|
||||||
|
Py_DECREF(sys_path_orig);
|
||||||
|
|
||||||
|
PyGILState_Release(gilstate);
|
||||||
|
#ifdef TIME_REGISTRATION
|
||||||
|
printf("script time %f\n", (PIL_check_seconds_timer()-time));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -181,6 +181,8 @@ static struct BPY_flag_def pyop_ret_flags[] = {
|
|||||||
#define PYOP_INVOKE 2
|
#define PYOP_INVOKE 2
|
||||||
#define PYOP_POLL 3
|
#define PYOP_POLL 3
|
||||||
|
|
||||||
|
extern void BPY_update_modules( void ); //XXX temp solution
|
||||||
|
|
||||||
static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *event)
|
static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *event)
|
||||||
{
|
{
|
||||||
PyObject *py_class = op->type->pyop_data;
|
PyObject *py_class = op->type->pyop_data;
|
||||||
@@ -190,6 +192,8 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
|
|||||||
|
|
||||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||||
|
|
||||||
|
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
|
||||||
py_class_instance = PyObject_Call(py_class, args, NULL);
|
py_class_instance = PyObject_Call(py_class, args, NULL);
|
||||||
|
|||||||
@@ -44,6 +44,8 @@
|
|||||||
#define PYPANEL_DRAW 1
|
#define PYPANEL_DRAW 1
|
||||||
#define PYPANEL_POLL 2
|
#define PYPANEL_POLL 2
|
||||||
|
|
||||||
|
extern void BPY_update_modules( void ); //XXX temp solution
|
||||||
|
|
||||||
static int PyPanel_generic(int mode, const bContext *C, Panel *pnl)
|
static int PyPanel_generic(int mode, const bContext *C, Panel *pnl)
|
||||||
{
|
{
|
||||||
PyObject *py_class= (PyObject *)(pnl->type->py_data);
|
PyObject *py_class= (PyObject *)(pnl->type->py_data);
|
||||||
@@ -55,6 +57,8 @@ static int PyPanel_generic(int mode, const bContext *C, Panel *pnl)
|
|||||||
|
|
||||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||||
|
|
||||||
|
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);
|
||||||
RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->srna, pnl, &panelptr);
|
RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->srna, pnl, &panelptr);
|
||||||
PyTuple_SET_ITEM(args, 0, pyrna_struct_CreatePyObject(&panelptr));
|
PyTuple_SET_ITEM(args, 0, pyrna_struct_CreatePyObject(&panelptr));
|
||||||
|
|||||||
@@ -1714,13 +1714,13 @@ static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyTypeObject pyrna_basetype_Type;
|
PyTypeObject pyrna_basetype_Type = BLANK_PYTHON_TYPE;
|
||||||
|
|
||||||
PyObject *BPY_rna_types(void)
|
PyObject *BPY_rna_types(void)
|
||||||
{
|
{
|
||||||
BPy_BaseTypeRNA *self;
|
BPy_BaseTypeRNA *self;
|
||||||
|
|
||||||
memset(&pyrna_basetype_Type, 0, sizeof(pyrna_basetype_Type));
|
if ((pyrna_basetype_Type.tp_flags & Py_TPFLAGS_READY)==0) {
|
||||||
pyrna_basetype_Type.tp_name = "RNA_Types";
|
pyrna_basetype_Type.tp_name = "RNA_Types";
|
||||||
pyrna_basetype_Type.tp_basicsize = sizeof( BPy_BaseTypeRNA );
|
pyrna_basetype_Type.tp_basicsize = sizeof( BPy_BaseTypeRNA );
|
||||||
pyrna_basetype_Type.tp_getattro = ( getattrofunc )pyrna_basetype_getattro;
|
pyrna_basetype_Type.tp_getattro = ( getattrofunc )pyrna_basetype_getattro;
|
||||||
@@ -1729,6 +1729,7 @@ PyObject *BPY_rna_types(void)
|
|||||||
|
|
||||||
if( PyType_Ready( &pyrna_basetype_Type ) < 0 )
|
if( PyType_Ready( &pyrna_basetype_Type ) < 0 )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
self= (BPy_BaseTypeRNA *)PyObject_NEW( BPy_BaseTypeRNA, &pyrna_basetype_Type );
|
self= (BPy_BaseTypeRNA *)PyObject_NEW( BPy_BaseTypeRNA, &pyrna_basetype_Type );
|
||||||
|
|
||||||
|
|||||||
@@ -67,4 +67,7 @@ int BPY_class_validate(const char *class_type, PyObject *class, PyObject *base_c
|
|||||||
|
|
||||||
char *BPy_enum_as_string(struct EnumPropertyItem *item);
|
char *BPy_enum_as_string(struct EnumPropertyItem *item);
|
||||||
|
|
||||||
|
|
||||||
|
#define BLANK_PYTHON_TYPE {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user