Beispiel #1
0
/**
 * \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) {
			if (BGE_PROXY_PYOWNS(self)) { /* Does python own this?, then delete it  */
				self_plus->m_proxy = NULL; /* Need this to stop ~PyObjectPlus from decrefing m_proxy otherwise its decref'd twice and py-debug crashes */
				delete self_plus;
			}
			BGE_PROXY_REF(self)= NULL; // not really needed
		}
		// the generic pointer is not deleted directly, only through self_plus
		BGE_PROXY_PTR(self)= NULL; // not really needed
	} else {
		void *ptr= BGE_PROXY_PTR(self);
		if (ptr) {
			if (BGE_PROXY_PYOWNS(self)) { /* Does python own this?, then delete it  */
				// generic structure owned by python MUST be created though MEM_alloc
				MEM_freeN(ptr);
			}
			BGE_PROXY_PTR(self)= NULL; // not really needed
		}
	}
#if 0
	/* is ok normally but not for subtyping, use tp_free instead. */
	PyObject_DEL( self );
#else
	Py_TYPE(self)->tp_free(self);
#endif
};
Beispiel #2
0
PyObject *PyObjectPlus::GetProxyPlus_Ext(PyObjectPlus *self, PyTypeObject *tp, void *ptr)
{
	if (self->m_proxy==NULL)
	{
		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;
	}
Beispiel #3
0
/* note, this is called as a python 'getset, where the PyAttributeDef is the closure */
PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *attrdef)
{
	PyObjectPlus *ref= (BGE_PROXY_REF(self_py));
	char* ptr = (attrdef->m_usePtr) ? (char*)BGE_PROXY_PTR(self_py) : (char*)ref;
	if (ptr == NULL || (BGE_PROXY_PYREF(self_py) && (ref==NULL || !ref->py_is_valid()))) {
		if (attrdef == BGE_PY_ATTR_INVALID)
			Py_RETURN_TRUE; // don't bother running the function

		PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
		return NULL;
	}

	if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_DUMMY)
	{
		// fake attribute, ignore
		return NULL;
	}
	if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_FUNCTION)
	{
		// the attribute has no field correspondence, handover processing to function.
		if (attrdef->m_getFunction == NULL)
			return NULL;
		return (*attrdef->m_getFunction)(ptr, attrdef);
	}
	ptr += attrdef->m_offset;
	if (attrdef->m_length > 1)
	{
		PyObject *resultlist = PyList_New(attrdef->m_length);
		for (unsigned int i=0; i<attrdef->m_length; i++)
		{
			switch (attrdef->m_type) {
			case KX_PYATTRIBUTE_TYPE_BOOL:
				{
					bool *val = reinterpret_cast<bool*>(ptr);
					ptr += sizeof(bool);
					PyList_SET_ITEM(resultlist, i, PyBool_FromLong(*val));
					break;
				}
			case KX_PYATTRIBUTE_TYPE_SHORT:
				{
					short int *val = reinterpret_cast<short int*>(ptr);
					ptr += sizeof(short int);
					PyList_SET_ITEM(resultlist, i, PyLong_FromLong(*val));
					break;
				}
			case KX_PYATTRIBUTE_TYPE_ENUM:
				// enum are like int, just make sure the field size is the same
				if (sizeof(int) != attrdef->m_size)
				{
					Py_DECREF(resultlist);
					return NULL;
				}
				// walkthrough
			case KX_PYATTRIBUTE_TYPE_INT:
				{
					int *val = reinterpret_cast<int*>(ptr);
					ptr += sizeof(int);
					PyList_SET_ITEM(resultlist, i, PyLong_FromLong(*val));
					break;
				}
			case KX_PYATTRIBUTE_TYPE_FLOAT:
				{
					float *val = reinterpret_cast<float*>(ptr);
					ptr += sizeof(float);
					PyList_SET_ITEM(resultlist, i, PyFloat_FromDouble(*val));
					break;
				}
			default:
				// no support for array of complex data
				Py_DECREF(resultlist);
				return NULL;
			}
		}
		return resultlist;
	}
	else
	{
		switch (attrdef->m_type) {
		case KX_PYATTRIBUTE_TYPE_FLAG:
			{
				bool bval;
				switch (attrdef->m_size) {
				case 1:
					{
						unsigned char *val = reinterpret_cast<unsigned char*>(ptr);
						bval = (*val & attrdef->m_imin);
						break;
					}
				case 2:
					{
						unsigned short *val = reinterpret_cast<unsigned short*>(ptr);
						bval = (*val & attrdef->m_imin);
						break;
					}
				case 4:
					{
						unsigned int *val = reinterpret_cast<unsigned int*>(ptr);
						bval = (*val & attrdef->m_imin);
						break;
					}
				default:
					return NULL;
				}
				if (attrdef->m_imax)
					bval = !bval;
				return PyBool_FromLong(bval);
			}
		case KX_PYATTRIBUTE_TYPE_BOOL:
			{
				bool *val = reinterpret_cast<bool*>(ptr);
				return PyBool_FromLong(*val);
			}
		case KX_PYATTRIBUTE_TYPE_SHORT:
			{
				short int *val = reinterpret_cast<short int*>(ptr);
				return PyLong_FromLong(*val);
			}
		case KX_PYATTRIBUTE_TYPE_ENUM:
			// enum are like int, just make sure the field size is the same
			if (sizeof(int) != attrdef->m_size)
			{
				return NULL;
			}
			// walkthrough
		case KX_PYATTRIBUTE_TYPE_INT:
			{
				int *val = reinterpret_cast<int*>(ptr);
				return PyLong_FromLong(*val);
			}
		case KX_PYATTRIBUTE_TYPE_FLOAT:
			{
				float *val = reinterpret_cast<float*>(ptr);
				if (attrdef->m_imin == 0) {
					if (attrdef->m_imax == 0) {
						return PyFloat_FromDouble(*val);
					} else {
						// vector, verify size
						if (attrdef->m_size != attrdef->m_imax*sizeof(float)) 
						{
							return NULL;
						}
#ifdef USE_MATHUTILS
						return Vector_CreatePyObject(val, attrdef->m_imax, NULL);
#else
						PyObject *resultlist = PyList_New(attrdef->m_imax);
						for (unsigned int i=0; i<attrdef->m_imax; i++)
						{
							PyList_SET_ITEM(resultlist, i, PyFloat_FromDouble(val[i]));
						}
						return resultlist;
#endif
					}
				} else {
					// matrix case
					if (attrdef->m_size != attrdef->m_imax*attrdef->m_imin*sizeof(float)) 
					{
						return NULL;
					}
#ifdef USE_MATHUTILS
					return Matrix_CreatePyObject_wrap(val, attrdef->m_imin, attrdef->m_imax, NULL);
#else
					PyObject *collist = PyList_New(attrdef->m_imin);
					for (unsigned int i=0; i<attrdef->m_imin; i++)
					{
						PyObject *col = PyList_New(attrdef->m_imax);
						for (unsigned int j=0; j<attrdef->m_imax; j++)
						{
							PyList_SET_ITEM(col, j, PyFloat_FromDouble(val[j]));
						}
						PyList_SET_ITEM(collist, i, col);
						val += attrdef->m_imax;
					}
					return collist;
#endif
				}
			}
		case KX_PYATTRIBUTE_TYPE_VECTOR:
			{
				MT_Vector3 *val = reinterpret_cast<MT_Vector3*>(ptr);
#ifdef USE_MATHUTILS
				float fval[3];
				val->getValue(fval);
				return Vector_CreatePyObject(fval, 3, NULL);
#else
				PyObject *resultlist = PyList_New(3);
				for (unsigned int i=0; i<3; i++)
				{
					PyList_SET_ITEM(resultlist, i, PyFloat_FromDouble((*val)[i]));
				}
				return resultlist;
#endif
			}
		case KX_PYATTRIBUTE_TYPE_STRING:
			{
				STR_String *val = reinterpret_cast<STR_String*>(ptr);
				return PyUnicode_From_STR_String(*val);
			}
		case KX_PYATTRIBUTE_TYPE_CHAR:
			{
				return PyUnicode_FromString(ptr);
			}
		default:
			return NULL;
		}
	}
}