From bc55102eac2ac0dfba8f32530ac674213aedc477 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 20 Oct 2008 23:21:01 +0000 Subject: renamed WITH_BF_BPYDOC to WITH_BF_DOCS, added SConscript for building BGE docs too. --- source/gameengine/PyDoc/SConscript | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 source/gameengine/PyDoc/SConscript (limited to 'source/gameengine') diff --git a/source/gameengine/PyDoc/SConscript b/source/gameengine/PyDoc/SConscript new file mode 100644 index 00000000000..3d1aa66bc69 --- /dev/null +++ b/source/gameengine/PyDoc/SConscript @@ -0,0 +1,28 @@ +#!/usr/bin/python +Import ('env') + + +from optparse import OptionParser +try: + import epydoc +except ImportError: + print "No epydoc install detected, Python API Docs will not be generated " +if epydoc: + from epydoc.docbuilder import build_doc_index + from epydoc import cli + names = env.Glob("source/gameengine/PyDoc/*.py") + docindex = build_doc_index(names) + optvalues = cli.OPTION_DEFAULTS + optvalues["verbose"] = 1 + optvalues["target"] = env["BF_DOCDIR"]+"/BGE_API/" + optvalues["url"] = "http://www.blender.org" + optvalues["top"] = "Game Engine API" + optvalues["name"] = "Blender" + optvalues["noprivate"] = 1 + optvalues["noframes"] = 1 + optvalues["names"] = names + optparser = OptionParser() + optparser.set_defaults(**optvalues) + (options, args) = optparser.parse_args() + cli.write_html(docindex, options) + -- cgit v1.2.3 From 59a30d822fe5ecfafbb5676b2058b7ff8d3760ed Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 22 Oct 2008 03:10:00 +0000 Subject: fix for [#17878] Scripts operating on blender objects don't clear memory after a crash This is an interesting bug since it is likely the cause of many other suspicious python crashes in blender. sys.last_traceback would store references to PyObjects at the point of the crash. it would only free these when sys.last_traceback was set again or on exit. This caused many crashes in the BGE while testing since python would end up freeing invalid game objects - When running scripts with errors, Blender would crash every 2-5 runs - in my test just now it crashed after 4 trys. It could also segfault blender, when (for eg) you run a script that has objects referenced. then load a new file and run another script that raises an error. In this case all the invalid Blender-Object's user counts would be decremented, even though none of the pointers were still valid. --- source/gameengine/GameLogic/SCA_PythonController.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source/gameengine') diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index 4cb9bc8fe53..1bbb93e0acc 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -262,6 +262,13 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) printf("Python compile error from controller \"%s\": \n", GetName().Ptr()); //PyRun_SimpleString(m_scriptText.Ptr()); PyErr_Print(); + + /* Added in 2.48a, the last_traceback can reference Objects for example, increasing + * their user count. Not to mention holding references to wrapped data. + * This is especially bad when the PyObject for the wrapped data is free'd, after blender + * has alredy dealocated the pointer */ + PySys_SetObject( "last_traceback", Py_None); + return; } m_bModified=false; @@ -298,6 +305,13 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) // something is wrong, tell the user what went wrong printf("Python script error from controller \"%s\": \n", GetName().Ptr()); PyErr_Print(); + + /* Added in 2.48a, the last_traceback can reference Objects for example, increasing + * their user count. Not to mention holding references to wrapped data. + * This is especially bad when the PyObject for the wrapped data is free'd, after blender + * has alredy dealocated the pointer */ + PySys_SetObject( "last_traceback", Py_None); + //PyRun_SimpleString(m_scriptText.Ptr()); } -- cgit v1.2.3 From 69c6bd604c36e06d704948bce1eb32134ac8971f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 22 Oct 2008 07:09:15 +0000 Subject: make sure BPY_Err_Handle clears python errors, even if the exception cant be printed. Added PyErr_Clear() incase there are other references to exception data (sys.exc_info() from python) --- source/gameengine/GameLogic/SCA_PythonController.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source/gameengine') diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index 1bbb93e0acc..c354ab39747 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -268,6 +268,7 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) * This is especially bad when the PyObject for the wrapped data is free'd, after blender * has alredy dealocated the pointer */ PySys_SetObject( "last_traceback", Py_None); + PyErr_Clear(); /* just to be sure */ return; } @@ -311,6 +312,7 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr) * This is especially bad when the PyObject for the wrapped data is free'd, after blender * has alredy dealocated the pointer */ PySys_SetObject( "last_traceback", Py_None); + PyErr_Clear(); /* just to be sure */ //PyRun_SimpleString(m_scriptText.Ptr()); } -- cgit v1.2.3 From 2e96728843d01fa0e8c79133b0e7f943930405de Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 27 Oct 2008 15:47:58 +0000 Subject: face transp option CLIP wasnt added to the py api. added gameObject.replaceMesh(meshname) - needed this for an automatically generated scene where 100's of objects would have needed logic bricks automatically added. Quicker to run replace mesh on all of them from 1 script. --- source/gameengine/Ketsji/KX_GameObject.cpp | 23 +++++++++++++++++++++++ source/gameengine/Ketsji/KX_GameObject.h | 1 + source/gameengine/PyDoc/KX_GameObject.py | 5 +++++ 3 files changed, 29 insertions(+) (limited to 'source/gameengine') diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 8b2feca53a3..739c122a5ef 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -998,6 +998,7 @@ PyMethodDef KX_GameObject::Methods[] = { {"getMesh", (PyCFunction)KX_GameObject::sPyGetMesh,METH_VARARGS}, {"getPhysicsId", (PyCFunction)KX_GameObject::sPyGetPhysicsId,METH_NOARGS}, {"getPropertyNames", (PyCFunction)KX_GameObject::sPyGetPropertyNames,METH_NOARGS}, + {"replaceMesh",(PyCFunction) KX_GameObject::sPyReplaceMesh, METH_O}, {"endObject",(PyCFunction) KX_GameObject::sPyEndObject, METH_NOARGS}, KX_PYMETHODTABLE(KX_GameObject, rayCastTo), KX_PYMETHODTABLE(KX_GameObject, rayCast), @@ -1024,6 +1025,28 @@ bool KX_GameObject::ConvertPythonVectorArgs(PyObject* args, } */ +PyObject* KX_GameObject::PyReplaceMesh(PyObject* self, PyObject* value) +{ + KX_Scene *scene = PHY_GetActiveScene(); + char* meshname; + void* mesh_pt; + + meshname = PyString_AsString(value); + if (meshname==NULL) { + PyErr_SetString(PyExc_ValueError, "Expected a mesh name"); + return NULL; + } + mesh_pt = SCA_ILogicBrick::m_sCurrentLogicManager->GetMeshByName(STR_String(meshname)); + + if (mesh_pt==NULL) { + PyErr_SetString(PyExc_ValueError, "The mesh name given does not exist"); + return NULL; + } + scene->ReplaceMesh(this, (class RAS_MeshObject*)mesh_pt); + + Py_RETURN_NONE; +} + PyObject* KX_GameObject::PyEndObject(PyObject* self) { diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 472d31362dd..20b15787d27 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -801,6 +801,7 @@ public: KX_PYMETHOD_VARARGS(KX_GameObject,GetMesh); KX_PYMETHOD_NOARGS(KX_GameObject,GetPhysicsId); KX_PYMETHOD_NOARGS(KX_GameObject,GetPropertyNames); + KX_PYMETHOD_O(KX_GameObject,ReplaceMesh); KX_PYMETHOD_NOARGS(KX_GameObject,EndObject); KX_PYMETHOD_DOC(KX_GameObject,rayCastTo); KX_PYMETHOD_DOC(KX_GameObject,rayCast); diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py index ff9b4ffc95b..505ce253dd1 100644 --- a/source/gameengine/PyDoc/KX_GameObject.py +++ b/source/gameengine/PyDoc/KX_GameObject.py @@ -30,6 +30,11 @@ class KX_GameObject: Delete this object, can be used inpace of the EndObject Actuator. The actual removal of the object from the scene is delayed. """ + def replaceMesh(mesh_name): + """ + Replace the mesh of this object with a new mesh. This works the same was as the actuator. + @type mesh_name: string + """ def getVisible(): """ Gets the game object's visible flag. -- cgit v1.2.3