From d7cabe7d6f4519856969137df415692e16a5372d Mon Sep 17 00:00:00 2001 From: Ines Almeida Date: Tue, 13 Jan 2015 11:43:22 +0100 Subject: BGE: python API cleanup - initialization for bge with submodules, closes D615 --- source/gameengine/Ketsji/KX_PythonInit.cpp | 114 ++++++++++++++++++----------- source/gameengine/Ketsji/KX_PythonInit.h | 1 + 2 files changed, 73 insertions(+), 42 deletions(-) diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 109e76cc94e..0b3e794f75e 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -2057,7 +2057,61 @@ void removeImportMain(struct Main *maggie) bpy_import_main_extra_remove(maggie); } -// Copied from bpy_interface.c + +PyDoc_STRVAR(BGE_module_documentation, + "This module contains submodules for the Blender Game Engine.\n" +); + +static struct PyModuleDef BGE_module_def = { + PyModuleDef_HEAD_INIT, + "bge", /* m_name */ + BGE_module_documentation, /* m_doc */ + 0, /* m_size */ + NULL, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; + +PyMODINIT_FUNC initBGE(void) +{ + PyObject *mod; + PyObject *submodule; + PyObject *sys_modules = PyThreadState_GET()->interp->modules; + + mod = PyModule_Create(&BGE_module_def); + + PyModule_AddObject(mod, "constraints", (submodule = initConstraintPythonBinding())); + PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule); + Py_INCREF(submodule); + + PyModule_AddObject(mod, "events", (submodule = initGameKeysPythonBinding())); + PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule); + Py_INCREF(submodule); + + PyModule_AddObject(mod, "logic", (submodule = initGameLogicPythonBinding())); + PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule); + Py_INCREF(submodule); + + PyModule_AddObject(mod, "render", (submodule = initRasterizerPythonBinding())); + PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule); + Py_INCREF(submodule); + + PyModule_AddObject(mod, "texture", (submodule = initVideoTexturePythonBinding())); + PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule); + Py_INCREF(submodule); + + /* GameTypes is initted *after* in initPyTypes() */ + PyModule_AddObject(mod, "types", (submodule = initGameTypesPythonBinding())); + PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule); + Py_INCREF(submodule); + + return mod; +} + + +/* minimal required blender modules to run blenderplayer */ static struct _inittab bge_internal_modules[] = { {"mathutils", PyInit_mathutils}, {"bgl", BPyInit_bgl}, @@ -2118,12 +2172,14 @@ PyObject *initGamePlayerPythonScripting(Main *maggie, int argc, char** argv) PySys_SetObject("argv", py_argv); Py_DECREF(py_argv); } - + /* Initialize thread support (also acquires lock) */ PyEval_InitThreads(); bpy_import_init(PyEval_GetBuiltins()); + PyDict_SetItemString(PyImport_GetModuleDict(), "bge", initBGE()); + /* mathutils types are used by the BGE even if we don't import them */ { PyObject *mod = PyImport_ImportModuleLevel("mathutils", NULL, NULL, NULL, 0); @@ -2138,12 +2194,12 @@ PyObject *initGamePlayerPythonScripting(Main *maggie, int argc, char** argv) } #endif - initPyTypes(); - bpy_import_main_set(maggie); - + initPySysObjects(maggie); - + + initPyTypes(); + first_time = false; PyObjectPlus::ClearDeprecationWarning(); @@ -2182,11 +2238,9 @@ void exitGamePlayerPythonScripting() */ PyObject *initGamePythonScripting(Main *maggie) { - /* not essential but nice to set our name */ - static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */ - BLI_strncpy_wchar_from_utf8(program_path_wchar, BKE_appdir_program_path(), ARRAY_SIZE(program_path_wchar)); - Py_SetProgramName(program_path_wchar); + /* no need to Py_SetProgramName, it was already taken care of in BPY_python_start */ + PyDict_SetItemString(PyImport_GetModuleDict(), "bge", initBGE()); #ifdef WITH_AUDASPACE /* accessing a SoundActuator's sound results in a crash if aud is not initialized... */ @@ -2233,7 +2287,12 @@ void exitGamePythonScripting() void setupGamePython(KX_KetsjiEngine* ketsjiengine, KX_Scene *startscene, Main *blenderdata, PyObject *pyGlobalDict, PyObject **gameLogic, PyObject **gameLogic_keys, int argc, char** argv) { - PyObject *dictionaryobject; + PyObject *modules, *dictionaryobject; + + gp_Canvas = ketsjiengine->GetCanvas(); + gp_Rasterizer = ketsjiengine->GetRasterizer(); + gp_KetsjiEngine = ketsjiengine; + gp_KetsjiScene = startscene; if (argv) /* player only */ dictionaryobject= initGamePlayerPythonScripting(blenderdata, argc, argv); @@ -2241,44 +2300,15 @@ void setupGamePython(KX_KetsjiEngine* ketsjiengine, KX_Scene *startscene, Main * dictionaryobject= initGamePythonScripting(blenderdata); ketsjiengine->SetPyNamespace(dictionaryobject); - gp_Canvas = ketsjiengine->GetCanvas(); - gp_Rasterizer = ketsjiengine->GetRasterizer(); - gp_KetsjiEngine = ketsjiengine; - gp_KetsjiScene = startscene; - initGameLogicPythonBinding(); - initRasterizerPythonBinding(); - initGameKeysPythonBinding(); - initConstraintPythonBinding(); - initVideoTexturePythonBinding(); + modules = PyImport_GetModuleDict(); - *gameLogic = PyDict_GetItemString(PyImport_GetModuleDict(), "GameLogic"); + *gameLogic = PyDict_GetItemString(modules, "GameLogic"); /* is set in initGameLogicPythonBinding so only set here if we want it to persist between scenes */ if (pyGlobalDict) PyDict_SetItemString(PyModule_GetDict(*gameLogic), "globalDict", pyGlobalDict); // Same as importing the module. *gameLogic_keys = PyDict_Keys(PyModule_GetDict(*gameLogic)); - - /* could be done a lot more nicely, but for now a quick way to get bge.* working */ - PyRun_SimpleString("sys = __import__('sys');" - "bge = type(sys)('bge');" - "bge.__dict__.update({'logic':__import__('GameLogic'), " - "'render':__import__('Rasterizer'), " - "'events':__import__('GameKeys'), " - "'constraints':__import__('PhysicsConstraints'), " - "'physics':__import__('PhysicsConstraints')," - "'types':__import__('GameTypes'), " - "'texture':__import__('VideoTexture')});" - /* so we can do 'import bge.foo as bar' */ - "sys.modules.update({'bge': bge, " - "'bge.logic':bge.logic, " - "'bge.render':bge.render, " - "'bge.events':bge.events, " - "'bge.constraints':bge.constraints, " - "'bge.physics':bge.physics," - "'bge.types':bge.types, " - "'bge.texture':bge.texture})" - ); } static struct PyModuleDef Rasterizer_module_def = { diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h index 8eaef342c5c..f74a4b3865f 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.h +++ b/source/gameengine/Ketsji/KX_PythonInit.h @@ -47,6 +47,7 @@ typedef enum { extern bool gUseVisibilityTemp; #ifdef WITH_PYTHON +PyMODINIT_FUNC initBGE(void); PyMODINIT_FUNC initGameLogicPythonBinding(void); PyMODINIT_FUNC initGameKeysPythonBinding(void); PyMODINIT_FUNC initRasterizerPythonBinding(void); -- cgit v1.2.3