diff options
Diffstat (limited to 'source/blender/python/intern/bpy_interface.c')
-rw-r--r-- | source/blender/python/intern/bpy_interface.c | 125 |
1 files changed, 94 insertions, 31 deletions
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 } |