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
This commit is contained in:
parent
92cea7c1b1
commit
8d2cb5bea4
@ -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++)
|
||||
{
|
||||
|
@ -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[] =
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
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_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.");
|
||||
}
|
||||
|
||||
return m_zombie;
|
||||
}
|
||||
|
||||
void SetZombie(bool is_zombie)
|
||||
{
|
||||
m_zombie= is_zombie;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
/* <----- */
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 *)
|
||||
|
@ -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++) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
@ -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 (PyObject_TypeCheck(value, &KX_Camera::Type))
|
||||
|
||||
if(value==Py_None)
|
||||
{
|
||||
camOb = static_cast<KX_Camera*>(value);
|
||||
if (actuator->m_camera)
|
||||
actuator->m_camera->UnregisterActuator(actuator);
|
||||
actuator->m_camera = camOb;
|
||||
|
||||
actuator->m_camera= NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (PyObject_TypeCheck(value, &KX_Camera::Type))
|
||||
{
|
||||
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->RegisterActuator(actuator);
|
||||
actuator->m_camera->UnregisterActuator(actuator);
|
||||
|
||||
actuator->m_camera = camOb;
|
||||
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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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())
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user