Skip to content

Commit

Permalink
UPBGE: Cleanup python initialization.
Browse files Browse the repository at this point in the history
Previously python was created and initialized the same way for the
blenderplayer through the function setupGamePython. This caused that
when reloading the launcher because of game reload (same file or other file)
we had to take care to not call anything related to python, and the
management of the global dict in blenderplayer was harder.
Because of this difficulties the global dict wasn't shared between game
reload contrary to the shared behaviour in embedded player.

To solve this issue the python initialization and module initialization
is split in two functions: initPlayerPython for constructing python and
initGamePython to initialize a context with all the modules and the
previous global dict.

In the same time the prefix bpy_ is removed in BL_BlenderConverter, and
python joysticks, keyboard and mouse are now using std::unique_ptr
in KX_PythonInit.cpp.
  • Loading branch information
panzergame committed Dec 17, 2017
1 parent 77464fb commit c83d50e
Show file tree
Hide file tree
Showing 12 changed files with 97 additions and 212 deletions.
34 changes: 17 additions & 17 deletions source/gameengine/Converter/BL_BlenderConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,38 +372,38 @@ static void async_convert(TaskPool *pool, void *ptr, int UNUSED(threadid))

KX_LibLoadStatus *BL_BlenderConverter::LinkBlendFileMemory(void *data, int length, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
{
BlendHandle *bpy_openlib = BLO_blendhandle_from_memory(data, length);
BlendHandle *blendlib = BLO_blendhandle_from_memory(data, length);

// Error checking is done in LinkBlendFile
return LinkBlendFile(bpy_openlib, path, group, scene_merge, err_str, options);
return LinkBlendFile(blendlib, path, group, scene_merge, err_str, options);
}

KX_LibLoadStatus *BL_BlenderConverter::LinkBlendFilePath(const char *filepath, char *group, KX_Scene *scene_merge, char **err_str, short options)
{
BlendHandle *bpy_openlib = BLO_blendhandle_from_file(filepath, nullptr);
BlendHandle *blendlib = BLO_blendhandle_from_file(filepath, nullptr);

// Error checking is done in LinkBlendFile
return LinkBlendFile(bpy_openlib, filepath, group, scene_merge, err_str, options);
return LinkBlendFile(blendlib, filepath, group, scene_merge, err_str, options);
}

static void load_datablocks(Main *main_tmp, BlendHandle *bpy_openlib, const char *path, int idcode)
static void load_datablocks(Main *main_tmp, BlendHandle *blendlib, const char *path, int idcode)
{
LinkNode *names = nullptr;

int totnames_dummy;
names = BLO_blendhandle_get_datablock_names(bpy_openlib, idcode, &totnames_dummy);
names = BLO_blendhandle_get_datablock_names(blendlib, idcode, &totnames_dummy);

int i = 0;
LinkNode *n = names;
while (n) {
BLO_library_link_named_part(main_tmp, &bpy_openlib, idcode, (char *)n->link);
BLO_library_link_named_part(main_tmp, &blendlib, idcode, (char *)n->link);
n = (LinkNode *)n->next;
i++;
}
BLI_linklist_free(names, free); // free linklist *and* each node's data
}

KX_LibLoadStatus *BL_BlenderConverter::LinkBlendFile(BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
KX_LibLoadStatus *BL_BlenderConverter::LinkBlendFile(BlendHandle *blendlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
{
Main *main_newlib; // stored as a dynamic 'main' until we free it
const int idcode = BKE_idcode_from_name(group);
Expand All @@ -416,18 +416,18 @@ KX_LibLoadStatus *BL_BlenderConverter::LinkBlendFile(BlendHandle *bpy_openlib, c
if (idcode != ID_SCE && idcode != ID_ME && idcode != ID_AC) {
snprintf(err_local, sizeof(err_local), "invalid ID type given \"%s\"\n", group);
*err_str = err_local;
BLO_blendhandle_close(bpy_openlib);
BLO_blendhandle_close(blendlib);
return nullptr;
}

if (GetMainDynamicPath(path)) {
snprintf(err_local, sizeof(err_local), "blend file already open \"%s\"\n", path);
*err_str = err_local;
BLO_blendhandle_close(bpy_openlib);
BLO_blendhandle_close(blendlib);
return nullptr;
}

if (bpy_openlib == nullptr) {
if (blendlib == nullptr) {
snprintf(err_local, sizeof(err_local), "could not open blendfile \"%s\"\n", path);
*err_str = err_local;
return nullptr;
Expand All @@ -438,22 +438,22 @@ KX_LibLoadStatus *BL_BlenderConverter::LinkBlendFile(BlendHandle *bpy_openlib, c

short flag = 0; // don't need any special options
// created only for linking, then freed
Main *main_tmp = BLO_library_link_begin(main_newlib, &bpy_openlib, (char *)path);
Main *main_tmp = BLO_library_link_begin(main_newlib, &blendlib, (char *)path);

load_datablocks(main_tmp, bpy_openlib, path, idcode);
load_datablocks(main_tmp, blendlib, path, idcode);

if (idcode == ID_SCE && options & LIB_LOAD_LOAD_SCRIPTS) {
load_datablocks(main_tmp, bpy_openlib, path, ID_TXT);
load_datablocks(main_tmp, blendlib, path, ID_TXT);
}

// now do another round of linking for Scenes so all actions are properly loaded
if (idcode == ID_SCE && options & LIB_LOAD_LOAD_ACTIONS) {
load_datablocks(main_tmp, bpy_openlib, path, ID_AC);
load_datablocks(main_tmp, blendlib, path, ID_AC);
}

BLO_library_link_end(main_tmp, &bpy_openlib, flag, nullptr, nullptr);
BLO_library_link_end(main_tmp, &blendlib, flag, nullptr, nullptr);

BLO_blendhandle_close(bpy_openlib);
BLO_blendhandle_close(blendlib);

BKE_reports_clear(&reports);
// done linking
Expand Down
2 changes: 1 addition & 1 deletion source/gameengine/Converter/BL_BlenderConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ class BL_BlenderConverter

KX_LibLoadStatus *LinkBlendFileMemory(void *data, int length, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options);
KX_LibLoadStatus *LinkBlendFilePath(const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options);
KX_LibLoadStatus *LinkBlendFile(BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options);
KX_LibLoadStatus *LinkBlendFile(BlendHandle *blendlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options);

bool FreeBlendFile(Main *maggie);
bool FreeBlendFile(const std::string& path);
Expand Down
6 changes: 1 addition & 5 deletions source/gameengine/GameLogic/SCA_PythonController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,13 +368,9 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
*/

if (!m_pythondictionary) {
m_pythondictionary = PyDict_Copy(PyC_DefaultNameSpace(nullptr)); /* new reference */

/* Without __file__ set the sys.argv[0] is used for the filename
* which ends up with lines from the blender binary being printed in the console */
PyObject *value = PyUnicode_FromStdString(m_scriptName);
PyDict_SetItemString(m_pythondictionary, "__file__", value);
Py_DECREF(value);
m_pythondictionary = PyDict_Copy(PyC_DefaultNameSpace(m_scriptName.c_str())); /* new reference */
}

excdict= PyDict_Copy(m_pythondictionary);
Expand Down
37 changes: 16 additions & 21 deletions source/gameengine/GamePlayer/GPG_ghost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ extern "C"
#include "GPU_draw.h"

#include "KX_Globals.h"
#include "KX_PythonInit.h"

#include "LA_SystemCommandLine.h"
#include "LA_PlayerLauncher.h"
Expand Down Expand Up @@ -553,7 +554,7 @@ static void get_filename(int argc, char **argv, char *filename)
#endif // !_APPLE
}

static BlendFileData *load_game_data(const char *progname, char *filename = nullptr, char *relativename = nullptr)
static BlendFileData *load_game_data(const char *progname, char *filename = nullptr)
{
ReportList reports;
BlendFileData *bfd = nullptr;
Expand Down Expand Up @@ -1121,7 +1122,13 @@ int main(
// receive an event with the filename

system->processEvents(0);


#ifdef WITH_PYTHON
// Initialize python and the global dictionary.
initPlayerPython(argc, argv);
PyObject *globalDict = PyDict_New();
#endif // WITH_PYTHON

// this bracket is needed for app (see below) to get out
// of scope before GHOST_ISystem::disposeSystem() is called.
{
Expand All @@ -1141,10 +1148,6 @@ int main(
// those may change during the game and persist after using Game Actuator
GlobalSettings gs;

#ifdef WITH_PYTHON
PyObject *globalDict = nullptr;
#endif // WITH_PYTHON

do {
// Read the Blender file
BlendFileData *bfd;
Expand Down Expand Up @@ -1378,10 +1381,8 @@ int main(
// This argc cant be argc_py_clamped, since python uses it.
LA_PlayerLauncher launcher(system, window, maggie, scene, &gs, stereomode, aasamples,
argc, argv, pythonControllerFile);

#ifdef WITH_PYTHON
if (!globalDict) {
globalDict = PyDict_New();
}
launcher.SetPythonGlobalDict(globalDict);
#endif // WITH_PYTHON

Expand All @@ -1394,18 +1395,6 @@ int main(
exitstring = launcher.GetExitString();
gs = *launcher.GetGlobalSettings();

/* Delete the globalDict before free the launcher, because the launcher calls
* Py_Finalize() which disallow any python commands after.
*/
if (quitGame(exitcode)) {
#ifdef WITH_PYTHON
// If the globalDict is to nullptr then python is certainly not initialized.
if (globalDict) {
PyDict_Clear(globalDict);
Py_DECREF(globalDict);
}
#endif
}
launcher.ExitEngine();

BLO_blendfiledata_free(bfd);
Expand All @@ -1417,6 +1406,12 @@ int main(

GPU_exit();

#ifdef WITH_PYTHON
PyDict_Clear(globalDict);
Py_DECREF(globalDict);
exitPlayerPython();
#endif // WITH_PYTHON

// Seg Fault; icon.c gIcons == 0
BKE_icons_free();

Expand Down
Loading

0 comments on commit c83d50e

Please sign in to comment.