Skip to content

Commit

Permalink
UPBGE: Fix reference counting of module items.
Browse files Browse the repository at this point in the history
The item passed to PyDict_SetItemString will be incref, so if the item
is constructed in the current scope and not stored in an external data,
the item must be decref.

These rules are applied to KX_PythonInit.cpp and remove the usage of
PyDict_Clear in LA_Launcher.
  • Loading branch information
panzergame committed Dec 17, 2017
1 parent ab265f6 commit 77464fb
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 24 deletions.
17 changes: 11 additions & 6 deletions source/gameengine/Ketsji/KX_PythonInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1452,6 +1452,7 @@ PyMODINIT_FUNC initGameLogicPythonBinding()
PyList_SET_ITEM(joylist, i, Py_None);
}
PyDict_SetItemString(d, "joysticks", joylist);
Py_DECREF(joylist);

ErrorObject = PyUnicode_FromString("GameLogic.error");
PyDict_SetItemString(d, "error", ErrorObject);
Expand Down Expand Up @@ -2057,7 +2058,9 @@ void initGamePlayerPythonScripting(Main *maggie, int argc, char** argv)
}
#endif

PyDict_SetItemString(PyImport_GetModuleDict(), "bge", initBGE());
PyObject *mod = initBGE();
PyDict_SetItemString(PyImport_GetModuleDict(), "bge", mod);
Py_DECREF(mod);

first_time = false;

Expand Down Expand Up @@ -2109,7 +2112,9 @@ void initGamePythonScripting(Main *maggie)
}
#endif

PyDict_SetItemString(PyImport_GetModuleDict(), "bge", initBGE());
PyObject *mod = initBGE();
PyDict_SetItemString(PyImport_GetModuleDict(), "bge", mod);
Py_DECREF(mod);

EXP_PyObjectPlus::NullDeprecationWarning();
}
Expand Down Expand Up @@ -2137,8 +2142,7 @@ void exitGamePythonScripting()

/* similar to the above functions except it sets up the namespace
* and other more general things */
void setupGamePython(KX_KetsjiEngine* ketsjiengine, Main *blenderdata,
PyObject *pyGlobalDict, PyObject **gameLogic, int argc, char** argv)
void setupGamePython(KX_KetsjiEngine* ketsjiengine, Main *blenderdata, PyObject *pyGlobalDict, int argc, char** argv)
{
PyObject *modules;

Expand All @@ -2149,10 +2153,11 @@ void setupGamePython(KX_KetsjiEngine* ketsjiengine, Main *blenderdata,

modules = PyImport_GetModuleDict();

*gameLogic = PyDict_GetItemString(modules, "GameLogic");
PyObject *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.z
PyDict_SetItemString(PyModule_GetDict(gameLogic), "globalDict", pyGlobalDict); // Same as importing the module.z
Py_DECREF(gameLogic);
}

void createPythonConsole()
Expand Down
3 changes: 1 addition & 2 deletions source/gameengine/Ketsji/KX_PythonInit.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ void appendPythonPath(const std::string& path);

void exitGamePlayerPythonScripting();
void exitGamePythonScripting();
void setupGamePython(KX_KetsjiEngine *ketsjiengine, Main *blenderdata,
PyObject *pyGlobalDict, PyObject **gameLogic, int argc, char **argv);
void setupGamePython(KX_KetsjiEngine *ketsjiengine, Main *blenderdata, PyObject *pyGlobalDict, int argc, char **argv);
std::string pathGamePythonConfig();
void saveGamePythonConfig();
void loadGamePythonConfig();
Expand Down
16 changes: 1 addition & 15 deletions source/gameengine/Launcher/LA_Launcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ LA_Launcher::LA_Launcher(GHOST_ISystem *system, Main *maggie, Scene *scene, Glob
m_converter(nullptr),
#ifdef WITH_PYTHON
m_globalDict(nullptr),
m_gameLogic(nullptr),
#endif // WITH_PYTHON
m_samples(samples),
m_stereoMode(stereoMode),
Expand Down Expand Up @@ -276,7 +275,7 @@ void LA_Launcher::InitEngine()
#ifdef WITH_PYTHON
KX_SetMainPath(std::string(m_maggie->name));
// Some python things.
setupGamePython(m_ketsjiEngine, m_maggie, m_globalDict, &m_gameLogic, m_argc, m_argv);
setupGamePython(m_ketsjiEngine, m_maggie, m_globalDict, m_argc, m_argv);
#endif // WITH_PYTHON

// Create a scene converter, create and convert the stratingscene.
Expand Down Expand Up @@ -325,19 +324,6 @@ void LA_Launcher::ExitEngine()
DEV_Joystick::Close();
m_ketsjiEngine->StopEngine();

#ifdef WITH_PYTHON

/* Clears the dictionary by hand:
* This prevents, extra references to global variables
* inside the GameLogic dictionary when the python interpreter is finalized.
* which allows the scene to safely delete them :)
* see: (space.c)->start_game
*/

PyDict_Clear(PyModule_GetDict(m_gameLogic));

#endif // WITH_PYTHON

// Do we will stop ?
if ((m_exitRequested != KX_ExitRequest::RESTART_GAME) && (m_exitRequested != KX_ExitRequest::START_OTHER_GAME)) {
// Then set the cursor back to normal here to avoid set the cursor visible between two game load.
Expand Down
1 change: 0 additions & 1 deletion source/gameengine/Launcher/LA_Launcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ class LA_Launcher

#ifdef WITH_PYTHON
PyObject *m_globalDict;
PyObject *m_gameLogic;
#endif // WITH_PYTHON

/// The number of render samples.
Expand Down
1 change: 1 addition & 0 deletions source/gameengine/VideoTexture/blendVideoTex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ PyMODINIT_FUNC initVideoTexturePythonBinding(void)
pyImageTypes.reg(m);
pyFilterTypes.reg(m);

Py_INCREF(&Texture::Type);
PyModule_AddObject(m, "Texture", (PyObject *)&Texture::Type);
#ifdef WITH_GAMEENGINE_DECKLINK
Py_INCREF(&DeckLinkType);
Expand Down

0 comments on commit 77464fb

Please sign in to comment.