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:
authorCampbell Barton <ideasman42@gmail.com>2009-04-11 20:17:39 +0400
committerCampbell Barton <ideasman42@gmail.com>2009-04-11 20:17:39 +0400
commit3f98b7ac35cbac648face4334402e1c3b707ed0c (patch)
tree84c34989fce927f6f3aa15ea329761164efec5c6 /source/blender
parent91d6e68830cc1d282c455c8e2c56f862473bded7 (diff)
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.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/python/BPY_extern.h1
-rw-r--r--source/blender/python/intern/bpy_interface.c125
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c4
-rw-r--r--source/blender/python/intern/bpy_panel_wrap.c4
-rw-r--r--source/blender/python/intern/bpy_rna.c21
-rw-r--r--source/blender/python/intern/bpy_util.h3
6 files changed, 117 insertions, 41 deletions
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index f46ef0fa670..6039ad05962 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -101,6 +101,7 @@ extern "C" {
int BPY_run_script_space_draw(struct bContext *C, struct SpaceScript * sc); // 2.5 working
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
+ void BPY_update_modules( void ); // XXX - annoying, need this for pointers that get out of date
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index c9485e0f22a..f6273c6381b 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -26,6 +26,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_util.h"
+#include "BLI_string.h"
#include "BKE_context.h"
#include "BKE_text.h"
@@ -39,22 +40,13 @@ void BPY_free_compiled_text( struct Text *text )
}
/*****************************************************************************
-* Description: This function creates a new Python dictionary object.
+* Description: Creates the bpy module and adds it to sys.modules for importing
*****************************************************************************/
-
-static PyObject *CreateGlobalDictionary( bContext *C )
+static void bpy_init_modules( void )
{
PyObject *mod;
- PyObject *dict = PyDict_New( );
- PyObject *item = PyUnicode_FromString( "__main__" );
- PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins( ) );
- PyDict_SetItemString( dict, "__name__", 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() ); */
@@ -62,12 +54,35 @@ static PyObject *CreateGlobalDictionary( bContext *C )
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.
+*****************************************************************************/
+static PyObject *CreateGlobalDictionary( bContext *C )
+{
+ PyObject *mod;
+ PyObject *dict = PyDict_New( );
+ PyObject *item = PyUnicode_FromString( "__main__" );
+ PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins( ) );
+ PyDict_SetItemString( dict, "__name__", item );
+ Py_DECREF(item);
+
// XXX - evil, need to access context
item = PyCObject_FromVoidPtr( C, NULL );
PyDict_SetItemString( dict, "__bpy_context__", item );
Py_DECREF(item);
-
// XXX - put somewhere more logical
{
PyMethodDef *ml;
@@ -83,13 +98,18 @@ 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;
}
void BPY_start_python( void )
{
PyThreadState *py_tstate = NULL;
-
+
Py_Initialize( );
//PySys_SetArgv( argc_copy, argv_copy );
@@ -97,7 +117,10 @@ void BPY_start_python( void )
/* Initialize thread support (also acquires lock) */
PyEval_InitThreads();
- // todo - sys paths - our own imports
+
+ /* bpy.* and lets us import it */
+ bpy_init_modules();
+
py_tstate = PyGILState_GetThisThreadState();
PyEval_ReleaseThread(py_tstate);
@@ -304,16 +327,30 @@ int BPY_run_python_script_space(const char *modulename, const char *func)
}
#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 */
-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;
struct dirent *de;
- struct stat status;
char *file_extension;
char path[FILE_MAX];
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)
return;
@@ -321,23 +358,49 @@ void BPY_run_ui_scripts(bContext *C)
if(!dir)
return;
-
- if (dir != NULL) {
- while((de = readdir(dir)) != NULL) {
- BLI_make_file_string("/", path, dirname, de->d_name);
+
+ 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) {
+ /* We could stat the file but easier just to let python
+ * import it and complain if theres a problem */
+
+ file_extension = strstr(de->d_name, ".py");
+
+ if(file_extension && *(file_extension + 3) == '\0') {
+ filelen = strlen(de->d_name);
+ BLI_strncpy(path, de->d_name, filelen-2); /* cut off the .py on copy */
- stat(path, &status);
-
- /* run if it is a .py file */
- if(S_ISREG(status.st_mode)) {
- file_extension = strstr(de->d_name, ".py");
-
- if(file_extension && *(file_extension + 3) == '\0')
- BPY_run_python_script(C, path, NULL);
+ 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
}
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index 1db1f547fa6..02a87450a06 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -181,6 +181,8 @@ static struct BPY_flag_def pyop_ret_flags[] = {
#define PYOP_INVOKE 2
#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)
{
PyObject *py_class = op->type->pyop_data;
@@ -189,6 +191,8 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED);
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);
PyTuple_SET_ITEM(args, 0, PyObject_GetAttrString(py_class, "__rna__")); // need to use an rna instance as the first arg
diff --git a/source/blender/python/intern/bpy_panel_wrap.c b/source/blender/python/intern/bpy_panel_wrap.c
index bc85e5bdced..8cdac286f8d 100644
--- a/source/blender/python/intern/bpy_panel_wrap.c
+++ b/source/blender/python/intern/bpy_panel_wrap.c
@@ -44,6 +44,8 @@
#define PYPANEL_DRAW 1
#define PYPANEL_POLL 2
+extern void BPY_update_modules( void ); //XXX temp solution
+
static int PyPanel_generic(int mode, const bContext *C, Panel *pnl)
{
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();
+ BPY_update_modules(); // XXX - the RNA pointers can change so update before running, would like a nicer solutuon for this.
+
args = PyTuple_New(1);
RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->srna, pnl, &panelptr);
PyTuple_SET_ITEM(args, 0, pyrna_struct_CreatePyObject(&panelptr));
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index c7c4a5ef489..d2d9364e7df 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -1714,21 +1714,22 @@ static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
return list;
}
-PyTypeObject pyrna_basetype_Type;
+PyTypeObject pyrna_basetype_Type = BLANK_PYTHON_TYPE;
PyObject *BPY_rna_types(void)
{
BPy_BaseTypeRNA *self;
- memset(&pyrna_basetype_Type, 0, sizeof(pyrna_basetype_Type));
- pyrna_basetype_Type.tp_name = "RNA_Types";
- pyrna_basetype_Type.tp_basicsize = sizeof( BPy_BaseTypeRNA );
- pyrna_basetype_Type.tp_getattro = ( getattrofunc )pyrna_basetype_getattro;
- pyrna_basetype_Type.tp_flags = Py_TPFLAGS_DEFAULT;
- pyrna_basetype_Type.tp_methods = pyrna_basetype_methods;
-
- if( PyType_Ready( &pyrna_basetype_Type ) < 0 )
- return NULL;
+ if ((pyrna_basetype_Type.tp_flags & Py_TPFLAGS_READY)==0) {
+ pyrna_basetype_Type.tp_name = "RNA_Types";
+ pyrna_basetype_Type.tp_basicsize = sizeof( BPy_BaseTypeRNA );
+ pyrna_basetype_Type.tp_getattro = ( getattrofunc )pyrna_basetype_getattro;
+ pyrna_basetype_Type.tp_flags = Py_TPFLAGS_DEFAULT;
+ pyrna_basetype_Type.tp_methods = pyrna_basetype_methods;
+
+ if( PyType_Ready( &pyrna_basetype_Type ) < 0 )
+ return NULL;
+ }
self= (BPy_BaseTypeRNA *)PyObject_NEW( BPy_BaseTypeRNA, &pyrna_basetype_Type );
diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h
index e2bea331b0e..9ce7a17b9e3 100644
--- a/source/blender/python/intern/bpy_util.h
+++ b/source/blender/python/intern/bpy_util.h
@@ -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);
+
+#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