Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2009-04-19 16:46:39 +0400
committerCampbell Barton <ideasman42@gmail.com>2009-04-19 16:46:39 +0400
commit8d2cb5bea44f4245dd17f2d82cbd0251d8090fd5 (patch)
treeb28e45f1edaf083c15d2176079836a4497685e57
parent92cea7c1b1540d11ed9729bacfabd23ccb7a79c7 (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
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp2
-rw-r--r--source/gameengine/Expressions/InputParser.cpp2
-rw-r--r--source/gameengine/Expressions/ListValue.cpp67
-rw-r--r--source/gameengine/Expressions/ListValue.h4
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.cpp69
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.h137
-rw-r--r--source/gameengine/Expressions/Value.cpp11
-rw-r--r--source/gameengine/Expressions/Value.h16
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.cpp3
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.cpp16
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp16
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp12
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp135
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h6
-rw-r--r--source/gameengine/Ketsji/KX_MeshProxy.cpp10
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_ParentActuator.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_PolyProxy.cpp14
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.cpp3
-rw-r--r--source/gameengine/Ketsji/KX_PyConstraintBinding.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp11
-rw-r--r--source/gameengine/Ketsji/KX_PythonInitTypes.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp9
-rw-r--r--source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp13
-rw-r--r--source/gameengine/Ketsji/KX_SceneActuator.cpp44
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.cpp8
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_VehicleWrapper.cpp5
-rw-r--r--source/gameengine/VideoTexture/FilterSource.h3
-rw-r--r--source/gameengine/VideoTexture/ImageRender.cpp23
33 files changed, 377 insertions, 294 deletions
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 792a3e309f3..9f214721c82 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -2354,7 +2354,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
// Remove the child reference in the local list!
// Note: there may be descendents already if the children of the child were processed
// by this loop before the child. In that case, we must remove the children also
- CListValue* childrenlist = (CListValue*)childobj->PyGetChildrenRecursive(childobj);
+ CListValue* childrenlist = childobj->GetChildrenRecursive();
childrenlist->Add(childobj->AddRef());
for ( i=0;i<childrenlist->GetCount();i++)
{
diff --git a/source/gameengine/Expressions/InputParser.cpp b/source/gameengine/Expressions/InputParser.cpp
index 1698f1919d1..66075dd8d42 100644
--- a/source/gameengine/Expressions/InputParser.cpp
+++ b/source/gameengine/Expressions/InputParser.cpp
@@ -649,7 +649,7 @@ PyObject* CParserPyMake(PyObject* ignored,PyObject* args)
CExpression* expr = parser.ProcessText(txt);
CValue* val = expr->Calculate();
expr->Release();
- return val;
+ return val->GetProxy();
}
static PyMethodDef CParserMethods[] =
diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp
index 37feba38f8b..eaed2b5c400 100644
--- a/source/gameengine/Expressions/ListValue.cpp
+++ b/source/gameengine/Expressions/ListValue.cpp
@@ -27,45 +27,61 @@
#define Py_ssize_t int
#endif
-Py_ssize_t listvalue_bufferlen(PyObject* list)
+Py_ssize_t listvalue_bufferlen(PyObject* self)
{
- return (Py_ssize_t)( ((CListValue*)list)->GetCount());
+ CListValue *list= static_cast<CListValue *>(BGE_PROXY_REF(self));
+ if (list==NULL)
+ return 0;
+
+ return (Py_ssize_t)list->GetCount();
}
-PyObject* listvalue_buffer_item(PyObject* list,Py_ssize_t index)
+PyObject* listvalue_buffer_item(PyObject* self, Py_ssize_t index)
{
- int count = ((CListValue*) list)->GetCount();
+ CListValue *list= static_cast<CListValue *>(BGE_PROXY_REF(self));
+ if (list==NULL) {
+ PyErr_SetString(PyExc_IndexError, BGE_PROXY_ERROR_MSG);
+ return NULL;
+ }
+
+ int count = list->GetCount();
if (index < 0)
index = count+index;
if (index >= 0 && index < count)
{
- PyObject* pyobj = ((CListValue*) list)->GetValue(index)->ConvertValueToPython();
+ PyObject* pyobj = list->GetValue(index)->ConvertValueToPython();
if (pyobj)
return pyobj;
else
- return ((CListValue*) list)->GetValue(index)->AddRef();
+ return list->GetValue(index)->GetProxy();
}
PyErr_SetString(PyExc_IndexError, "Python ListIndex out of range");
return NULL;
}
-PyObject* listvalue_mapping_subscript(PyObject* list,PyObject* pyindex)
+PyObject* listvalue_mapping_subscript(PyObject* self, PyObject* pyindex)
{
+ CListValue *list= static_cast<CListValue *>(BGE_PROXY_REF(self));
+ if (list==NULL) {
+ PyErr_SetString(PyExc_IndexError, BGE_PROXY_ERROR_MSG);
+ return NULL;
+ }
+
if (PyString_Check(pyindex))
{
STR_String index(PyString_AsString(pyindex));
CValue *item = ((CListValue*) list)->FindValue(index);
if (item)
- return (PyObject*) item;
+ return item->GetProxy();
}
if (PyInt_Check(pyindex))
{
int index = PyInt_AsLong(pyindex);
- return listvalue_buffer_item(list, index);
+ return listvalue_buffer_item(self, index);
}
PyObject *pyindex_str = PyObject_Repr(pyindex); /* new ref */
@@ -76,10 +92,16 @@ PyObject* listvalue_mapping_subscript(PyObject* list,PyObject* pyindex)
/* just slice it into a python list... */
-PyObject* listvalue_buffer_slice(PyObject* list,Py_ssize_t ilow, Py_ssize_t ihigh)
+PyObject* listvalue_buffer_slice(PyObject* self,Py_ssize_t ilow, Py_ssize_t ihigh)
{
+ CListValue *list= static_cast<CListValue *>(BGE_PROXY_REF(self));
+ if (list==NULL) {
+ PyErr_SetString(PyExc_IndexError, BGE_PROXY_ERROR_MSG);
+ return NULL;
+ }
+
int i, j;
- PyListObject *newlist;
+ PyObject *newlist;
if (ilow < 0) ilow = 0;
@@ -90,18 +112,18 @@ PyObject* listvalue_buffer_slice(PyObject* list,Py_ssize_t ilow, Py_ssize_t ihig
if (ihigh < ilow)
ihigh = ilow;
- newlist = (PyListObject *) PyList_New(ihigh - ilow);
+ newlist = PyList_New(ihigh - ilow);
if (!newlist)
return NULL;
for (i = ilow, j = 0; i < ihigh; i++, j++)
{
- PyObject* pyobj = ((CListValue*) list)->GetValue(i)->ConvertValueToPython();
+ PyObject* pyobj = list->GetValue(i)->ConvertValueToPython();
if (!pyobj)
- pyobj = ((CListValue*) list)->GetValue(i)->AddRef();
- newlist->ob_item[j] = pyobj;
+ pyobj = list->GetValue(i)->GetProxy();
+ PyList_SET_ITEM(newlist, i, pyobj);
}
- return (PyObject *) newlist;
+ return newlist;
}
@@ -109,11 +131,16 @@ PyObject* listvalue_buffer_slice(PyObject* list,Py_ssize_t ilow, Py_ssize_t ihig
static PyObject *
listvalue_buffer_concat(PyObject * self, PyObject * other)
{
+ CListValue *listval= static_cast<CListValue *>(BGE_PROXY_REF(self));
+ if (listval==NULL) {
+ PyErr_SetString(PyExc_IndexError, BGE_PROXY_ERROR_MSG);
+ return NULL;
+ }
+
// for now, we support CListValue concatenated with items
// and CListValue concatenated to Python Lists
// and CListValue concatenated with another CListValue
-
- CListValue* listval = (CListValue*) self;
+
listval->AddRef();
if (other->ob_type == &PyList_Type)
{
@@ -519,8 +546,8 @@ PyObject* CListValue::Pyfrom_id(PyObject* self, PyObject* value)
int numelem = GetCount();
for (int i=0;i<numelem;i++)
{
- if (reinterpret_cast<BGE_ID_TYPE>(static_cast<PyObject*>(m_pValueArray[i])) == id)
- return GetValue(i);
+ if (reinterpret_cast<BGE_ID_TYPE>(m_pValueArray[i]->m_proxy) == id)
+ return GetValue(i)->GetProxy();
}
PyErr_SetString(PyExc_IndexError, "from_id(#), id not found in CValueList");
diff --git a/source/gameengine/Expressions/ListValue.h b/source/gameengine/Expressions/ListValue.h
index cf2976c2bbb..2af5a330c43 100644
--- a/source/gameengine/Expressions/ListValue.h
+++ b/source/gameengine/Expressions/ListValue.h
@@ -61,9 +61,11 @@ public:
virtual PyObject* py_getattro(PyObject* attr);
virtual PyObject* py_repr(void) {
- PyObject *py_list= PySequence_List((PyObject *)this);
+ PyObject *py_proxy= this->GetProxy();
+ PyObject *py_list= PySequence_List(py_proxy);
PyObject *py_string= PyObject_Repr(py_list);
Py_DECREF(py_list);
+ Py_DECREF(py_proxy);
return py_string;
}
diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp
index 0db2e8991fc..2c5ba3f39fc 100644
--- a/source/gameengine/Expressions/PyObjectPlus.cpp
+++ b/source/gameengine/Expressions/PyObjectPlus.cpp
@@ -54,6 +54,7 @@
* PyObjectPlus Type -- Every class, even the abstract one should have a Type
------------------------------*/
+
PyTypeObject PyObjectPlus::Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
@@ -74,21 +75,33 @@ PyTypeObject PyObjectPlus::Type = {
Methods
};
+
PyObjectPlus::~PyObjectPlus()
{
- if (ob_refcnt)
- {
- _Py_ForgetReference(this);
+ if(m_proxy) {
+ Py_DECREF(m_proxy); /* Remove own reference, python may still have 1 */
+ BGE_PROXY_REF(m_proxy)= NULL;
}
// assert(ob_refcnt==0);
}
+void PyObjectPlus::PyDestructor(PyObject *self) // python wrapper
+{
+ PyObjectPlus *self_plus= BGE_PROXY_REF(self);
+ if(self_plus) {
+ if(BGE_PROXY_PYOWNS(self)) { /* Does python own this?, then delete it */
+ delete self_plus;
+ }
+
+ BGE_PROXY_REF(self)= NULL; // not really needed
+ }
+ PyObject_DEL( self );
+};
+
PyObjectPlus::PyObjectPlus(PyTypeObject *T) // constructor
{
MT_assert(T != NULL);
- this->ob_type = T;
- _Py_NewReference(this);
- SetZombie(false);
+ m_proxy= NULL;
};
/*------------------------------
@@ -131,7 +144,7 @@ PyObject *PyObjectPlus::py_getattro(PyObject* attr)
if (PyCObject_Check(descr)) {
return py_get_attrdef((void *)this, (const PyAttributeDef*)PyCObject_AsVoidPtr(descr));
} else if (descr->ob_type->tp_descr_get) {
- return PyCFunction_New(((PyMethodDescrObject *)descr)->d_method, (PyObject *)this);
+ return PyCFunction_New(((PyMethodDescrObject *)descr)->d_method, this->m_proxy);
} else {
fprintf(stderr, "Unknown attribute type (PyObjectPlus::py_getattro)");
return descr;
@@ -794,5 +807,47 @@ PyObject *py_getattr_dict(PyObject *pydict, PyObject *tp_dict)
return pydict;
}
+
+
+PyObject *PyObjectPlus::GetProxy_Ext(PyObjectPlus *self, PyTypeObject *tp)
+{
+ if (self->m_proxy==NULL)
+ {
+ self->m_proxy = reinterpret_cast<PyObject *>PyObject_NEW( PyObjectPlus_Proxy, tp);
+ BGE_PROXY_PYOWNS(self->m_proxy) = false;
+ }
+ //PyObject_Print(self->m_proxy, stdout, 0);
+ //printf("ref %d\n", self->m_proxy->ob_refcnt);
+
+ BGE_PROXY_REF(self->m_proxy) = self; /* Its possible this was set to NULL, so set it back here */
+ Py_INCREF(self->m_proxy); /* we own one, thos ones fore the return */
+ return self->m_proxy;
+}
+
+PyObject *PyObjectPlus::NewProxy_Ext(PyObjectPlus *self, PyTypeObject *tp, bool py_owns)
+{
+ if (self->m_proxy)
+ {
+ if(py_owns)
+ { /* Free */
+ BGE_PROXY_REF(self->m_proxy) = NULL;
+ Py_DECREF(self->m_proxy);
+ self->m_proxy= NULL;
+ }
+ else {
+ Py_INCREF(self->m_proxy);
+ return self->m_proxy;
+ }
+
+ }
+
+ GetProxy_Ext(self, tp);
+ if(py_owns) {
+ BGE_PROXY_PYOWNS(self->m_proxy) = py_owns;
+ Py_DECREF(self->m_proxy); /* could avoid thrashing here but for now its ok */
+ }
+ return self->m_proxy;
+}
+
#endif //NO_EXP_PYTHON_EMBEDDING
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h
index 58a74e4ca74..3be9a2f2bcb 100644
--- a/source/gameengine/Expressions/PyObjectPlus.h
+++ b/source/gameengine/Expressions/PyObjectPlus.h
@@ -81,6 +81,20 @@ static inline void Py_Fatal(const char *M) {
exit(-1);
};
+typedef struct {
+ PyObject_HEAD /* required python macro */
+ class PyObjectPlus *ref;
+ bool py_owns;
+} PyObjectPlus_Proxy;
+
+#define BGE_PROXY_ERROR_MSG "Blender Game Engine data has been freed, cannot use this python variable"
+#define BGE_PROXY_REF(_self) (((PyObjectPlus_Proxy *)_self)->ref)
+#define BGE_PROXY_PYOWNS(_self) (((PyObjectPlus_Proxy *)_self)->py_owns)
+
+/* Note, sometimes we dont care what BGE type this is as long as its a proxy */
+#define BGE_PROXY_CHECK_TYPE(_self) ((_self)->ob_type->tp_dealloc == PyDestructor)
+
+
// This must be the first line of each
// PyC++ class
#define Py_Header \
@@ -90,7 +104,10 @@ static inline void Py_Fatal(const char *M) {
static PyAttributeDef Attributes[]; \
static PyParentObject Parents[]; \
virtual PyTypeObject *GetType(void) {return &Type;}; \
- virtual PyParentObject *GetParents(void) {return Parents;}
+ virtual PyParentObject *GetParents(void) {return Parents;} \
+ virtual PyObject *GetProxy() {return GetProxy_Ext(this, &Type);}; \
+ virtual PyObject *NewProxy(bool py_owns) {return NewProxy_Ext(this, &Type, py_owns);}; \
+
@@ -106,7 +123,7 @@ static inline void Py_Fatal(const char *M) {
if (PyCObject_Check(descr)) { \
return py_get_attrdef((void *)this, (const PyAttributeDef*)PyCObject_AsVoidPtr(descr)); \
} else if (descr->ob_type->tp_descr_get) { \
- return PyCFunction_New(((PyMethodDescrObject *)descr)->d_method, (PyObject *)this); \
+ return PyCFunction_New(((PyMethodDescrObject *)descr)->d_method, this->m_proxy); \
} else { \
fprintf(stderr, "unknown attribute type"); \
return descr; \
@@ -165,52 +182,60 @@ static inline void Py_Fatal(const char *M) {
#define KX_PYMETHOD(class_name, method_name) \
PyObject* Py##method_name(PyObject* self, PyObject* args, PyObject* kwds); \
static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \
- return ((class_name*) self)->Py##method_name(self, args, kwds); \
+ PyObjectPlus *self_plus= BGE_PROXY_REF(self); \
+ return ((class_name*)self_plus)->Py##method_name(self, args, kwds); \
}; \
#define KX_PYMETHOD_VARARGS(class_name, method_name) \
PyObject* Py##method_name(PyObject* self, PyObject* args); \
static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \
- return ((class_name*) self)->Py##method_name(self, args); \
+ PyObjectPlus *self_plus= BGE_PROXY_REF(self); \
+ return ((class_name*)self_plus)->Py##method_name(self, args); \
}; \
#define KX_PYMETHOD_NOARGS(class_name, method_name) \
PyObject* Py##method_name(PyObject* self); \
static PyObject* sPy##method_name( PyObject* self) { \
- return ((class_name*) self)->Py##method_name(self); \
+ PyObjectPlus *self_plus= BGE_PROXY_REF(self); \
+ return ((class_name*)self_plus)->Py##method_name(self); \
}; \
#define KX_PYMETHOD_O(class_name, method_name) \
PyObject* Py##method_name(PyObject* self, PyObject* value); \
static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \
- return ((class_name*) self)->Py##method_name(self, value); \
+ PyObjectPlus *self_plus= ((PyObjectPlus_Proxy *)self)->ref; \
+ return ((class_name*) self_plus)->Py##method_name(self, value); \
}; \
#define KX_PYMETHOD_DOC(class_name, method_name) \
PyObject* Py##method_name(PyObject* self, PyObject* args, PyObject* kwds); \
static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \
- return ((class_name*) self)->Py##method_name(self, args, kwds); \
+ PyObjectPlus *self_plus= BGE_PROXY_REF(self); \
+ return ((class_name*)self_plus)->Py##method_name(self, args, kwds); \
}; \
static const char method_name##_doc[]; \
#define KX_PYMETHOD_DOC_VARARGS(class_name, method_name) \
PyObject* Py##method_name(PyObject* self, PyObject* args); \
static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \
- return ((class_name*) self)->Py##method_name(self, args); \
+ PyObjectPlus *self_plus= BGE_PROXY_REF(self); \
+ return ((class_name*)self_plus)->Py##method_name(self, args); \
}; \
static const char method_name##_doc[]; \
#define KX_PYMETHOD_DOC_O(class_name, method_name) \
PyObject* Py##method_name(PyObject* self, PyObject* value); \
static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \
- return ((class_name*) self)->Py##method_name(self, value); \
+ PyObjectPlus *self_plus= BGE_PROXY_REF(self); \
+ return ((class_name*)self_plus)->Py##method_name(self, value); \
}; \
static const char method_name##_doc[]; \
#define KX_PYMETHOD_DOC_NOARGS(class_name, method_name) \
PyObject* Py##method_name(PyObject* self); \
static PyObject* sPy##method_name( PyObject* self) { \
- return ((class_name*) self)->Py##method_name(self); \
+ PyObjectPlus *self_plus= BGE_PROXY_REF(self); \
+ return ((class_name*)self_plus)->Py##method_name(self); \
}; \
static const char method_name##_doc[]; \
@@ -233,19 +258,19 @@ static inline void Py_Fatal(const char *M) {
*/
#define KX_PYMETHODDEF_DOC(class_name, method_name, doc_string) \
const char class_name::method_name##_doc[] = doc_string; \
-PyObject* class_name::Py##method_name(PyObject*, PyObject* args, PyObject*)
+PyObject* class_name::Py##method_name(PyObject* self, PyObject* args, PyObject*)
#define KX_PYMETHODDEF_DOC_VARARGS(class_name, method_name, doc_string) \
const char class_name::method_name##_doc[] = doc_string; \
-PyObject* class_name::Py##method_name(PyObject*, PyObject* args)
+PyObject* class_name::Py##method_name(PyObject* self, PyObject* args)
#define KX_PYMETHODDEF_DOC_O(class_name, method_name, doc_string) \
const char class_name::method_name##_doc[] = doc_string; \
-PyObject* class_name::Py##method_name(PyObject*, PyObject* value)
+PyObject* class_name::Py##method_name(PyObject* self, PyObject* value)
#define KX_PYMETHODDEF_DOC_NOARGS(class_name, method_name, doc_string) \
const char class_name::method_name##_doc[] = doc_string; \
-PyObject* class_name::Py##method_name(PyObject*)
+PyObject* class_name::Py##method_name(PyObject* self)
/**
* Attribute management
@@ -394,19 +419,17 @@ typedef struct KX_PYATTRIBUTE_DEF {
------------------------------*/
typedef PyTypeObject * PyParentObject; // Define the PyParent Object
-class PyObjectPlus : public PyObject
+class PyObjectPlus
{ // The PyObjectPlus abstract class
Py_Header; // Always start with Py_Header
public:
PyObjectPlus(PyTypeObject *T);
- bool m_zombie;
+
+ PyObject *m_proxy; /* actually a PyObjectPlus_Proxy */
virtual ~PyObjectPlus(); // destructor
- static void PyDestructor(PyObject *P) // python wrapper
- {
- delete ((PyObjectPlus *) P);
- };
+ static void PyDestructor(PyObject *self); // python wrapper
// void INCREF(void) {
// Py_INCREF(this);
@@ -418,15 +441,15 @@ public:
virtual PyObject *py_getattro(PyObject *attr); // py_getattro method
static PyObject *py_base_getattro(PyObject * self, PyObject *attr) // This should be the entry in Type.
{
- if (((PyObjectPlus*)self)->IsZombie()) {
- if (!strcmp(PyString_AsString(attr), "isValid")) {
- Py_RETURN_FALSE;
+ PyObjectPlus *self_plus= BGE_PROXY_REF(self);
+ if(self_plus==NULL) {
+ if(!strcmp("isValid", PyString_AsString(attr))) {
+ Py_RETURN_TRUE;
}
- ((PyObjectPlus*)self)->IsZombiePyErr(); /* raise an error */
+ PyErr_SetString(PyExc_RuntimeError, "data has been removed");
return NULL;
}
-
- return ((PyObjectPlus*) self)->py_getattro(attr);
+ return self_plus->py_getattro(attr);
}
static PyObject* py_get_attrdef(void *self, const PyAttributeDef *attrdef);
@@ -441,22 +464,29 @@ public:
virtual int py_setattro(PyObject *attr, PyObject *value); // py_setattro method
static int py_base_setattro(PyObject *self, PyObject *attr, PyObject *value) // the PyType should reference this
{
- if (((PyObjectPlus*)self)->IsZombie()) {
- /* you cant set isValid anyway */
- ((PyObjectPlus*)self)->IsZombiePyErr();
+ PyObjectPlus *self_plus= BGE_PROXY_REF(self);
+ if(self_plus==NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "data has been removed");
return -1;
}
if (value==NULL)
- return ((PyObjectPlus*)self)->py_delattro(attr);
+ return self_plus->py_delattro(attr);
- return ((PyObjectPlus*)self)->py_setattro(attr, value);
+ return self_plus->py_setattro(attr, value);
}
virtual PyObject *py_repr(void); // py_repr method
- static PyObject *py_base_repr(PyObject *PyObj) // This should be the entry in Type.
+ static PyObject *py_base_repr(PyObject *self) // This should be the entry in Type.
{
- return ((PyObjectPlus*) PyObj)->py_repr();
+
+ PyObjectPlus *self_plus= BGE_PROXY_REF(self);
+ if(self_plus==NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "data has been removed");
+ return NULL;
+ }
+
+ return self_plus->py_repr();
}
// isA methods
@@ -465,43 +495,20 @@ public:
PyObject *Py_isA(PyObject *value);
static PyObject *sPy_isA(PyObject *self, PyObject *value)
{
- return ((PyObjectPlus*)self)->Py_isA(value);
- }
-
- /* Kindof dumb, always returns True, the false case is checked for, before this function gets accessed */
- static PyObject* pyattr_get_is_valid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
-
- bool IsZombie()
- {
- return m_zombie;
- }
-
- bool IsZombiePyErr()
- {
- if(m_zombie) {
- /*
- PyObject *this_pystr = PyObject_Repr(this);
-
- PyErr_Format(
- PyExc_RuntimeError,
- "\"%s\" of type \"%s\" has been freed by the blender game engine, "
- "scripts cannot access this anymore, check for this case with the \"isValid\" attribute",
- PyString_AsString(this_pystr), ob_type->tp_name );
-
- Py_DECREF(this_pystr);
- */
-
- PyErr_SetString(PyExc_RuntimeError, "This value has been freed by the blender game engine but python is still holding a reference, this value cant be used.");
+ PyObjectPlus *self_plus= BGE_PROXY_REF(self);
+ if(self_plus==NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "data has been removed");
+ return NULL;
}
- return m_zombie;
+ return self_plus->Py_isA(value);
}
- void SetZombie(bool is_zombie)
- {
- m_zombie= is_zombie;
- }
+ /* Kindof dumb, always returns True, the false case is checked for, before this function gets accessed */
+ static PyObject* pyattr_get_is_valid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject *GetProxy_Ext(PyObjectPlus *self, PyTypeObject *tp);
+ static PyObject *NewProxy_Ext(PyObjectPlus *self, PyTypeObject *tp, bool py_owns);
};
PyObject *py_getattr_dict(PyObject *pydict, PyObject *tp_dict);
diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp
index 63776c39d70..7958c16ca81 100644
--- a/source/gameengine/Expressions/Value.cpp
+++ b/source/gameengine/Expressions/Value.cpp
@@ -501,12 +501,6 @@ int CValue::Release()
// Decrease local reference count, if it reaches 0 the object should be freed
if (--m_refcount > 0)
{
- // Benoit suggest this as a way to automatically set the zombie flag, but I couldnt get it working - Campbell
- /*
- if (m_refcount == 1 && ob_refcnt > 1)
- SetZombie(true); // the remaining refcount is held by Python!!
- */
-
// Reference count normal, return new reference count
return m_refcount;
}
@@ -544,9 +538,6 @@ void CValue::AddDataToReplica(CValue *replica)
{
replica->m_refcount = 1;
- //register with Python
- _Py_NewReference(replica);
-
#ifdef _DEBUG
//gRefCountValue++;
#endif
@@ -616,7 +607,7 @@ PyObject* CValue::py_getattro(PyObject *attr)
if (pyconvert)
return pyconvert;
else
- return resultattr; // also check if it's already in pythoninterpreter!
+ return resultattr->GetProxy();
}
py_getattro_up(PyObjectPlus);
}
diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h
index bcee355cda2..a687e1a493c 100644
--- a/source/gameengine/Expressions/Value.h
+++ b/source/gameengine/Expressions/Value.h
@@ -225,21 +225,6 @@ public:
virtual PyObject* py_getattro(PyObject *attr);
-
- void SpecialRelease()
- {
- if (ob_refcnt == 0) /* make sure python always holds a reference */
- {
- _Py_NewReference(this);
-
- }
- Release();
- }
- static void PyDestructor(PyObject *P) // python wrapper
- {
- ((CValue*)P)->SpecialRelease();
- };
-
virtual PyObject* ConvertValueToPython() {
return NULL;
}
@@ -352,7 +337,6 @@ private:
std::map<STR_String,CValue*>* m_pNamedPropertyArray; // Properties for user/game etc
ValueFlags m_ValFlags; // Frequently used flags in a bitfield (low memoryusage)
int m_refcount; // Reference Counter
- bool m_zombie; // Object is invalid put its still being referenced (by python)
static double m_sZeroVec[3];
static bool m_ignore_deprecation_warnings;
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
index 46e132c65fc..7fa55cfb1ee 100644
--- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
@@ -294,8 +294,7 @@ PyObject* SCA_ILogicBrick::PyGetOwner(PyObject* self)
CValue* parent = GetParent();
if (parent)
{
- parent->AddRef();
- return parent;
+ return parent->GetProxy();
}
printf("ERROR: Python scriptblock without owner\n");
diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp
index 1c5b597f937..687ae421af1 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.cpp
+++ b/source/gameengine/GameLogic/SCA_PythonController.cpp
@@ -157,7 +157,7 @@ static const char* sPyGetCurrentController__doc__;
PyObject* SCA_PythonController::sPyGetCurrentController(PyObject* self)
{
- return m_sCurrentController->AddRef();
+ return m_sCurrentController->GetProxy();
}
SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value)
@@ -176,10 +176,10 @@ SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value)
}
}
}
- else {
- /* Expecting an actuator type */
+ else if (BGE_PROXY_CHECK_TYPE(value)) {
+ PyObjectPlus *value_plus= BGE_PROXY_REF(value); /* Expecting an actuator type */ // XXX TODO - CHECK TYPE
for(it = lacts.begin(); it!= lacts.end(); it++) {
- if( static_cast<SCA_IActuator*>(value) == (*it) ) {
+ if( static_cast<SCA_IActuator*>(value_plus) == (*it) ) {
return *it;
}
}
@@ -413,7 +413,7 @@ PyObject* SCA_PythonController::PyGetActuators(PyObject* self)
PyObject* resultlist = PyList_New(m_linkedactuators.size());
for (unsigned int index=0;index<m_linkedactuators.size();index++)
{
- PyList_SET_ITEM(resultlist,index,m_linkedactuators[index]->AddRef());
+ PyList_SET_ITEM(resultlist,index, m_linkedactuators[index]->GetProxy());
}
return resultlist;
@@ -437,7 +437,7 @@ SCA_PythonController::PyGetSensor(PyObject* self, PyObject* value)
STR_String realname = sensor->GetName();
if (realname == scriptArg)
{
- return sensor->AddRef();
+ return sensor->GetProxy();
}
}
@@ -466,7 +466,7 @@ SCA_PythonController::PyGetActuator(PyObject* self, PyObject* value)
SCA_IActuator* actua = m_linkedactuators[index];
if (actua->GetName() == scriptArg)
{
- return actua->AddRef();
+ return actua->GetProxy();
}
}
@@ -484,7 +484,7 @@ SCA_PythonController::PyGetSensors(PyObject* self)
PyObject* resultlist = PyList_New(m_linkedsensors.size());
for (unsigned int index=0;index<m_linkedsensors.size();index++)
{
- PyList_SET_ITEM(resultlist,index,m_linkedsensors[index]->AddRef());
+ PyList_SET_ITEM(resultlist,index, m_linkedsensors[index]->GetProxy());
}
return resultlist;
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())
{
diff --git a/source/gameengine/VideoTexture/FilterSource.h b/source/gameengine/VideoTexture/FilterSource.h
index 6385ed5108f..254e0a02679 100644
--- a/source/gameengine/VideoTexture/FilterSource.h
+++ b/source/gameengine/VideoTexture/FilterSource.h
@@ -225,7 +225,7 @@ protected:
// otherwise if only vertical interpolation is needed
}
}
- else if ((y & 1) == 1)
+ else if ((y & 1) == 1) {
// if this pixel is on the edge
if (isEdge(x, y, size))
{
@@ -239,6 +239,7 @@ protected:
d = interpolV(m_buffU + offset) - 128;
e = interpolV(m_buffV + offset) - 128;
}
+ }
// convert to RGB
// R = clip(( 298 * C + 409 * E + 128) >> 8)
// G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp
index 6ef62f64d3f..9a3c4fea70e 100644
--- a/source/gameengine/VideoTexture/ImageRender.cpp
+++ b/source/gameengine/VideoTexture/ImageRender.cpp
@@ -434,26 +434,35 @@ static int ImageMirror_init (PyObject * pySelf, PyObject * args, PyObject * kwds
{
// get scene pointer
KX_Scene * scenePtr (NULL);
- if (scene != NULL && PyObject_TypeCheck(scene, &KX_Scene::Type))
- scenePtr = static_cast<KX_Scene*>(scene);
- else
+ if (scene != NULL && PyObject_TypeCheck(scene, &KX_Scene::Type))
+ scenePtr = static_cast<KX_Scene*>BGE_PROXY_REF(scene);
+ else
THRWEXCP(SceneInvalid, S_OK);
-
+
+ if(scenePtr==NULL) /* incase the python proxy reference is invalid */
+ THRWEXCP(SceneInvalid, S_OK);
+
// get observer pointer
KX_GameObject * observerPtr (NULL);
if (observer != NULL && PyObject_TypeCheck(observer, &KX_GameObject::Type))
- observerPtr = static_cast<KX_GameObject*>(observer);
+ observerPtr = static_cast<KX_GameObject*>BGE_PROXY_REF(observer);
else if (observer != NULL && PyObject_TypeCheck(observer, &KX_Camera::Type))
- observerPtr = static_cast<KX_Camera*>(observer);
+ observerPtr = static_cast<KX_Camera*>BGE_PROXY_REF(observer);
else
THRWEXCP(ObserverInvalid, S_OK);
+
+ if(observerPtr==NULL) /* incase the python proxy reference is invalid */
+ THRWEXCP(ObserverInvalid, S_OK);
// get mirror pointer
KX_GameObject * mirrorPtr (NULL);
if (mirror != NULL && PyObject_TypeCheck(mirror, &KX_GameObject::Type))
- mirrorPtr = static_cast<KX_GameObject*>(mirror);
+ mirrorPtr = static_cast<KX_GameObject*>BGE_PROXY_REF(mirror);
else
THRWEXCP(MirrorInvalid, S_OK);
+
+ if(mirrorPtr==NULL) /* incase the python proxy reference is invalid */
+ THRWEXCP(MirrorInvalid, S_OK);
// locate the material in the mirror
RAS_IPolyMaterial * material = getMaterial(mirror, materialID);