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 09:46:40 +0400
committerCampbell Barton <ideasman42@gmail.com>2009-04-11 09:46:40 +0400
commit9d922b4c24538d53aed9b0661804652455f8a3b7 (patch)
treeca1beb6b2c571e84d7822b414ce0b30cefc38002 /source/blender/python/intern
parentc7b587105fae174c47bd29291ac384037af06685 (diff)
Changed the script UI registration to import rather then run each python script,
this means it caches the compiled pyc files after importing fro the first time. My times for importing 501 buttons_objects.py files were. - running each as a script 1.9sec - importing for the first time 1.8sec - importing a second time (using pyc files) 0.57sec Also added "bpy" to sys.modules so it can be imported.
Diffstat (limited to 'source/blender/python/intern')
-rw-r--r--source/blender/python/intern/bpy_interface.c120
-rw-r--r--source/blender/python/intern/bpy_operator.c2
-rw-r--r--source/blender/python/intern/bpy_operator.h2
-rw-r--r--source/blender/python/intern/bpy_rna.c21
4 files changed, 103 insertions, 42 deletions
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 667dd14283f..db82b740a15 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,35 +40,42 @@ 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() ); */
PyModule_AddObject( mod, "types", BPY_rna_types() );
- PyModule_AddObject( mod, "ops", BPY_operator_module(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);
+}
+
+/*****************************************************************************
+* 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 +91,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 +110,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 +320,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 +351,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.c b/source/blender/python/intern/bpy_operator.c
index 29ec3376765..3e403ea1aad 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -262,7 +262,7 @@ static PyObject *pyop_base_rna(PyObject *self, PyObject *pyname)
PyTypeObject pyop_base_Type = {NULL};
-PyObject *BPY_operator_module( bContext *C )
+PyObject *BPY_operator_module( void )
{
pyop_base_Type.tp_name = "OperatorBase";
pyop_base_Type.tp_basicsize = sizeof( BPy_OperatorBase );
diff --git a/source/blender/python/intern/bpy_operator.h b/source/blender/python/intern/bpy_operator.h
index 8eb0b887baa..c4741f936bf 100644
--- a/source/blender/python/intern/bpy_operator.h
+++ b/source/blender/python/intern/bpy_operator.h
@@ -40,7 +40,7 @@ typedef struct {
PyObject_HEAD /* required python macro */
} BPy_OperatorBase;
-PyObject *BPY_operator_module(bContext *C );
+PyObject *BPY_operator_module(void);
/* fill in properties from a python dict */
int PYOP_props_from_dict(PointerRNA *ptr, PyObject *kw);
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 3dc7456de61..3f70d914801 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -1526,10 +1526,13 @@ PyObject* pyrna_struct_Subtype(PointerRNA *ptr)
- myClass = type(name='myClass', bases=(myBase,), dict={'some':'value'})
*/
char name[256], *nameptr;
+ const char *descr= RNA_struct_ui_description(ptr);
PyObject *args = PyTuple_New(3);
PyObject *bases = PyTuple_New(1);
PyObject *dict = PyDict_New();
+ PyObject *item;
+
nameptr= RNA_property_string_get_alloc(ptr, nameprop, name, sizeof(name));
@@ -1544,6 +1547,12 @@ PyObject* pyrna_struct_Subtype(PointerRNA *ptr)
PyTuple_SET_ITEM(args, 1, bases);
// arg 3 - add an instance of the rna
+ if(descr) {
+ item= PyUnicode_FromString(descr);
+ PyDict_SetItemString(dict, "__doc__", item);
+ Py_DECREF(item);
+ }
+
PyTuple_SET_ITEM(args, 2, dict); // fill with useful subclass things!
if (PyErr_Occurred()) {
@@ -1552,23 +1561,19 @@ PyObject* pyrna_struct_Subtype(PointerRNA *ptr)
}
newclass = PyObject_CallObject((PyObject *)&PyType_Type, args);
- // Set this later
-
+ Py_DECREF(args);
if (newclass) {
- PyObject *rna;
RNA_struct_py_type_set(ptr->data, (void *)newclass); /* Store for later use */
/* Not 100% needed but useful,
* having an instance within a type looks wrong however this instance IS an rna type */
- rna = pyrna_struct_CreatePyObject(ptr);
- PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "__rna__", rna);
- Py_DECREF(rna);
+ item = pyrna_struct_CreatePyObject(ptr);
+ PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "__rna__", item);
+ Py_DECREF(item);
/* done with rna instance */
}
- Py_DECREF(args);
-
if (name != nameptr)
MEM_freeN(nameptr);
}