diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-04-30 03:39:27 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-04-30 03:39:27 +0400 |
commit | 1e7df5851959db6822bdc2a71b83aa533b0ec117 (patch) | |
tree | 11eed5eee6c03d3c1dfe88c2c714ec66d1965b37 | |
parent | 537b0803798674501634c4dfbaeedb97b2ee889c (diff) |
python modules in the game engine could point to builtin modules like GameLogic that was cleared.
I added module clearing before there was checks for invalid python objects, so now its not needed for BGE Builtin types at least.
also made the builtin modules get re-used if they already exist and clear all user modules when the game engine finishes so with Module-Py-Controllers the referenced modules are at least up to date when pressing Pkey.
-rw-r--r-- | source/blender/python/api2_2x/bpy_internal_import.c | 11 | ||||
-rw-r--r-- | source/blender/python/api2_2x/bpy_internal_import.h | 2 | ||||
-rw-r--r-- | source/gameengine/Expressions/InputParser.cpp | 16 | ||||
-rw-r--r-- | source/gameengine/Expressions/Value.cpp | 16 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_PyConstraintBinding.cpp | 15 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_PythonInit.cpp | 69 | ||||
-rw-r--r-- | source/gameengine/VideoTexture/blendVideoTex.cpp | 22 |
7 files changed, 119 insertions, 32 deletions
diff --git a/source/blender/python/api2_2x/bpy_internal_import.c b/source/blender/python/api2_2x/bpy_internal_import.c index 1e1454dcd5c..125993cc425 100644 --- a/source/blender/python/api2_2x/bpy_internal_import.c +++ b/source/blender/python/api2_2x/bpy_internal_import.c @@ -272,7 +272,12 @@ PyMethodDef bpy_reload_meth[] = { {"bpy_reload_meth", blender_reload, METH_VARAR * Its also needed for the BGE Python api so imported scripts are not used between levels * * This clears every modules that has a __file__ attribute (is not a builtin) - * and is a filename only (no path). since pythons bultins include a full path even for win32. + * + * Note that clearing external python modules is important for the BGE otherwise + * it wont reload scripts between loading different blend files or while making the game. + * - use 'clear_all' arg in this case. + * + * Since pythons bultins include a full path even for win32. * even if we remove a python module a reimport will bring it back again. */ @@ -284,7 +289,7 @@ PyMethodDef bpy_reload_meth[] = { {"bpy_reload_meth", blender_reload, METH_VARAR #endif -void bpy_text_clear_modules(void) +void bpy_text_clear_modules(int clear_all) { PyObject *modules= PySys_GetObject("modules"); @@ -309,7 +314,7 @@ void bpy_text_clear_modules(void) while (PyDict_Next(modules, &pos, &key, &value)) { fname= PyModule_GetFilename(value); if(fname) { - if ((strstr(fname, SEPSTR))==0) { /* no path ? */ + if (clear_all || ((strstr(fname, SEPSTR))==0)) { /* no path ? */ file_extension = strstr(fname, ".py"); if(file_extension && *(file_extension + 3) == '\0') { /* .py extension ? */ /* now we can be fairly sure its a python import from the blendfile */ diff --git a/source/blender/python/api2_2x/bpy_internal_import.h b/source/blender/python/api2_2x/bpy_internal_import.h index 137818bb0db..7220212f13e 100644 --- a/source/blender/python/api2_2x/bpy_internal_import.h +++ b/source/blender/python/api2_2x/bpy_internal_import.h @@ -37,7 +37,7 @@ PyObject* bpy_text_import( char *name, int *found ); PyObject* bpy_text_reimport( PyObject *module, int *found ); -void bpy_text_clear_modules( void ); /* Clear user modules */ +void bpy_text_clear_modules( int clear_all ); /* Clear user modules */ extern PyMethodDef bpy_import_meth[]; extern PyMethodDef bpy_reload_meth[]; diff --git a/source/gameengine/Expressions/InputParser.cpp b/source/gameengine/Expressions/InputParser.cpp index d45a9375dc7..834faf70aae 100644 --- a/source/gameengine/Expressions/InputParser.cpp +++ b/source/gameengine/Expressions/InputParser.cpp @@ -676,11 +676,23 @@ static struct PyModuleDef Expression_module_def = { extern "C" { void initExpressionModule(void) { + PyObject *m; + /* Use existing module where possible + * be careful not to init any runtime vars after this */ + m = PyImport_ImportModule( "Expression" ); + if(m) { + Py_DECREF(m); + return m; + } + else { + PyErr_Clear(); + #if (PY_VERSION_HEX >= 0x03000000) - PyModule_Create(&Expression_module_def); + PyModule_Create(&Expression_module_def); #else - Py_InitModule("Expression",CParserMethods); + Py_InitModule("Expression",CParserMethods); #endif + } } } diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index fbd86cc4022..373924301ae 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -773,11 +773,23 @@ static struct PyModuleDef CValue_module_def = { extern "C" { void initCValue(void) { + PyObject *m; + /* Use existing module where possible + * be careful not to init any runtime vars after this */ + m = PyImport_ImportModule( "CValue" ); + if(m) { + Py_DECREF(m); + return m; + } + else { + PyErr_Clear(); + #if (PY_VERSION_HEX >= 0x03000000) - PyModule_Create(&CValue_module_def); + PyModule_Create(&CValue_module_def); #else - Py_InitModule("CValue",CValueMethods); + Py_InitModule("CValue",CValueMethods); #endif + } } } diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp index e801e9c5858..0f21b24489d 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -586,13 +586,24 @@ PyObject* initPythonConstraintBinding() PyObject* m; PyObject* d; + /* Use existing module where possible + * be careful not to init any runtime vars after this */ + m = PyImport_ImportModule( "PhysicsConstraints" ); + if(m) { + Py_DECREF(m); + return m; + } + else { + PyErr_Clear(); + #if (PY_VERSION_HEX >= 0x03000000) - m = PyModule_Create(&PhysicsConstraints_module_def); + m = PyModule_Create(&PhysicsConstraints_module_def); #else - m = Py_InitModule4("PhysicsConstraints", physicsconstraints_methods, + m = Py_InitModule4("PhysicsConstraints", physicsconstraints_methods, PhysicsConstraints_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); #endif + } // Add some symbolic constants to the module d = PyModule_GetDict(m); diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 22e092e8277..22960eaed2c 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -1098,16 +1098,28 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack gUseVisibilityTemp=false; - // Create the module and add the functions + + /* Use existing module where possible + * be careful not to init any runtime vars after this */ + m = PyImport_ImportModule( "GameLogic" ); + if(m) { + Py_DECREF(m); + return m; + } + else { + PyErr_Clear(); + + // Create the module and add the functions #if (PY_VERSION_HEX >= 0x03000000) - m = PyModule_Create(&GameLogic_module_def); + m = PyModule_Create(&GameLogic_module_def); #else - m = Py_InitModule4("GameLogic", game_methods, - GameLogic_module_documentation, - (PyObject*)NULL,PYTHON_API_VERSION); + m = Py_InitModule4("GameLogic", game_methods, + GameLogic_module_documentation, + (PyObject*)NULL,PYTHON_API_VERSION); #endif - + } + // Add some symbolic constants to the module d = PyModule_GetDict(m); @@ -1562,8 +1574,7 @@ PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLev bpy_import_main_set(maggie); - /* run this to clear game modules and user modules which - * may contain references to in game data */ + /* clear user defined modules that may contain data from the last run */ clearGameModules(); PyObject* moduleobj = PyImport_AddModule("__main__"); @@ -1583,6 +1594,8 @@ static void clearModule(PyObject *modules, const char *name) static void clearGameModules() { + /* references to invalid BGE data is better supported in 2.49+ so dont clear dicts */ +#if 0 /* Note, user modules could still reference these modules * but since the dict's are cleared their members wont be accessible */ @@ -1597,9 +1610,10 @@ static void clearGameModules() clearModule(modules, "Mathutils"); clearModule(modules, "BGL"); PyErr_Clear(); // incase some of these were alredy removed. +#endif - /* clear user defined modules */ - bpy_text_clear_modules(); + /* clear user defined modules, arg '1' for clear external py modules too */ + bpy_text_clear_modules(1); } void exitGamePythonScripting() @@ -1633,14 +1647,25 @@ PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas) PyObject* d; PyObject* item; - // Create the module and add the functions + /* Use existing module where possible + * be careful not to init any runtime vars after this */ + m = PyImport_ImportModule( "Rasterizer" ); + if(m) { + Py_DECREF(m); + return m; + } + else { + PyErr_Clear(); + + // Create the module and add the functions #if (PY_VERSION_HEX >= 0x03000000) - m = PyModule_Create(&Rasterizer_module_def); + m = PyModule_Create(&Rasterizer_module_def); #else - m = Py_InitModule4("Rasterizer", rasterizer_methods, + m = Py_InitModule4("Rasterizer", rasterizer_methods, Rasterizer_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); #endif + } // Add some symbolic constants to the module d = PyModule_GetDict(m); @@ -1756,15 +1781,25 @@ PyObject* initGameKeys() PyObject* m; PyObject* d; PyObject* item; - - // Create the module and add the functions + + /* Use existing module where possible */ + m = PyImport_ImportModule( "GameKeys" ); + if(m) { + Py_DECREF(m); + return m; + } + else { + PyErr_Clear(); + + // Create the module and add the functions #if (PY_VERSION_HEX >= 0x03000000) - m = PyModule_Create(&GameKeys_module_def); + m = PyModule_Create(&GameKeys_module_def); #else - m = Py_InitModule4("GameKeys", gamekeys_methods, + m = Py_InitModule4("GameKeys", gamekeys_methods, GameKeys_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); #endif + } // Add some symbolic constants to the module d = PyModule_GetDict(m); diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index 8b2a9dc2a5d..239f43763b8 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -192,13 +192,24 @@ PyObject* initVideoTexture(void) if (PyType_Ready(&TextureType) < 0) return NULL; + /* Use existing module where possible + * be careful not to init any runtime vars after this */ + m = PyImport_ImportModule( "VideoTexture" ); + if(m) { + Py_DECREF(m); + return m; + } + else { + PyErr_Clear(); + #if (PY_VERSION_HEX >= 0x03000000) - m = PyModule_Create(&VideoTexture_module_def); + m = PyModule_Create(&VideoTexture_module_def); #else - m = Py_InitModule4("VideoTexture", moduleMethods, - "Module that allows to play video files on textures in GameBlender.", - (PyObject*)NULL,PYTHON_API_VERSION); + m = Py_InitModule4("VideoTexture", moduleMethods, + "Module that allows to play video files on textures in GameBlender.", + (PyObject*)NULL,PYTHON_API_VERSION); #endif + } if (m == NULL) return NULL; @@ -209,9 +220,10 @@ PyObject* initVideoTexture(void) Py_INCREF(&TextureType); PyModule_AddObject(m, (char*)"Texture", (PyObject*)&TextureType); - + // init last error description Exception::m_lastError[0] = '\0'; + return m; } |