diff --git a/release/ui/buttons_objects.py b/release/ui/buttons_objects.py index 48c113a84ff..9e4cb9340a4 100644 --- a/release/ui/buttons_objects.py +++ b/release/ui/buttons_objects.py @@ -1,3 +1,4 @@ +import bpy class OBJECT_PT_transform(bpy.types.Panel): __label__ = "Transform" @@ -121,4 +122,3 @@ bpy.ui.addPanel(OBJECT_PT_groups, "BUTTONS_WINDOW", "WINDOW") bpy.ui.addPanel(OBJECT_PT_display, "BUTTONS_WINDOW", "WINDOW") bpy.ui.addPanel(OBJECT_PT_duplication, "BUTTONS_WINDOW", "WINDOW") bpy.ui.addPanel(OBJECT_PT_animation, "BUTTONS_WINDOW", "WINDOW") - diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h index f46ef0fa670..bb22432d90f 100644 --- a/source/blender/python/BPY_extern.h +++ b/source/blender/python/BPY_extern.h @@ -99,7 +99,7 @@ extern "C" { /* 2.5 UI Scripts */ int BPY_run_python_script( struct bContext *C, const char *filename, struct Text *text ); // 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(void); // int BPY_run_script_space_listener(struct bContext *C, struct SpaceScript * sc, struct ARegion *ar, struct wmNotifier *wmn); // 2.5 working 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" @@ -38,10 +39,29 @@ 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); +} + /***************************************************************************** * Description: This function creates a new Python dictionary object. *****************************************************************************/ - static PyObject *CreateGlobalDictionary( bContext *C ) { PyObject *mod; @@ -51,23 +71,11 @@ static PyObject *CreateGlobalDictionary( bContext *C ) 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, "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 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); } diff --git a/source/creator/creator.c b/source/creator/creator.c index 082f2395b3f..cb1fc18248f 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -529,7 +529,7 @@ int main(int argc, char **argv) */ BPY_post_start_python(); - BPY_run_ui_scripts(C); + BPY_run_ui_scripts(); #endif #ifdef WITH_QUICKTIME diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp index 324e5eae98a..ca30382b8c0 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp @@ -148,7 +148,7 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval) bool justreleased = false; bool active = false; - for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++) + for (int i=SCA_IInputDevice::KX_BEGINKEY ; i<= SCA_IInputDevice::KX_ENDKEY;i++) { const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i); switch (inevent.m_status) @@ -528,7 +528,7 @@ void SCA_KeyboardSensor::LogKeystrokes(void) int index = 0; /* Check on all keys whether they were pushed. This does not * untangle the ordering, so don't type too fast :) */ - for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++) + for (int i=SCA_IInputDevice::KX_BEGINKEY ; i<= SCA_IInputDevice::KX_ENDKEY;i++) { const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i); if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED) //NO_INPUTSTATUS) @@ -663,7 +663,7 @@ PyObject* SCA_KeyboardSensor::PyGetPressedKeys(PyObject* self, PyObject* args, P int index = 0; - for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++) + for (int i=SCA_IInputDevice::KX_BEGINKEY ; i<= SCA_IInputDevice::KX_ENDKEY;i++) { const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i); if ((inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED) @@ -704,7 +704,7 @@ SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice(); { int index = 0; - for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++) + for (int i=SCA_IInputDevice::KX_BEGINKEY ; i<= SCA_IInputDevice::KX_ENDKEY;i++) { const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i); if ( (inevent.m_status == SCA_InputEvent::KX_ACTIVE) @@ -737,7 +737,7 @@ KX_PYMETHODDEF_DOC_NOARGS(SCA_KeyboardSensor, getEventList, PyObject* resultlist = PyList_New(0); - for (int i=SCA_IInputDevice::KX_BEGINKEY ; i< SCA_IInputDevice::KX_ENDKEY;i++) + for (int i=SCA_IInputDevice::KX_BEGINKEY ; i<= SCA_IInputDevice::KX_ENDKEY;i++) { const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i); if (inevent.m_status != SCA_InputEvent::KX_NO_INPUTSTATUS)