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()
This commit is contained in:
@@ -139,19 +139,22 @@ static PyNumberMethods cvalue_as_number = {
|
||||
|
||||
|
||||
PyTypeObject CValue::Type = {
|
||||
PyObject_HEAD_INIT(&PyType_Type)
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0,
|
||||
"CValue",
|
||||
sizeof(CValue),
|
||||
0,
|
||||
PyDestructor,
|
||||
0,
|
||||
__getattr,
|
||||
__setattr,
|
||||
0,
|
||||
0,
|
||||
&MyPyCompare,
|
||||
__repr,
|
||||
py_base_repr,
|
||||
&cvalue_as_number,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
py_base_getattro,
|
||||
py_base_setattro,
|
||||
0,0,0,0,0,0,0,0,0,
|
||||
Methods
|
||||
};
|
||||
|
||||
@@ -695,9 +698,10 @@ PyAttributeDef CValue::Attributes[] = {
|
||||
};
|
||||
|
||||
|
||||
PyObject* CValue::_getattr(const char *attr)
|
||||
PyObject* CValue::py_getattro(PyObject *attr)
|
||||
{
|
||||
CValue* resultattr = GetProperty(attr);
|
||||
char *attr_str= PyString_AsString(attr);
|
||||
CValue* resultattr = GetProperty(attr_str);
|
||||
if (resultattr)
|
||||
{
|
||||
PyObject* pyconvert = resultattr->ConvertValueToPython();
|
||||
@@ -707,7 +711,7 @@ PyObject* CValue::_getattr(const char *attr)
|
||||
else
|
||||
return resultattr; // also check if it's already in pythoninterpreter!
|
||||
}
|
||||
_getattr_up(PyObjectPlus);
|
||||
py_getattro_up(PyObjectPlus);
|
||||
}
|
||||
|
||||
CValue* CValue::ConvertPythonToValue(PyObject* pyobj)
|
||||
@@ -769,26 +773,28 @@ CValue* CValue::ConvertPythonToValue(PyObject* pyobj)
|
||||
|
||||
}
|
||||
|
||||
int CValue::_delattr(const char *attr)
|
||||
int CValue::py_delattro(PyObject *attr)
|
||||
{
|
||||
if (RemoveProperty(STR_String(attr)))
|
||||
char *attr_str= PyString_AsString(attr);
|
||||
if (RemoveProperty(STR_String(attr_str)))
|
||||
return 0;
|
||||
|
||||
PyErr_Format(PyExc_AttributeError, "attribute \"%s\" dosnt exist", attr);
|
||||
PyErr_Format(PyExc_AttributeError, "attribute \"%s\" dosnt exist", attr_str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CValue::_setattr(const char *attr, PyObject* pyobj)
|
||||
int CValue::py_setattro(PyObject *attr, PyObject* pyobj)
|
||||
{
|
||||
CValue* vallie = ConvertPythonToValue(pyobj);
|
||||
if (vallie)
|
||||
{
|
||||
CValue* oldprop = GetProperty(attr);
|
||||
char *attr_str= PyString_AsString(attr);
|
||||
CValue* oldprop = GetProperty(attr_str);
|
||||
|
||||
if (oldprop)
|
||||
oldprop->SetValue(vallie);
|
||||
else
|
||||
SetProperty(attr, vallie);
|
||||
SetProperty(attr_str, vallie);
|
||||
|
||||
vallie->Release();
|
||||
} else
|
||||
@@ -796,7 +802,7 @@ int CValue::_setattr(const char *attr, PyObject* pyobj)
|
||||
return 1; /* ConvertPythonToValue sets the error message */
|
||||
}
|
||||
|
||||
//PyObjectPlus::_setattr(attr,value);
|
||||
//PyObjectPlus::py_setattro(attr,value);
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user