diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-04-19 16:46:39 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-04-19 16:46:39 +0400 |
commit | 8d2cb5bea44f4245dd17f2d82cbd0251d8090fd5 (patch) | |
tree | b28e45f1edaf083c15d2176079836a4497685e57 /source/gameengine/Ketsji | |
parent | 92cea7c1b1540d11ed9729bacfabd23ccb7a79c7 (diff) |
BGE Python API
This changes how the BGE classes and Python work together, which hasnt changed since blender went opensource.
The main difference is PyObjectPlus - the base class for most game engine classes, no longer inherit from PyObject, and cannot be cast to a PyObject.
This has the advantage that the BGE does not have to keep 2 reference counts valid for C++ and Python.
Previously C++ classes would never be freed while python held a reference, however this reference could be problematic eg: a GameObject that isnt in a scene anymore should not be used by python, doing so could even crash blender in some cases.
Instead PyObjectPlus has a member "PyObject *m_proxy" which is lazily initialized when python needs it. m_proxy reference counts are managed by python, though it should never be freed while the C++ class exists since it holds a reference to avoid making and freeing it all the time.
When the C++ class is free'd it sets the m_proxy reference to NULL, If python accesses this variable it will raise a RuntimeError, (check the isValid attribute to see if its valid without raising an error).
- This replaces the m_zombie bool and IsZombie() tests added recently.
In python return values that used to be..
return value->AddRef();
Are now
return value->GetProxy();
or...
return value->NewProxy(true); // true means python owns this C++ value which will be deleted when the PyObject is freed
Diffstat (limited to 'source/gameengine/Ketsji')
21 files changed, 163 insertions, 155 deletions
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp index 65600856377..8aca2e372d1 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp @@ -235,9 +235,9 @@ PyObject* KX_NetworkMessageSensor::pyattr_get_bodies(void *self_v, const KX_PYAT { KX_NetworkMessageSensor *self = static_cast<KX_NetworkMessageSensor*>(self_v); if (self->m_BodyList) { - return ((PyObject*) self->m_BodyList->AddRef()); + return self->m_BodyList->GetProxy(); } else { - return ((PyObject*) new CListValue()); + return (new CListValue())->NewProxy(true); } } @@ -245,9 +245,9 @@ PyObject* KX_NetworkMessageSensor::pyattr_get_subjects(void *self_v, const KX_PY { KX_NetworkMessageSensor *self = static_cast<KX_NetworkMessageSensor*>(self_v); if (self->m_SubjectList) { - return ((PyObject*) self->m_SubjectList->AddRef()); + return self->m_SubjectList->GetProxy(); } else { - return ((PyObject*) new CListValue()); + return (new CListValue())->NewProxy(true); } } @@ -290,9 +290,9 @@ PyObject* KX_NetworkMessageSensor::PyGetBodies( PyObject* ) { ShowDeprecationWarning("getBodies()", "bodies"); if (m_BodyList) { - return ((PyObject*) m_BodyList->AddRef()); + return m_BodyList->GetProxy(); } else { - return ((PyObject*) new CListValue()); + return (new CListValue())->NewProxy(true); } } @@ -316,9 +316,9 @@ PyObject* KX_NetworkMessageSensor::PyGetSubjects( PyObject* ) { ShowDeprecationWarning("getSubjects()", "subjects"); if (m_SubjectList) { - return ((PyObject*) m_SubjectList->AddRef()); + return m_SubjectList->GetProxy(); } else { - return ((PyObject*) new CListValue()); + return (new CListValue())->NewProxy(true); } } // <----- Deprecated
\ No newline at end of file diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 0e417dde5d2..bdad21f76eb 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -827,8 +827,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") m_flag &= ~RAS_BLENDERGLSL; mMaterial->SetSharedMaterial(true); mScene->GetBucketManager()->ReleaseDisplayLists(this); - Py_INCREF(mShader); - return mShader; + return mShader->GetProxy(); }else { // decref all references to the object @@ -836,13 +835,8 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()") // We will then go back to fixed functionality // for this material if(mShader) { - if(mShader->ob_refcnt > 1) { - Py_DECREF(mShader); - } - else { - delete mShader; - mShader=0; - } + delete mShader; /* will handle python de-referencing */ + mShader=0; } } Py_RETURN_NONE; diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp index 329d31cfa25..a1159dbc23f 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.cpp +++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp @@ -449,7 +449,7 @@ PyObject* KX_CameraActuator::PyGetObject(PyObject* self, PyObject* args) if (ret_name_only) return PyString_FromString(m_ob->GetName()); else - return m_ob->AddRef(); + return m_ob->GetProxy(); } /* set obj ---------------------------------------------------------- */ const char KX_CameraActuator::SetObject_doc[] = @@ -597,7 +597,7 @@ PyObject* KX_CameraActuator::pyattr_get_object(void *self_v, const KX_PYATTRIBUT if (self->m_ob==NULL) Py_RETURN_NONE; else - return self->m_ob->AddRef(); + return self->m_ob->GetProxy(); } int KX_CameraActuator::pyattr_set_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 3e7c99dc472..402c242315a 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1039,7 +1039,43 @@ void KX_GameObject::Suspend() } } +static void walk_children(SG_Node* node, CListValue* list, bool recursive) +{ + if (!node) + return; + NodeList& children = node->GetSGChildren(); + + for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit) + { + SG_Node* childnode = (*childit); + CValue* childobj = (CValue*)childnode->GetSGClientObject(); + if (childobj != NULL) // This is a GameObject + { + // add to the list + list->Add(childobj->AddRef()); + } + + // if the childobj is NULL then this may be an inverse parent link + // so a non recursive search should still look down this node. + if (recursive || childobj==NULL) { + walk_children(childnode, list, recursive); + } + } +} + +CListValue* KX_GameObject::GetChildren() +{ + CListValue* list = new CListValue(); + walk_children(GetSGNode(), list, 0); /* GetSGNode() is always valid or it would have raised an exception before this */ + return list; +} +CListValue* KX_GameObject::GetChildrenRecursive() +{ + CListValue* list = new CListValue(); + walk_children(GetSGNode(), list, 1); + return list; +} /* ------- python stuff ---------------------------------------------------*/ @@ -1185,13 +1221,10 @@ PyObject* KX_GameObject::PyGetPosition(PyObject* self) Py_ssize_t KX_GameObject::Map_Len(PyObject* self_v) { - KX_GameObject* self= static_cast<KX_GameObject*>(self_v); + KX_GameObject* self= static_cast<KX_GameObject*>BGE_PROXY_REF(self_v); - if (self->IsZombie()) /* not sure what to do here */ - { - PyErr_Clear(); + if (self==NULL) /* not sure what to do here */ return 0; - } Py_ssize_t len= self->GetPropertyCount(); if(self->m_attr_dict) @@ -1202,18 +1235,20 @@ Py_ssize_t KX_GameObject::Map_Len(PyObject* self_v) PyObject *KX_GameObject::Map_GetItem(PyObject *self_v, PyObject *item) { - KX_GameObject* self= static_cast<KX_GameObject*>(self_v); + KX_GameObject* self= static_cast<KX_GameObject*>BGE_PROXY_REF(self_v); const char *attr_str= PyString_AsString(item); CValue* resultattr; PyObject* pyconvert; - if (self->IsZombiePyErr()) + if (self==NULL) { + PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG); return NULL; + } /* first see if the attributes a string and try get the cvalue attribute */ if(attr_str && (resultattr=self->GetProperty(attr_str))) { pyconvert = resultattr->ConvertValueToPython(); - return pyconvert ? pyconvert:resultattr; + return pyconvert ? pyconvert:resultattr->GetProxy(); } /* no CValue attribute, try get the python only m_attr_dict attribute */ else if (self->m_attr_dict && (pyconvert=PyDict_GetItem(self->m_attr_dict, item))) { @@ -1234,13 +1269,15 @@ PyObject *KX_GameObject::Map_GetItem(PyObject *self_v, PyObject *item) int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val) { - KX_GameObject* self= static_cast<KX_GameObject*>(self_v); + KX_GameObject* self= static_cast<KX_GameObject*>BGE_PROXY_REF(self_v); const char *attr_str= PyString_AsString(key); if(attr_str==NULL) PyErr_Clear(); - if (self->IsZombiePyErr()) + if (self==NULL) { + PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG); return -1; + } if (val==NULL) { /* del ob["key"] */ int del= 0; @@ -1370,7 +1407,7 @@ PyObject* KX_GameObject::pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DE KX_GameObject* self= static_cast<KX_GameObject*>(self_v); KX_GameObject* parent = self->GetParent(); if (parent) - return parent->AddRef(); + return parent->GetProxy(); Py_RETURN_NONE; } @@ -1667,7 +1704,7 @@ PyObject* KX_GameObject::pyattr_get_meshes(void *self_v, const KX_PYATTRIBUTE_DE for(i=0; i < self->m_meshes.size(); i++) { KX_MeshProxy* meshproxy = new KX_MeshProxy(self->m_meshes[i]); - PyList_SET_ITEM(meshes, i, meshproxy); + PyList_SET_ITEM(meshes, i, meshproxy->GetProxy()); } return meshes; @@ -1681,7 +1718,7 @@ PyObject* KX_GameObject::pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_D PyObject* resultlist = PyList_New(sensors.size()); for (unsigned int index=0;index<sensors.size();index++) - PyList_SET_ITEM(resultlist, index, sensors[index]->AddRef()); + PyList_SET_ITEM(resultlist, index, sensors[index]->GetProxy()); return resultlist; } @@ -1693,7 +1730,7 @@ PyObject* KX_GameObject::pyattr_get_controllers(void *self_v, const KX_PYATTRIBU PyObject* resultlist = PyList_New(controllers.size()); for (unsigned int index=0;index<controllers.size();index++) - PyList_SET_ITEM(resultlist, index, controllers[index]->AddRef()); + PyList_SET_ITEM(resultlist, index, controllers[index]->GetProxy()); return resultlist; } @@ -1705,7 +1742,7 @@ PyObject* KX_GameObject::pyattr_get_actuators(void *self_v, const KX_PYATTRIBUTE PyObject* resultlist = PyList_New(actuators.size()); for (unsigned int index=0;index<actuators.size();index++) - PyList_SET_ITEM(resultlist, index, actuators[index]->AddRef()); + PyList_SET_ITEM(resultlist, index, actuators[index]->GetProxy()); return resultlist; } @@ -2083,28 +2120,17 @@ PyObject* KX_GameObject::PyGetParent(PyObject* self) ShowDeprecationWarning("getParent()", "the parent property"); KX_GameObject* parent = this->GetParent(); if (parent) - return parent->AddRef(); + return parent->GetProxy(); Py_RETURN_NONE; } PyObject* KX_GameObject::PySetParent(PyObject* self, PyObject* value) { - if (!PyObject_TypeCheck(value, &KX_GameObject::Type)) { - PyErr_SetString(PyExc_TypeError, "expected a KX_GameObject type"); + KX_GameObject *obj; + if (!ConvertPythonToGameObject(value, &obj, false)) return NULL; - } - if (self==value) { - PyErr_SetString(PyExc_ValueError, "cannot set the object to be its own parent!"); - return NULL; - } - // The object we want to set as parent - CValue *m_ob = (CValue*)value; - KX_GameObject *obj = ((KX_GameObject*)m_ob); - KX_Scene *scene = KX_GetActiveScene(); - - this->SetParent(scene, obj); - + this->SetParent(KX_GetActiveScene(), obj); Py_RETURN_NONE; } @@ -2115,43 +2141,14 @@ PyObject* KX_GameObject::PyRemoveParent(PyObject* self) Py_RETURN_NONE; } - -static void walk_children(SG_Node* node, CListValue* list, bool recursive) -{ - if (!node) - return; - NodeList& children = node->GetSGChildren(); - - for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit) - { - SG_Node* childnode = (*childit); - CValue* childobj = (CValue*)childnode->GetSGClientObject(); - if (childobj != NULL) // This is a GameObject - { - // add to the list - list->Add(childobj->AddRef()); - } - - // if the childobj is NULL then this may be an inverse parent link - // so a non recursive search should still look down this node. - if (recursive || childobj==NULL) { - walk_children(childnode, list, recursive); - } - } -} - PyObject* KX_GameObject::PyGetChildren(PyObject* self) { - CListValue* list = new CListValue(); - walk_children(GetSGNode(), list, 0); /* GetSGNode() is always valid or it would have raised an exception before this */ - return list; + return GetChildren()->NewProxy(true); } PyObject* KX_GameObject::PyGetChildrenRecursive(PyObject* self) { - CListValue* list = new CListValue(); - walk_children(GetSGNode(), list, 1); - return list; + return GetChildrenRecursive()->NewProxy(true); } PyObject* KX_GameObject::PyGetMesh(PyObject* self, PyObject* args) @@ -2166,7 +2163,7 @@ PyObject* KX_GameObject::PyGetMesh(PyObject* self, PyObject* args) if (((unsigned int)mesh < m_meshes.size()) && mesh >= 0) { KX_MeshProxy* meshproxy = new KX_MeshProxy(m_meshes[mesh]); - return meshproxy; + return meshproxy->NewProxy(true); // XXX Todo Python own. } Py_RETURN_NONE; @@ -2516,7 +2513,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo, KX_RayCast::RayTest(pe, fromPoint, toPoint, callback); if (m_pHitObject) - return m_pHitObject->AddRef(); + return m_pHitObject->GetProxy(); Py_RETURN_NONE; } @@ -2618,7 +2615,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast, { PyObject* returnValue = (poly) ? PyTuple_New(4) : PyTuple_New(3); if (returnValue) { // unlikely this would ever fail, if it does python sets an error - PyTuple_SET_ITEM(returnValue, 0, m_pHitObject->AddRef()); + PyTuple_SET_ITEM(returnValue, 0, m_pHitObject->GetProxy()); PyTuple_SET_ITEM(returnValue, 1, PyObjectFrom(callback.m_hitPoint)); PyTuple_SET_ITEM(returnValue, 2, PyObjectFrom(callback.m_hitNormal)); if (poly) @@ -2628,7 +2625,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast, // if this field is set, then we can trust that m_hitPolygon is a valid polygon RAS_Polygon* polygon = callback.m_hitMesh->GetPolygon(callback.m_hitPolygon); KX_PolyProxy* polyproxy = new KX_PolyProxy(callback.m_hitMesh, polygon); - PyTuple_SET_ITEM(returnValue, 3, polyproxy); + PyTuple_SET_ITEM(returnValue, 3, polyproxy->NewProxy(true)); } else { @@ -2708,7 +2705,7 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py } if (PyString_Check(value)) { - *object = (KX_GameObject *)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String( PyString_AsString(value) )); + *object = (KX_GameObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String( PyString_AsString(value) )); if (*object) { return true; @@ -2719,11 +2716,13 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py } if (PyObject_TypeCheck(value, &KX_GameObject::Type)) { - *object = static_cast<KX_GameObject*>(value); + *object = static_cast<KX_GameObject*>BGE_PROXY_REF(value); /* sets the error */ - if ((*object)->IsZombiePyErr()) + if (*object==NULL) { + PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG); return false; + } return true; } diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index dd85c2f2faa..89517bd76ce 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -807,6 +807,10 @@ public: } KX_ClientObjectInfo* getClientInfo() { return m_pClient_info; } + + CListValue* GetChildren(); + CListValue* GetChildrenRecursive(); + /** * @section Python interface functions. */ @@ -816,8 +820,6 @@ public: virtual int py_delattro(PyObject *attr); virtual PyObject* py_repr(void) { - if (IsZombiePyErr()) - return NULL; return PyString_FromString(GetName().ReadPtr()); } diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index 93d92480b3d..09e19933dd9 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -232,7 +232,7 @@ PyObject* KX_MeshProxy::PyGetVertex(PyObject* self, RAS_TexVert* vertex = m_meshobj->GetVertex(matindex,vertexindex); if (vertex) { - vertexob = new KX_VertexProxy(this, vertex); + vertexob = (new KX_VertexProxy(this, vertex))->NewProxy(true); } } else { @@ -263,7 +263,7 @@ PyObject* KX_MeshProxy::PyGetPolygon(PyObject* self, RAS_Polygon* polygon = m_meshobj->GetPolygon(polyindex); if (polygon) { - polyob = new KX_PolyProxy(m_meshobj, polygon); + polyob = (new KX_PolyProxy(m_meshobj, polygon))->NewProxy(true); } else { PyErr_SetString(PyExc_AttributeError, "polygon is NULL, unknown reason"); @@ -297,13 +297,11 @@ PyObject* KX_MeshProxy::pyattr_get_materials(void *self_v, const KX_PYATTRIBUTE_ if(polymat->GetFlag() & RAS_BLENDERMAT) { KX_BlenderMaterial *mat = static_cast<KX_BlenderMaterial*>(polymat); - PyList_SET_ITEM(materials, i, mat); - Py_INCREF(mat); + PyList_SET_ITEM(materials, i, mat->GetProxy()); } else { KX_PolygonMaterial *mat = static_cast<KX_PolygonMaterial*>(polymat); - PyList_SET_ITEM(materials, i, mat); - Py_INCREF(mat); + PyList_SET_ITEM(materials, i, mat->GetProxy()); } } return materials; diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp index 65190937f35..e1b89eb3095 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp @@ -396,7 +396,7 @@ PyObject* KX_MouseFocusSensor::PyGetHitObject(PyObject* self) ShowDeprecationWarning("GetHitObject()", "the hitObject property"); if (m_hitObject) - return m_hitObject->AddRef(); + return m_hitObject->GetProxy(); Py_RETURN_NONE; } @@ -487,7 +487,7 @@ PyObject* KX_MouseFocusSensor::pyattr_get_hit_object(void *self_v, const KX_PYAT KX_MouseFocusSensor* self= static_cast<KX_MouseFocusSensor*>(self_v); if(self->m_hitObject) - return self->m_hitObject->AddRef(); + return self->m_hitObject->GetProxy(); Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp index d0d441e2c1c..a667b459c22 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.cpp +++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp @@ -184,7 +184,7 @@ PyObject* KX_ParentActuator::pyattr_get_object(void *self, const struct KX_PYATT if (!actuator->m_ob) Py_RETURN_NONE; else - return actuator->m_ob->AddRef(); + return actuator->m_ob->GetProxy(); } int KX_ParentActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -261,7 +261,7 @@ PyObject* KX_ParentActuator::PyGetObject(PyObject* self, PyObject* args) if (ret_name_only) return PyString_FromString(m_ob->GetName()); else - return m_ob->AddRef(); + return m_ob->GetProxy(); } /* <----- */ diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp index e102ca4e0e6..c03d585395c 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.cpp +++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp @@ -109,14 +109,12 @@ PyObject* KX_PolyProxy::py_getattro(PyObject *attr) if(polymat->GetFlag() & RAS_BLENDERMAT) { KX_BlenderMaterial* mat = static_cast<KX_BlenderMaterial*>(polymat); - Py_INCREF(mat); - return mat; + return mat->GetProxy(); } else { KX_PolygonMaterial* mat = static_cast<KX_PolygonMaterial*>(polymat); - Py_INCREF(mat); - return mat; + return mat->GetProxy(); } } if (!strcmp(attr_str, "matid")) @@ -258,7 +256,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMesh, "getMesh() : returns a mesh proxy\n") { KX_MeshProxy* meshproxy = new KX_MeshProxy((RAS_MeshObject*)m_mesh); - return meshproxy; + return meshproxy->NewProxy(true); } KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterial, @@ -268,13 +266,11 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterial, if(polymat->GetFlag() & RAS_BLENDERMAT) { KX_BlenderMaterial* mat = static_cast<KX_BlenderMaterial*>(polymat); - Py_INCREF(mat); - return mat; + return mat->GetProxy(); } else { KX_PolygonMaterial* mat = static_cast<KX_PolygonMaterial*>(polymat); - Py_INCREF(mat); - return mat; + return mat->GetProxy(); } } diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index 056442f77d9..bf1fbe386e6 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -98,8 +98,7 @@ bool KX_PolygonMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingI { PyObject *pyRasty = PyCObject_FromVoidPtr((void*)rasty, NULL); /* new reference */ PyObject *pyCachingInfo = PyCObject_FromVoidPtr((void*) &cachingInfo, NULL); /* new reference */ - - PyObject *ret = PyObject_CallMethod(m_pymaterial, "activate", "(NNO)", pyRasty, pyCachingInfo, (PyObject*) this); + PyObject *ret = PyObject_CallMethod(m_pymaterial, "activate", "(NNO)", pyRasty, pyCachingInfo, (PyObject*) this->m_proxy); if (ret) { bool value = PyInt_AsLong(ret); diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp index 34c975f6bf6..2c65c184a9c 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -381,7 +381,7 @@ static PyObject* gPyGetVehicleConstraint(PyObject* self, if (vehicle) { KX_VehicleWrapper* pyWrapper = new KX_VehicleWrapper(vehicle,PHY_GetActiveEnvironment()); - return pyWrapper; + return pyWrapper->NewProxy(true); } } @@ -440,7 +440,7 @@ static PyObject* gPyCreateConstraint(PyObject* self, KX_ConstraintWrapper* wrap = new KX_ConstraintWrapper((enum PHY_ConstraintType)constrainttype,constraintid,PHY_GetActiveEnvironment()); - return wrap; + return wrap->NewProxy(true); } diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 7643a043a7c..1c3bb250b03 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -359,8 +359,7 @@ static STR_String gPyGetCurrentScene_doc = "Gets a reference to the current scene.\n"; static PyObject* gPyGetCurrentScene(PyObject* self) { - Py_INCREF(gp_KetsjiScene); - return (PyObject*) gp_KetsjiScene; + return gp_KetsjiScene->GetProxy(); } static STR_String gPyGetSceneList_doc = @@ -369,7 +368,6 @@ static STR_String gPyGetSceneList_doc = static PyObject* gPyGetSceneList(PyObject* self) { KX_KetsjiEngine* m_engine = KX_GetActiveEngine(); - //CListValue* list = new CListValue(); PyObject* list; KX_SceneList* scenes = m_engine->CurrentScenes(); int numScenes = scenes->size(); @@ -380,13 +378,10 @@ static PyObject* gPyGetSceneList(PyObject* self) for (i=0;i<numScenes;i++) { KX_Scene* scene = scenes->at(i); - //list->Add(scene); - PyList_SET_ITEM(list, i, scene); - Py_INCREF(scene); - + PyList_SET_ITEM(list, i, scene->GetProxy()); } - return (PyObject*)list; + return list; } static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *) diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp index 06163ec8c4f..2bf60dbc102 100644 --- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp +++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp @@ -98,7 +98,7 @@ void initPyObjectPlusType(PyTypeObject **parents) } #if 0 - PyObject_Print((PyObject *)parents[i], stderr, 0); + PyObject_Print(reinterpret_cast<PyObject *>parents[i], stderr, 0); fprintf(stderr, "\n"); PyObject_Print(parents[i]->tp_dict, stderr, 0); fprintf(stderr, "\n\n"); @@ -117,7 +117,7 @@ void initPyObjectPlusType(PyTypeObject **parents) dict= parents[i]->tp_dict; #if 1 - PyObject_Print((PyObject *)parents[i], stderr, 0); + PyObject_Print(reinterpret_cast<PyObject *>(parents[i]), stderr, 0); fprintf(stderr, "\n"); PyObject_Print(parents[i]->tp_dict, stderr, 0); fprintf(stderr, "\n\n"); @@ -135,7 +135,7 @@ static void PyType_Ready_ADD(PyObject *dict, PyTypeObject *tp, PyAttributeDef *a PyObject *item; PyType_Ready(tp); - PyDict_SetItemString(dict, tp->tp_name, (PyObject *)tp); + PyDict_SetItemString(dict, tp->tp_name, reinterpret_cast<PyObject *>(tp)); /* store attr defs in the tp_dict for to avoid string lookups */ for(attr= attributes; attr->m_name; attr++) { diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp index 42e2fdc3e14..9dfc8243330 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.cpp +++ b/source/gameengine/Ketsji/KX_RaySensor.cpp @@ -375,7 +375,7 @@ PyObject* KX_RaySensor::pyattr_get_hitobject(void *self_v, const KX_PYATTRIBUTE_ { KX_RaySensor* self = static_cast<KX_RaySensor*>(self_v); if (self->m_hitObject) - return self->m_hitObject->AddRef(); + return self->m_hitObject->GetProxy(); Py_RETURN_NONE; } @@ -389,7 +389,7 @@ PyObject* KX_RaySensor::PyGetHitObject(PyObject* self) ShowDeprecationWarning("getHitObject()", "the hitObject property"); if (m_hitObject) { - return m_hitObject->AddRef(); + return m_hitObject->GetProxy(); } Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp index 65b654ccba4..975e6d9d6cc 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp @@ -223,7 +223,7 @@ PyObject* KX_SCA_AddObjectActuator::pyattr_get_object(void *self, const struct K if (!actuator->m_OriginalObject) Py_RETURN_NONE; else - return actuator->m_OriginalObject->AddRef(); + return actuator->m_OriginalObject->GetProxy(); } int KX_SCA_AddObjectActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -251,7 +251,7 @@ PyObject* KX_SCA_AddObjectActuator::pyattr_get_objectLastCreated(void *self, con if (!actuator->m_lastCreatedObject) Py_RETURN_NONE; else - return actuator->m_lastCreatedObject->AddRef(); + return actuator->m_lastCreatedObject->GetProxy(); } @@ -350,7 +350,7 @@ PyObject* KX_SCA_AddObjectActuator::PyGetObject(PyObject* self, PyObject* args) if (ret_name_only) return PyString_FromString(m_OriginalObject->GetName()); else - return m_OriginalObject->AddRef(); + return m_OriginalObject->GetProxy(); } @@ -492,8 +492,7 @@ PyObject* KX_SCA_AddObjectActuator::PyGetLastCreatedObject(PyObject* self) // it means the object has ended, The BGE python api crashes in many places if the object is returned. if (result && (static_cast<KX_GameObject *>(result))->GetSGNode()) { - result->AddRef(); - return result; + return result->GetProxy(); } // don't return NULL to python anymore, it gives trouble in the scripts Py_RETURN_NONE; diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp index 9097ca6c85e..999b017b64c 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp @@ -110,7 +110,7 @@ PyObject* KX_SCA_ReplaceMeshActuator::pyattr_get_mesh(void *self, const struct K if (!actuator->m_mesh) Py_RETURN_NONE; KX_MeshProxy* meshproxy = new KX_MeshProxy(actuator->m_mesh); - return meshproxy; + return meshproxy->NewProxy(true); } int KX_SCA_ReplaceMeshActuator::pyattr_set_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index c99fa363ffe..d8d6f215213 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -924,8 +924,6 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj) { int ret; KX_GameObject* newobj = (KX_GameObject*) gameobj; - - gameobj->SetZombie(true); /* disallow future python access */ // keep the blender->game object association up to date // note that all the replicas of an object will have the same @@ -1623,13 +1621,13 @@ PyObject* KX_Scene::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attr PyObject* KX_Scene::pyattr_get_objects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_Scene* self= static_cast<KX_Scene*>(self_v); - return self->GetObjectList()->AddRef(); + return self->GetObjectList()->GetProxy(); } PyObject* KX_Scene::pyattr_get_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_Scene* self= static_cast<KX_Scene*>(self_v); - return self->GetActiveCamera()->AddRef(); + return self->GetActiveCamera()->GetProxy(); } /* __dict__ only for the purpose of giving useful dir() results */ @@ -1717,7 +1715,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getLightList, "Returns a list of all lights in the scene.\n" ) { - return (PyObject*) m_lightlist->AddRef(); + return m_lightlist->GetProxy(); } KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getObjectList, @@ -1726,7 +1724,7 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getObjectList, ) { // ShowDeprecationWarning("getObjectList()", "the objects property"); // XXX Grr, why doesnt this work? - return (PyObject*) m_objectlist->AddRef(); + return m_objectlist->GetProxy(); } KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getName, @@ -1755,6 +1753,5 @@ KX_PYMETHODDEF_DOC(KX_Scene, addObject, SCA_IObject* replica = AddReplicaObject((SCA_IObject*)ob, other, time); - replica->AddRef(); - return replica; + return replica->GetProxy(); }
\ No newline at end of file diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp index 2d3022a68f7..b52cc81f68b 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.cpp +++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp @@ -291,23 +291,39 @@ PyObject* KX_SceneActuator::pyattr_get_camera(void *self, const struct KX_PYATTR KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self); if (!actuator->m_camera) Py_RETURN_NONE; - actuator->m_camera->AddRef(); - return actuator->m_camera; + + return actuator->m_camera->GetProxy(); } int KX_SceneActuator::pyattr_set_camera(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) { KX_SceneActuator* actuator = static_cast<KX_SceneActuator*>(self); KX_Camera *camOb; - + + if(value==Py_None) + { + if (actuator->m_camera) + actuator->m_camera->UnregisterActuator(actuator); + + actuator->m_camera= NULL; + return 0; + } + if (PyObject_TypeCheck(value, &KX_Camera::Type)) { - camOb = static_cast<KX_Camera*>(value); + KX_Camera *camOb= static_cast<KX_Camera*>BGE_PROXY_REF(value); + + if(camOb==NULL) + { + PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG); + return 1; + } + if (actuator->m_camera) actuator->m_camera->UnregisterActuator(actuator); + actuator->m_camera = camOb; - if (actuator->m_camera) - actuator->m_camera->RegisterActuator(actuator); + actuator->m_camera->RegisterActuator(actuator); return 0; } @@ -423,11 +439,21 @@ PyObject* KX_SceneActuator::PySetCamera(PyObject* self, PyObject *cam; if (PyArg_ParseTuple(args, "O!:setCamera", &KX_Camera::Type, &cam)) { + KX_Camera *new_camera; + + new_camera = static_cast<KX_Camera*>BGE_PROXY_REF(cam); + if(new_camera==NULL) + { + PyErr_SetString(PyExc_RuntimeError, BGE_PROXY_ERROR_MSG); + return NULL; + } + if (m_camera) m_camera->UnregisterActuator(this); - m_camera = (KX_Camera*) cam; - if (m_camera) - m_camera->RegisterActuator(this); + + m_camera= new_camera; + + m_camera->RegisterActuator(this); Py_RETURN_NONE; } PyErr_Clear(); diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp index 70fa6326c19..7265ade6789 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.cpp +++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp @@ -342,7 +342,7 @@ PyObject* KX_TouchSensor::PyGetHitObject(PyObject* self) /* otherwise, this leaks memory */ if (m_hitObject) { - return m_hitObject->AddRef(); + return m_hitObject->GetProxy(); } Py_RETURN_NONE; } @@ -356,7 +356,7 @@ PyObject* KX_TouchSensor::PyGetHitObjectList(PyObject* self) ShowDeprecationWarning("getHitObjectList()", "the objectHitList property"); /* to do: do Py_IncRef if the object is already known in Python */ /* otherwise, this leaks memory */ /* Edit, this seems ok and not to leak memory - Campbell */ - return m_colliders->AddRef(); + return m_colliders->GetProxy(); } /*getTouchMaterial and setTouchMaterial were never added to the api, @@ -400,7 +400,7 @@ PyObject* KX_TouchSensor::pyattr_get_object_hit(void *self_v, const KX_PYATTRIBU KX_TouchSensor* self= static_cast<KX_TouchSensor*>(self_v); if (self->m_hitObject) - return self->m_hitObject->AddRef(); + return self->m_hitObject->GetProxy(); else Py_RETURN_NONE; } @@ -408,7 +408,7 @@ PyObject* KX_TouchSensor::pyattr_get_object_hit(void *self_v, const KX_PYATTRIBU PyObject* KX_TouchSensor::pyattr_get_object_hit_list(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_TouchSensor* self= static_cast<KX_TouchSensor*>(self_v); - return self->m_colliders->AddRef(); + return self->m_colliders->GetProxy(); } diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp index 29c6a21b0b3..5ea08f855a3 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp +++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp @@ -481,7 +481,7 @@ PyObject* KX_TrackToActuator::pyattr_get_object(void *self, const struct KX_PYAT if (!actuator->m_object) Py_RETURN_NONE; else - return actuator->m_object->AddRef(); + return actuator->m_object->GetProxy(); } int KX_TrackToActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) @@ -560,7 +560,7 @@ PyObject* KX_TrackToActuator::PyGetObject(PyObject* self, PyObject* args) if (ret_name_only) return PyString_FromString(m_object->GetName()); else - return m_object->AddRef(); + return m_object->GetProxy(); } diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp index 98f5a1ea87d..0ba55fe5986 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp @@ -48,7 +48,10 @@ PyObject* KX_VehicleWrapper::PyAddWheel(PyObject* self, if (PyArg_ParseTuple(args,"OOOOffi:addWheel",&wheelGameObject,&pylistPos,&pylistDir,&pylistAxleDir,&suspensionRestLength,&wheelRadius,&hasSteering)) { - KX_GameObject* gameOb = (KX_GameObject*) wheelGameObject; + KX_GameObject *gameOb; + if (!ConvertPythonToGameObject(wheelGameObject, &gameOb, false)) + return NULL; + if (gameOb->GetSGNode()) { |