patch [#26215] Python weak reference (weakref) support for game objects
by Alex Fraser (z0r)
This commit is contained in:
@@ -108,19 +108,26 @@ void PyObjectPlus::InvalidateProxy() // check typename of each parent
|
||||
|
||||
PyTypeObject PyObjectPlus::Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"PyObjectPlus", /*tp_name*/
|
||||
"PyObjectPlus", /*tp_name*/
|
||||
sizeof(PyObjectPlus_Proxy), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
py_base_dealloc,
|
||||
py_base_dealloc, /* tp_dealloc */
|
||||
0, /* printfunc tp_print; */
|
||||
0, /* getattrfunc tp_getattr; */
|
||||
0, /* setattrfunc tp_setattr; */
|
||||
0, /* tp_compare */ /* DEPRECATED in python 3.0! */
|
||||
py_base_repr, /* tp_repr */
|
||||
0,0,0,0,0,0,0,0,0, /* Method suites for standard classes */
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,/* long tp_flags; */
|
||||
0,0,0,0,
|
||||
/* weak reference enabler */
|
||||
#ifdef USE_WEAKREFS
|
||||
offsetof(PyObjectPlus_Proxy, in_weakreflist), /* long tp_weaklistoffset; */
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
py_base_repr,
|
||||
0,0,0,0,0,0,0,0,0,
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
0,0,0,0,0,0,0,
|
||||
#endif
|
||||
0,0,
|
||||
Methods,
|
||||
0,
|
||||
0,
|
||||
@@ -209,8 +216,16 @@ PyObject * PyObjectPlus::py_base_new(PyTypeObject *type, PyObject *args, PyObjec
|
||||
return (PyObject *)ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param self A PyObjectPlus_Proxy
|
||||
*/
|
||||
void PyObjectPlus::py_base_dealloc(PyObject *self) // python wrapper
|
||||
{
|
||||
#ifdef USE_WEAKREFS
|
||||
if (BGE_PROXY_WKREF(self) != NULL)
|
||||
PyObject_ClearWeakRefs((PyObject *) self);
|
||||
#endif
|
||||
|
||||
if (BGE_PROXY_PYREF(self)) {
|
||||
PyObjectPlus *self_plus= BGE_PROXY_REF(self);
|
||||
if(self_plus) {
|
||||
@@ -1107,6 +1122,7 @@ PyObject *PyObjectPlus::GetProxyPlus_Ext(PyObjectPlus *self, PyTypeObject *tp, v
|
||||
self->m_proxy = reinterpret_cast<PyObject *>PyObject_NEW( PyObjectPlus_Proxy, tp);
|
||||
BGE_PROXY_PYOWNS(self->m_proxy) = false;
|
||||
BGE_PROXY_PYREF(self->m_proxy) = true;
|
||||
BGE_PROXY_WKREF(self->m_proxy) = NULL;
|
||||
}
|
||||
//PyObject_Print(self->m_proxy, stdout, 0);
|
||||
//printf("ref %d\n", self->m_proxy->ob_refcnt);
|
||||
@@ -1127,6 +1143,7 @@ PyObject *PyObjectPlus::NewProxyPlus_Ext(PyObjectPlus *self, PyTypeObject *tp, v
|
||||
BGE_PROXY_PYOWNS(proxy) = py_owns;
|
||||
BGE_PROXY_REF(proxy) = NULL;
|
||||
BGE_PROXY_PTR(proxy) = ptr;
|
||||
BGE_PROXY_WKREF(self->m_proxy) = NULL;
|
||||
return proxy;
|
||||
}
|
||||
if (self->m_proxy)
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
* \ingroup expressions
|
||||
*/
|
||||
|
||||
/* for now keep weakrefs optional */
|
||||
#define USE_WEAKREFS
|
||||
|
||||
#ifndef _adr_py_lib_h_ // only process once,
|
||||
#define _adr_py_lib_h_ // even if multiply included
|
||||
|
||||
@@ -95,6 +98,9 @@ typedef struct PyObjectPlus_Proxy {
|
||||
void *ptr; // optional pointer to generic structure, the structure holds no reference to this proxy
|
||||
bool py_owns; // true if the object pointed by ref should be deleted when the proxy is deleted
|
||||
bool py_ref; // true if proxy is connected to a GE object (ref is used)
|
||||
#ifdef USE_WEAKREFS
|
||||
PyObject *in_weakreflist; // weak reference enabler
|
||||
#endif
|
||||
} PyObjectPlus_Proxy;
|
||||
|
||||
#define BGE_PROXY_ERROR_MSG "Blender Game Engine data has been freed, cannot use this python variable"
|
||||
@@ -102,6 +108,7 @@ typedef struct PyObjectPlus_Proxy {
|
||||
#define BGE_PROXY_PTR(_self) (((PyObjectPlus_Proxy *)_self)->ptr)
|
||||
#define BGE_PROXY_PYOWNS(_self) (((PyObjectPlus_Proxy *)_self)->py_owns)
|
||||
#define BGE_PROXY_PYREF(_self) (((PyObjectPlus_Proxy *)_self)->py_ref)
|
||||
#define BGE_PROXY_WKREF(_self) (((PyObjectPlus_Proxy *)_self)->in_weakreflist)
|
||||
|
||||
/* Note, sometimes we dont care what BGE type this is as long as its a proxy */
|
||||
#define BGE_PROXY_CHECK_TYPE(_type) ((_type)->tp_dealloc == PyObjectPlus::py_base_dealloc)
|
||||
|
||||
Reference in New Issue
Block a user