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-03 18:51:06 +0400
committerCampbell Barton <ideasman42@gmail.com>2009-04-03 18:51:06 +0400
commitfd2b1156783d52dbb7c93c53fe008d9e14cbffdd (patch)
tree3578443cee384e883450b35480244a0c46aaf34b /source/gameengine/Expressions/PyObjectPlus.cpp
parente30cb79aaa8d9a25b66c57aa08fb79bf591b6be4 (diff)
Python BGE API
- Initialize python types with PyType_Ready, which adds methods to the type dictionary. - use Pythons get/setattro (uses a python string for the attribute rather then char*). Using basic C strings seems nice but internally python converts them to python strings and discards them for most functions that accept char arrays. - Method lookups use the PyTypes dictionary (should be faster then Py_FindMethod) - Renamed __getattr -> py_base_getattro, _getattr -> py_getattro, __repr -> py_base_repr, py_delattro, py_getattro_self etc. From here is possible to put all the parent classes methods into each python types dictionary to avoid nested lookups (api has 4 levels of lookups in some places), tested this but its not ready yet. Simple tests for getting a method within a loop show this to be between 0.5 and 3.2x faster then using Py_FindMethod()
Diffstat (limited to 'source/gameengine/Expressions/PyObjectPlus.cpp')
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.cpp54
1 files changed, 31 insertions, 23 deletions
diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp
index 417388be464..ed6932b414a 100644
--- a/source/gameengine/Expressions/PyObjectPlus.cpp
+++ b/source/gameengine/Expressions/PyObjectPlus.cpp
@@ -55,19 +55,22 @@
------------------------------*/
PyTypeObject PyObjectPlus::Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"PyObjectPlus", /*tp_name*/
sizeof(PyObjectPlus), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
- PyDestructor, /*tp_dealloc*/
- 0, /*tp_print*/
- __getattr, /*tp_getattr*/
- __setattr, /*tp_setattr*/
- 0, /*tp_compare*/
- __repr,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ PyDestructor,
+ 0,
+ 0,
+ 0,
+ 0,
+ py_base_repr,
+ 0,0,0,0,0,0,
+ py_base_getattro,
+ py_base_setattro,
+ 0,0,0,0,0,0,0,0,0,
Methods
};
@@ -103,37 +106,41 @@ PyParentObject PyObjectPlus::Parents[] = {&PyObjectPlus::Type, NULL};
/*------------------------------
* PyObjectPlus attributes -- attributes
------------------------------*/
-PyObject *PyObjectPlus::_getattr(const char *attr)
+PyObject *PyObjectPlus::py_getattro(PyObject* attr)
{
- if (!strcmp(attr, "__doc__") && GetType()->tp_doc)
- return PyString_FromString(GetType()->tp_doc);
-
+ PyObject *descr = PyDict_GetItem(Type.tp_dict, attr); \
+ if (descr == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "attribute not found");
+ return NULL;
+ } else {
+ return PyCFunction_New(((PyMethodDescrObject *)descr)->d_method, (PyObject *)this); \
+ }
//if (streq(attr, "type"))
// return Py_BuildValue("s", (*(GetParents()))->tp_name);
-
- return Py_FindMethod(Methods, this, attr);
}
-int PyObjectPlus::_delattr(const char *attr)
+int PyObjectPlus::py_delattro(PyObject* attr)
{
PyErr_SetString(PyExc_AttributeError, "attribute cant be deleted");
return 1;
}
-int PyObjectPlus::_setattr(const char *attr, PyObject *value)
+int PyObjectPlus::py_setattro(PyObject *attr, PyObject* value)
{
- //return PyObject::_setattr(attr,value);
+ //return PyObject::py_setattro(attr,value);
//cerr << "Unknown attribute" << endl;
PyErr_SetString(PyExc_AttributeError, "attribute cant be set");
return 1;
}
-PyObject *PyObjectPlus::_getattr_self(const PyAttributeDef attrlist[], void *self, const char *attr)
+PyObject *PyObjectPlus::py_getattro_self(const PyAttributeDef attrlist[], void *self, PyObject *attr)
{
+ char *attr_str= PyString_AsString(attr);
+
const PyAttributeDef *attrdef;
for (attrdef=attrlist; attrdef->m_name != NULL; attrdef++)
{
- if (!strcmp(attr, attrdef->m_name))
+ if (!strcmp(attr_str, attrdef->m_name))
{
if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_DUMMY)
{
@@ -242,16 +249,17 @@ PyObject *PyObjectPlus::_getattr_self(const PyAttributeDef attrlist[], void *sel
return NULL;
}
-int PyObjectPlus::_setattr_self(const PyAttributeDef attrlist[], void *self, const char *attr, PyObject *value)
+int PyObjectPlus::py_setattro_self(const PyAttributeDef attrlist[], void *self, PyObject *attr, PyObject *value)
{
const PyAttributeDef *attrdef;
void *undoBuffer = NULL;
void *sourceBuffer = NULL;
size_t bufferSize = 0;
+ char *attr_str= PyString_AsString(attr);
for (attrdef=attrlist; attrdef->m_name != NULL; attrdef++)
{
- if (!strcmp(attr, attrdef->m_name))
+ if (!strcmp(attr_str, attrdef->m_name))
{
if (attrdef->m_access == KX_PYATTRIBUTE_RO ||
attrdef->m_type == KX_PYATTRIBUTE_TYPE_DUMMY)
@@ -684,7 +692,7 @@ int PyObjectPlus::_setattr_self(const PyAttributeDef attrlist[], void *self, con
/*------------------------------
* PyObjectPlus repr -- representations
------------------------------*/
-PyObject *PyObjectPlus::_repr(void)
+PyObject *PyObjectPlus::py_repr(void)
{
PyErr_SetString(PyExc_SystemError, "Representation not overridden by object.");
return NULL;
@@ -726,7 +734,7 @@ PyObject *PyObjectPlus::Py_isA(PyObject *value) // Python wrapper for isA
Py_RETURN_FALSE;
}
-/* Utility function called by the macro _getattr_up()
+/* Utility function called by the macro py_getattro_up()
* for getting ob.__dict__() values from our PyObject
* this is used by python for doing dir() on an object, so its good
* if we return a list of attributes and methods.