diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 4af5ac4d5d2..b3a3a47152a 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -332,6 +332,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, ketsjiengine->SetPythonDictionary(dictionaryobject); initRasterizer(rasterizer, canvas); PyObject *gameLogic = initGameLogic(startscene); + PyDict_SetItemString(dictionaryobject, "GameLogic", gameLogic); // Same as importing the module. initGameKeys(); initPythonConstraintBinding(); @@ -399,7 +400,14 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, exitstring = ketsjiengine->GetExitString(); // when exiting the mainloop - dictionaryClearByHand(gameLogic); + + // 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(gameLogic)); + ketsjiengine->StopEngine(); exitGamePythonScripting(); networkdevice->Disconnect(); @@ -591,6 +599,7 @@ extern "C" void StartKetsjiShellSimulation(struct ScrArea *area, ketsjiengine->SetPythonDictionary(dictionaryobject); initRasterizer(rasterizer, canvas); PyObject *gameLogic = initGameLogic(startscene); + PyDict_SetItemString(dictionaryobject, "GameLogic", gameLogic); // Same as importing the module initGameKeys(); initPythonConstraintBinding(); diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index 76386079bdf..01ae4072335 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -116,7 +116,7 @@ CValue* SCA_PythonController::GetReplica() void SCA_PythonController::SetScriptText(const STR_String& text) { - m_scriptText = "import GameLogic\n" + text; + m_scriptText = text; m_bModified = true; } @@ -354,8 +354,10 @@ SCA_PythonController::PyGetSensor(PyObject* self, PyObject* value) return sensor->AddRef(); } } - - PyErr_SetString(PyExc_AttributeError, "Unable to find requested sensor"); + + char emsg[96]; + PyOS_snprintf( emsg, sizeof( emsg ), "Unable to find requested sensor \"%s\"", scriptArg ); + PyErr_SetString(PyExc_AttributeError, emsg); return NULL; } @@ -382,8 +384,10 @@ SCA_PythonController::PyGetActuator(PyObject* self, PyObject* value) return actua->AddRef(); } } - - PyErr_SetString(PyExc_AttributeError, "Unable to find requested actuator"); + + char emsg[96]; + PyOS_snprintf( emsg, sizeof( emsg ), "Unable to find requested actuator \"%s\"", scriptArg ); + PyErr_SetString(PyExc_AttributeError, emsg); return NULL; } diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp index d6908b53d40..b5ebffb9378 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp @@ -644,7 +644,7 @@ bool GPG_Application::startEngine(void) PyObject* dictionaryobject = initGamePlayerPythonScripting("Ketsji", psl_Lowest); m_ketsjiengine->SetPythonDictionary(dictionaryobject); initRasterizer(m_rasterizer, m_canvas); - PyObject *gameLogic = initGameLogic(startscene); + PyDict_SetItemString(dictionaryobject, "GameLogic", initGameLogic(startscene)); // Same as importing the module initGameKeys(); initPythonConstraintBinding(); diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 20187a193ba..db099d56b55 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -231,7 +231,10 @@ void KX_KetsjiEngine::SetRasterizer(RAS_IRasterizer* rasterizer) } - +/* + * At the moment the GameLogic module is imported into 'pythondictionary' after this function is called. + * if this function ever changes to assign a copy, make sure the game logic module is imported into this dictionary before hand. + */ void KX_KetsjiEngine::SetPythonDictionary(PyObject* pythondictionary) { MT_assert(pythondictionary); diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 433e0636833..61ed8b6a8e4 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -828,20 +828,9 @@ PyObject* initGameLogic(KX_Scene* scene) // quick hack to get gravity hook Py_FatalError("can't initialize module GameLogic"); } - return d; + return m; } -void dictionaryClearByHand(PyObject *dict) -{ - // 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 - if(dict) PyDict_Clear(dict); -} - - // Python Sandbox code // override builtin functions import() and open() diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h index c7d8f1b78bc..41cf7fd67b3 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.h +++ b/source/gameengine/Ketsji/KX_PythonInit.h @@ -47,7 +47,6 @@ PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur void exitGamePlayerPythonScripting(); PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level); void exitGamePythonScripting(); -void dictionaryClearByHand(PyObject *dict); void PHY_SetActiveScene(class KX_Scene* scene); class KX_Scene* PHY_GetActiveScene(); diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index 949156571a7..34a3baec093 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -291,7 +291,8 @@ PyObject* KX_SoundActuator::PyGetFilename(PyObject* self, PyObject* args, PyObje char* name = objectname.Ptr(); if (!name) { - Py_Return; /* internal error */ + PyErr_SetString(PyExc_RuntimeError, "Unable to get sound filename"); + return NULL; } else return PyString_FromString(name); }