diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-04-06 12:17:04 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-04-06 12:17:04 +0400 |
commit | c10d1c28532e238f418244df7c994c212634114a (patch) | |
tree | ae4fbed9502b06c68e5e1f2a6347535a8add0554 /source | |
parent | a95f97cb2832296fc02cb2cb236cbb69d51a3cf1 (diff) |
Python ref-counting fixes
Diffstat (limited to 'source')
-rw-r--r-- | source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp | 4 | ||||
-rw-r--r-- | source/gameengine/Ketsji/BL_Shader.h | 1 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_PyConstraintBinding.cpp | 1 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_PythonInit.cpp | 73 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Scene.cpp | 2 |
5 files changed, 65 insertions, 16 deletions
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 1d4cd011fe4..9228798890a 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -527,7 +527,9 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, SND_DeviceManager::Unsubscribe(); } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME); - + + Py_DECREF(pyGlobalDict); + if (bfd) BLO_blendfiledata_free(bfd); BLI_strncpy(G.sce, oldsce, sizeof(G.sce)); diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h index 490c0268a6d..08cad5071fd 100644 --- a/source/gameengine/Ketsji/BL_Shader.h +++ b/source/gameengine/Ketsji/BL_Shader.h @@ -203,6 +203,7 @@ public: // Python interface virtual PyObject* py_getattro(PyObject *attr); + virtual PyObject* py_repr(void) { return PyString_FromFormat("BL_Shader\n\tvertex shader:%s\n\n\tfragment shader%s\n\n", vertProg, fragProg); } // ----------------------------------- KX_PYMETHOD_DOC( BL_Shader, setSource ); diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp index fb37eded450..34c975f6bf6 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -582,6 +582,7 @@ PyObject* initPythonConstraintBinding() d = PyModule_GetDict(m); ErrorObject = PyString_FromString("PhysicsConstraints.error"); PyDict_SetItemString(d, "error", ErrorObject); + Py_DECREF(ErrorObject); // XXXX Add constants here diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index ef7655f38a2..73342d891d8 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -113,9 +113,9 @@ void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,cons /* Macro for building the keyboard translation */ //#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyInt_FromLong(SCA_IInputDevice::KX_##name)) -#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyInt_FromLong(name)) +#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, item=PyInt_FromLong(name)); Py_DECREF(item) /* For the defines for types from logic bricks, we do stuff explicitly... */ -#define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, PyInt_FromLong(name2)) +#define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, item=PyInt_FromLong(name2)); Py_DECREF(item) // temporarily python stuff, will be put in another place later ! @@ -916,26 +916,41 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack { PyObject* m; PyObject* d; - + PyObject* item; /* temp PyObject* storage */ + gp_KetsjiEngine = engine; gp_KetsjiScene = scene; gUseVisibilityTemp=false; // Create the module and add the functions - m = Py_InitModule4("GameLogic", game_methods, + + + m = PyImport_ImportModule("GameLogic"); + + if(m==NULL) { + printf("Import for the first time!\n"); + PyErr_Clear(); + m = Py_InitModule4("GameLogic", game_methods, GameLogic_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); - + } + else { + Py_DECREF(m); /**/ + printf("Alredy imported!\n"); + return(m); + } // Add some symbolic constants to the module d = PyModule_GetDict(m); // can be overwritten later for gameEngine instances that can load new blend files and re-initialize this module // for now its safe to make sure it exists for other areas such as the web plugin - PyDict_SetItemString(d, "globalDict", PyDict_New()); + + PyDict_SetItemString(d, "globalDict", item=PyDict_New()); Py_DECREF(item); ErrorObject = PyString_FromString("GameLogic.error"); PyDict_SetItemString(d, "error", ErrorObject); + Py_DECREF(ErrorObject); // XXXX Add constants here /* To use logic bricks, we need some sort of constants. Here, we associate */ @@ -1225,18 +1240,18 @@ void setSandbox(TPythonSecurityLevel level) { PyObject *m = PyImport_AddModule("__builtin__"); PyObject *d = PyModule_GetDict(m); - + PyObject *item; switch (level) { case psl_Highest: //if (!g_security) { //g_oldopen = PyDict_GetItemString(d, "open"); // functions we cant trust - PyDict_SetItemString(d, "open", PyCFunction_New(meth_open, NULL)); - PyDict_SetItemString(d, "reload", PyCFunction_New(meth_reload, NULL)); - PyDict_SetItemString(d, "file", PyCFunction_New(meth_file, NULL)); - PyDict_SetItemString(d, "execfile", PyCFunction_New(meth_execfile, NULL)); - PyDict_SetItemString(d, "compile", PyCFunction_New(meth_compile, NULL)); + PyDict_SetItemString(d, "open", item=PyCFunction_New(meth_open, NULL)); Py_DECREF(item); + PyDict_SetItemString(d, "reload", item=PyCFunction_New(meth_reload, NULL)); Py_DECREF(item); + PyDict_SetItemString(d, "file", item=PyCFunction_New(meth_file, NULL)); Py_DECREF(item); + PyDict_SetItemString(d, "execfile", item=PyCFunction_New(meth_execfile, NULL)); Py_DECREF(item); + PyDict_SetItemString(d, "compile", item=PyCFunction_New(meth_compile, NULL)); Py_DECREF(item); // our own import PyDict_SetItemString(d, "__import__", PyCFunction_New(meth_import, NULL)); @@ -1266,8 +1281,8 @@ void setSandbox(TPythonSecurityLevel level) */ default: /* Allow importing internal text, from bpy_internal_import.py */ - PyDict_SetItemString(d, "reload", PyCFunction_New(bpy_reload, NULL)); - PyDict_SetItemString(d, "__import__", PyCFunction_New(bpy_import, NULL)); + PyDict_SetItemString(d, "reload", item=PyCFunction_New(bpy_reload, NULL)); Py_DECREF(item); + PyDict_SetItemString(d, "__import__", item=PyCFunction_New(bpy_import, NULL)); Py_DECREF(item); break; } } @@ -1296,6 +1311,7 @@ PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur void exitGamePlayerPythonScripting() { + //clearGameModules(); // were closing python anyway Py_Finalize(); bpy_import_main_set(NULL); } @@ -1319,10 +1335,36 @@ PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLev return PyModule_GetDict(moduleobj); } +static void clearModule(PyObject *modules, const char *name) +{ + PyObject *mod= PyDict_GetItemString(modules, name); + + if (mod==NULL) + return; + + PyDict_Clear(PyModule_GetDict(mod)); /* incase there are any circular refs */ + PyDict_DelItemString(modules, name); +} +static void clearGameModules() +{ + /* Note, user modules could still reference these modules + * but since the dict's are cleared their members wont be accessible */ + + PyObject *modules= PySys_GetObject("modules"); + clearModule(modules, "Expression"); + clearModule(modules, "CValue"); + clearModule(modules, "PhysicsConstraints"); + clearModule(modules, "GameLogic"); + clearModule(modules, "Rasterizer"); + clearModule(modules, "GameKeys"); + clearModule(modules, "VideoTexture"); + PyErr_Clear(); // incase some of these were alredy removed. +} void exitGamePythonScripting() { + clearGameModules(); bpy_import_main_set(NULL); } @@ -1336,6 +1378,7 @@ PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas) PyObject* m; PyObject* d; + PyObject* item; // Create the module and add the functions m = Py_InitModule4("Rasterizer", rasterizer_methods, @@ -1346,6 +1389,7 @@ PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas) d = PyModule_GetDict(m); ErrorObject = PyString_FromString("Rasterizer.error"); PyDict_SetItemString(d, "error", ErrorObject); + Py_DECREF(ErrorObject); /* needed for get/setMaterialType */ KX_MACRO_addTypesToDict(d, KX_TEXFACE_MATERIAL, KX_TEXFACE_MATERIAL); @@ -1414,6 +1458,7 @@ PyObject* initGameKeys() { PyObject* m; PyObject* d; + PyObject* item; // Create the module and add the functions m = Py_InitModule4("GameKeys", gamekeys_methods, diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 254717894df..72f2fd9827f 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -244,7 +244,7 @@ KX_Scene::~KX_Scene() { delete m_bucketmanager; } - //Py_DECREF(m_attrlist); + Py_DECREF(m_attrlist); } void KX_Scene::SetProjectionMatrix(MT_CmMatrix4x4& pmat) |