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-18 00:06:06 +0400
committerCampbell Barton <ideasman42@gmail.com>2009-04-18 00:06:06 +0400
commitdf8cf26404c7e922751643b1095e38f1ab430811 (patch)
treeb4258cc6c90913c379f5cdd05edebd8785230647 /source/gameengine/Ketsji
parent90c6cf77f10961de756f6ff06329d3fa65ce3da4 (diff)
Added m_zombie to the base python class (PyObjectPlus), when this is set all the subclasses will raise an error on access to their members.
Other small changes... - KX_Camera and KX_Light didnt have get/setitem access in their PyType definition. - CList.from_id() error checking for a long was checking for -1 against an unsigned value (own fault) - CValue::SpecialRelease was incrementing an int for no reason. - renamed m_attrlist to m_attr_dict since its a PyDict type. - removed custom getattro/setattro functions for KX_Scene and KX_GameObject, use py_base_getattro, py_base_setattro for all subclasses of PyObjectPlus. - lowercase windows.h in VideoBase.cpp for cross compiling.
Diffstat (limited to 'source/gameengine/Ketsji')
-rw-r--r--source/gameengine/Ketsji/KX_Camera.cpp22
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp179
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h26
-rw-r--r--source/gameengine/Ketsji/KX_Light.cpp15
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp68
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h26
6 files changed, 148 insertions, 188 deletions
diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp
index befc8462aa3..daa37056d68 100644
--- a/source/gameengine/Ketsji/KX_Camera.cpp
+++ b/source/gameengine/Ketsji/KX_Camera.cpp
@@ -517,13 +517,20 @@ PyTypeObject KX_Camera::Type = {
0,
0,
py_base_repr,
- 0,0,0,0,0,0,
+ 0,0,
+ &KX_GameObject::Mapping,
+ 0,0,0,
py_base_getattro,
py_base_setattro,
0,0,0,0,0,0,0,0,0,
Methods
};
+
+
+
+
+
PyParentObject KX_Camera::Parents[] = {
&KX_Camera::Type,
&KX_GameObject::Type,
@@ -534,22 +541,11 @@ PyParentObject KX_Camera::Parents[] = {
PyObject* KX_Camera::py_getattro(PyObject *attr)
{
- if (ValidPythonToGameObject(this)==false) {
- if (!strcmp(PyString_AsString(attr), "isValid")) {
- PyErr_Clear();
- Py_RETURN_FALSE;
- }
- return NULL; /* ValidPythonToGameObject sets the error */
- }
-
py_getattro_up(KX_GameObject);
}
int KX_Camera::py_setattro(PyObject *attr, PyObject *value)
-{
- if (ValidPythonToGameObject(this)==false)
- return -1;
-
+{
py_setattro_up(KX_GameObject);
}
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 283b78c2947..3e7c99dc472 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -103,7 +103,7 @@ KX_GameObject::KX_GameObject(
m_xray(false),
m_pHitObject(NULL),
m_isDeformable(false),
- m_attrlist(NULL)
+ m_attr_dict(NULL)
{
m_ignore_activity_culling = false;
m_pClient_info = new KX_ClientObjectInfo(this, KX_ClientObjectInfo::ACTOR);
@@ -146,9 +146,9 @@ KX_GameObject::~KX_GameObject()
delete m_pGraphicController;
}
- if (m_attrlist) {
- PyDict_Clear(m_attrlist); /* incase of circular refs or other weired cases */
- Py_DECREF(m_attrlist);
+ if (m_attr_dict) {
+ PyDict_Clear(m_attr_dict); /* incase of circular refs or other weired cases */
+ Py_DECREF(m_attr_dict);
}
}
@@ -339,8 +339,8 @@ void KX_GameObject::ProcessReplica(KX_GameObject* replica)
replica->m_pClient_info = new KX_ClientObjectInfo(*m_pClient_info);
replica->m_pClient_info->m_gameobject = replica;
replica->m_state = 0;
- if(m_attrlist)
- replica->m_attrlist= PyDict_Copy(m_attrlist);
+ if(m_attr_dict)
+ replica->m_attr_dict= PyDict_Copy(m_attr_dict);
}
@@ -1123,9 +1123,6 @@ PyAttributeDef KX_GameObject::Attributes[] = {
KX_PYATTRIBUTE_RO_FUNCTION("sensors", KX_GameObject, pyattr_get_sensors),
KX_PYATTRIBUTE_RO_FUNCTION("controllers", KX_GameObject, pyattr_get_controllers),
KX_PYATTRIBUTE_RO_FUNCTION("actuators", KX_GameObject, pyattr_get_actuators),
-
- KX_PYATTRIBUTE_RO_FUNCTION("isValid", KX_GameObject, pyattr_get_is_valid),
-
{NULL} //Sentinel
};
@@ -1190,14 +1187,15 @@ Py_ssize_t KX_GameObject::Map_Len(PyObject* self_v)
{
KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
- if (ValidPythonToGameObject(self)==false) {
+ if (self->IsZombie()) /* not sure what to do here */
+ {
PyErr_Clear();
return 0;
}
Py_ssize_t len= self->GetPropertyCount();
- if(self->m_attrlist)
- len += PyDict_Size(self->m_attrlist);
+ if(self->m_attr_dict)
+ len += PyDict_Size(self->m_attr_dict);
return len;
}
@@ -1209,7 +1207,7 @@ PyObject *KX_GameObject::Map_GetItem(PyObject *self_v, PyObject *item)
CValue* resultattr;
PyObject* pyconvert;
- if (ValidPythonToGameObject(self)==false)
+ if (self->IsZombiePyErr())
return NULL;
/* first see if the attributes a string and try get the cvalue attribute */
@@ -1217,8 +1215,8 @@ PyObject *KX_GameObject::Map_GetItem(PyObject *self_v, PyObject *item)
pyconvert = resultattr->ConvertValueToPython();
return pyconvert ? pyconvert:resultattr;
}
- /* no CValue attribute, try get the python only m_attrlist attribute */
- else if (self->m_attrlist && (pyconvert=PyDict_GetItem(self->m_attrlist, item))) {
+ /* 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))) {
if (attr_str)
PyErr_Clear();
@@ -1241,7 +1239,7 @@ int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val)
if(attr_str==NULL)
PyErr_Clear();
- if (ValidPythonToGameObject(self)==false)
+ if (self->IsZombiePyErr())
return -1;
if (val==NULL) { /* del ob["key"] */
@@ -1251,15 +1249,15 @@ int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val)
if(attr_str)
del |= (self->RemoveProperty(attr_str)==true) ? 1:0;
- if(self->m_attrlist)
- del |= (PyDict_DelItem(self->m_attrlist, key)==0) ? 1:0;
+ if(self->m_attr_dict)
+ del |= (PyDict_DelItem(self->m_attr_dict, key)==0) ? 1:0;
if (del==0) {
if(attr_str) PyErr_Format(PyExc_KeyError, "KX_GameObject key \"%s\" not found", attr_str);
else PyErr_SetString(PyExc_KeyError, "KX_GameObject key not found");
return -1;
}
- else if (self->m_attrlist) {
+ else if (self->m_attr_dict) {
PyErr_Clear(); /* PyDict_DelItem sets an error when it fails */
}
}
@@ -1284,8 +1282,8 @@ int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val)
set= 1;
/* try remove dict value to avoid double ups */
- if (self->m_attrlist){
- if (PyDict_DelItem(self->m_attrlist, key) != 0)
+ if (self->m_attr_dict){
+ if (PyDict_DelItem(self->m_attr_dict, key) != 0)
PyErr_Clear();
}
}
@@ -1296,11 +1294,11 @@ int KX_GameObject::Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val)
if(set==0)
{
- if (self->m_attrlist==NULL) /* lazy init */
- self->m_attrlist= PyDict_New();
+ if (self->m_attr_dict==NULL) /* lazy init */
+ self->m_attr_dict= PyDict_New();
- if(PyDict_SetItem(self->m_attrlist, key, val)==0)
+ if(PyDict_SetItem(self->m_attr_dict, key, val)==0)
{
if(attr_str)
self->RemoveProperty(attr_str); /* overwrite the CValue if it exists */
@@ -1343,8 +1341,8 @@ PyTypeObject KX_GameObject::Type = {
0,0,
&Mapping,
0,0,0,
- py_base_getattro_gameobject,
- py_base_setattro_gameobject,
+ py_base_getattro,
+ py_base_setattro,
0,0,0,0,0,0,0,0,0,
Methods
};
@@ -1675,11 +1673,6 @@ PyObject* KX_GameObject::pyattr_get_meshes(void *self_v, const KX_PYATTRIBUTE_DE
return meshes;
}
-PyObject* KX_GameObject::pyattr_get_is_valid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
-{
- Py_RETURN_TRUE;
-}
-
/* experemental! */
PyObject* KX_GameObject::pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
@@ -1741,47 +1734,36 @@ PyObject* KX_GameObject::pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_
Py_DECREF(list);
- /* Add m_attrlist if we have it */
- if(self->m_attrlist)
- PyDict_Update(dict, self->m_attrlist);
+ /* Add m_attr_dict if we have it */
+ if(self->m_attr_dict)
+ PyDict_Update(dict, self->m_attr_dict);
return dict;
}
-PyObject* KX_GameObject::py_getattro(PyObject *attr)
+/* We need these because the macros have a return in them */
+PyObject* KX_GameObject::py_getattro__internal(PyObject *attr)
{
py_getattro_up(SCA_IObject);
}
-int KX_GameObject::py_setattro(PyObject *attr, PyObject *value) // py_setattro method
+int KX_GameObject::py_setattro__internal(PyObject *attr, PyObject *value) // py_setattro method
{
py_setattro_up(SCA_IObject);
}
-/* we need our own getattr and setattr types */
-/* See m_attrlist definition for rules on how this works */
-PyObject *KX_GameObject::py_base_getattro_gameobject(PyObject * self, PyObject *attr)
+PyObject* KX_GameObject::py_getattro(PyObject *attr)
{
- if(((KX_GameObject *) self)->GetSGNode()==NULL) {
- if (!strcmp(PyString_AsString(attr), "isValid")) {
- PyErr_Clear();
- Py_INCREF(Py_False);
- return Py_False;
- }
-
- ValidPythonToGameObject(((KX_GameObject *) self)); // we know its invalid, just get the error
- return NULL;
- }
-
- PyObject *object= ((KX_GameObject *) self)->py_getattro(attr);
+ PyObject *object= py_getattro__internal(attr);
- if (object==NULL && ((KX_GameObject *) self)->m_attrlist) {
+ if (object==NULL && m_attr_dict)
+ {
/* backup the exception incase the attr doesnt exist in the dict either */
PyObject *err_type, *err_value, *err_tb;
PyErr_Fetch(&err_type, &err_value, &err_tb);
- object= PyDict_GetItem(((KX_GameObject *) self)->m_attrlist, attr);
+ object= PyDict_GetItem(m_attr_dict, attr);
if (object) {
Py_INCREF(object);
@@ -1797,62 +1779,33 @@ PyObject *KX_GameObject::py_base_getattro_gameobject(PyObject * self, PyObject *
return object;
}
-int KX_GameObject::py_base_setattro_gameobject(PyObject * self, PyObject *attr, PyObject *value)
+int KX_GameObject::py_setattro(PyObject *attr, PyObject *value) // py_setattro method
{
int ret;
- /* Delete the item */
- if (value==NULL)
- {
- ret= ((PyObjectPlus*) self)->py_delattro(attr);
-
- if (ret != 0) /* CValue attribute failed, try KX_GameObject m_attrlist dict */
- {
- if (((KX_GameObject *) self)->m_attrlist)
- {
- /* backup the exception incase the attr doesnt exist in the dict either */
- PyObject *err_type, *err_value, *err_tb;
- PyErr_Fetch(&err_type, &err_value, &err_tb);
-
- if (PyDict_DelItem(((KX_GameObject *) self)->m_attrlist, attr) == 0)
- {
- ret= 0;
- PyErr_Clear();
- Py_XDECREF( err_type );
- Py_XDECREF( err_value );
- Py_XDECREF( err_tb );
- }
- else {
- PyErr_Restore(err_type, err_value, err_tb); /* use the error from the parent function */
- }
- }
- }
- return ret;
- }
-
-
- ret= ((PyObjectPlus*) self)->py_setattro(attr, value);
+ ret= py_setattro__internal(attr, value);
if (ret==PY_SET_ATTR_SUCCESS) {
/* remove attribute in our own dict to avoid double ups */
- if (((KX_GameObject *) self)->m_attrlist) {
- if (PyDict_DelItem(((KX_GameObject *) self)->m_attrlist, attr) != 0)
+ /* NOTE: Annoying that we also do this for setting builtin attributes like mass and visibility :/ */
+ if (m_attr_dict) {
+ if (PyDict_DelItem(m_attr_dict, attr) != 0)
PyErr_Clear();
}
}
if (ret==PY_SET_ATTR_COERCE_FAIL) {
- /* CValue attribute exists, remove and add dict value */
- ((KX_GameObject *) self)->RemoveProperty(STR_String(PyString_AsString(attr)));
+ /* CValue attribute exists, remove CValue and add PyDict value */
+ RemoveProperty(STR_String(PyString_AsString(attr)));
ret= PY_SET_ATTR_MISSING;
}
if (ret==PY_SET_ATTR_MISSING) {
/* Lazy initialization */
- if (((KX_GameObject *) self)->m_attrlist==NULL)
- ((KX_GameObject *) self)->m_attrlist = PyDict_New();
+ if (m_attr_dict==NULL)
+ m_attr_dict = PyDict_New();
- if (PyDict_SetItem(((KX_GameObject *) self)->m_attrlist, attr, value)==0) {
+ if (PyDict_SetItem(m_attr_dict, attr, value)==0) {
PyErr_Clear();
ret= PY_SET_ATTR_SUCCESS;
}
@@ -1862,9 +1815,25 @@ int KX_GameObject::py_base_setattro_gameobject(PyObject * self, PyObject *attr,
}
}
- return ret;
+ return ret;
}
+
+int KX_GameObject::py_delattro(PyObject *attr)
+{
+ char *attr_str= PyString_AsString(attr);
+
+ if (RemoveProperty(STR_String(attr_str))) // XXX - should call CValues instead but its only 2 lines here
+ return 0;
+
+ if (m_attr_dict && (PyDict_DelItem(m_attr_dict, attr) == 0))
+ return 0;
+
+ PyErr_Format(PyExc_AttributeError, "attribute \"%s\" dosnt exist", attr_str);
+ return 1;
+}
+
+
PyObject* KX_GameObject::PyApplyForce(PyObject* self, PyObject* args)
{
int local = 0;
@@ -2374,11 +2343,11 @@ PyObject* KX_GameObject::PyGetPropertyNames(PyObject* self)
{
PyObject *list= ConvertKeysToPython();
- if(m_attrlist) {
+ if(m_attr_dict) {
PyObject *key, *value;
Py_ssize_t pos = 0;
- while (PyDict_Next(m_attrlist, &pos, &key, &value)) {
+ while (PyDict_Next(m_attr_dict, &pos, &key, &value)) {
PyList_Append(list, key);
}
}
@@ -2685,8 +2654,8 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_GameObject, sendMessage,
"to = Name of object to send the message to")
{
char* subject;
- char* body = "";
- char* to = "";
+ char* body = (char *)"";
+ char* to = (char *)"";
const STR_String& from = GetName();
if (!PyArg_ParseTuple(args, "s|sss:sendMessage", &subject, &body, &to))
@@ -2753,7 +2722,7 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py
*object = static_cast<KX_GameObject*>(value);
/* sets the error */
- if (ValidPythonToGameObject(*object)==false)
+ if ((*object)->IsZombiePyErr())
return false;
return true;
@@ -2769,17 +2738,3 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py
return false;
}
-
-bool ValidPythonToGameObject(KX_GameObject *object)
-{
- if (object->GetSGNode()==NULL) {
- PyErr_Format(
- PyExc_RuntimeError,
- "KX_GameObject \"%s\" is not longer in a scene, "
- "check for this case with the \"isValid\" attribute",
- object->GetName().ReadPtr() );
- return false;
- }
-
- return true;
-} \ No newline at end of file
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index cf0c0e6b0f5..dd85c2f2faa 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -62,7 +62,6 @@ struct Object;
/* utility conversion function */
bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py_none_ok);
-bool ValidPythonToGameObject(KX_GameObject *object);
/**
* KX_GameObject is the main class for dynamic objects.
@@ -119,15 +118,15 @@ public:
// these can be used with property actuators
//
// For the python API, For types that cannot be converted into CValues (lists, dicts, GameObjects)
- // these will be put into "m_attrlist", logic bricks cannot access them.
+ // these will be put into "m_attr_dict", logic bricks cannot access them.
//
// rules for setting attributes.
//
- // * there should NEVER be a CValue and a m_attrlist attribute with matching names. get/sets make sure of this.
- // * if CValue conversion fails, use a PyObject in "m_attrlist"
- // * when assigning a value, first see if it can be a CValue, if it can remove the "m_attrlist" and set the CValue
+ // * there should NEVER be a CValue and a m_attr_dict attribute with matching names. get/sets make sure of this.
+ // * if CValue conversion fails, use a PyObject in "m_attr_dict"
+ // * when assigning a value, first see if it can be a CValue, if it can remove the "m_attr_dict" and set the CValue
//
- PyObject* m_attrlist;
+ PyObject* m_attr_dict;
virtual void /* This function should be virtual - derived classed override it */
Relink(
@@ -814,16 +813,21 @@ public:
virtual PyObject* py_getattro(PyObject *attr);
virtual int py_setattro(PyObject *attr, PyObject *value); // py_setattro method
+ virtual int py_delattro(PyObject *attr);
virtual PyObject* py_repr(void)
{
- if (ValidPythonToGameObject(this)==false)
+ if (IsZombiePyErr())
return NULL;
return PyString_FromString(GetName().ReadPtr());
}
- static PyObject *py_base_getattro_gameobject(PyObject * self, PyObject *attr);
- static int py_base_setattro_gameobject(PyObject * self, PyObject *attr, PyObject *value);
+ /* quite annoying that we need these but the bloody
+ * py_getattro_up and py_setattro_up macro's have a returns in them! */
+ PyObject* py_getattro__internal(PyObject *attr);
+ int py_setattro__internal(PyObject *attr, PyObject *value); // py_setattro method
+
+
KX_PYMETHOD_NOARGS(KX_GameObject,GetPosition);
KX_PYMETHOD_O(KX_GameObject,SetPosition);
KX_PYMETHOD_O(KX_GameObject,SetWorldPosition);
@@ -897,7 +901,6 @@ public:
static PyObject* pyattr_get_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_state(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_meshes(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
- static PyObject* pyattr_get_is_valid(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
/* for dir(), python3 uses __dir__() */
static PyObject* pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
@@ -913,7 +916,6 @@ public:
static PyObject* Map_GetItem(PyObject *self_v, PyObject *item);
static int Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val);
-
private :
/**
@@ -931,5 +933,7 @@ private :
};
+
+
#endif //__KX_GAMEOBJECT
diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp
index 0fcd2c39078..29033c2d802 100644
--- a/source/gameengine/Ketsji/KX_Light.cpp
+++ b/source/gameengine/Ketsji/KX_Light.cpp
@@ -177,14 +177,6 @@ PyObject* KX_LightObject::py_getattro(PyObject *attr)
{
char *attr_str= PyString_AsString(attr);
- if (ValidPythonToGameObject(this)==false) {
- if (!strcmp(attr_str, "isValid")) {
- PyErr_Clear();
- Py_RETURN_FALSE;
- }
- return NULL;
- }
-
if (!strcmp(attr_str, "layer"))
return PyInt_FromLong(m_lightobj.m_layer);
@@ -229,9 +221,6 @@ int KX_LightObject::py_setattro(PyObject *attr, PyObject *pyvalue)
{
char *attr_str= PyString_AsString(attr);
- if (ValidPythonToGameObject(this)==false)
- return -1;
-
if (PyInt_Check(pyvalue))
{
int value = PyInt_AsLong(pyvalue);
@@ -347,7 +336,9 @@ PyTypeObject KX_LightObject::Type = {
0,
0,
py_base_repr,
- 0,0,0,0,0,0,
+ 0,0,
+ &KX_GameObject::Mapping,
+ 0,0,0,
py_base_getattro,
py_base_setattro,
0,0,0,0,0,0,0,0,0,
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index c63167e2d56..c99fa363ffe 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -196,7 +196,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
m_canvasDesignWidth = 0;
m_canvasDesignHeight = 0;
- m_attrlist = PyDict_New(); /* new ref */
+ m_attr_dict = PyDict_New(); /* new ref */
}
@@ -250,8 +250,8 @@ KX_Scene::~KX_Scene()
{
delete m_bucketmanager;
}
- PyDict_Clear(m_attrlist);
- Py_DECREF(m_attrlist);
+ PyDict_Clear(m_attr_dict);
+ Py_DECREF(m_attr_dict);
}
void KX_Scene::SetProjectionMatrix(MT_CmMatrix4x4& pmat)
@@ -924,6 +924,8 @@ 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
@@ -998,6 +1000,7 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
if (m_sceneConverter)
m_sceneConverter->UnregisterGameObject(newobj);
// return value will be 0 if the object is actually deleted (all reference gone)
+
return ret;
}
@@ -1591,7 +1594,7 @@ PyTypeObject KX_Scene::Type = {
py_base_repr,
0,0,0,0,0,0,
py_base_getattro,
- py_base_setattro_scene, /* unlike almost all other types we need out own because user attributes are supported */
+ py_base_setattro,
0,0,0,0,0,0,0,0,0,
Methods
};
@@ -1633,12 +1636,12 @@ PyObject* KX_Scene::pyattr_get_active_camera(void *self_v, const KX_PYATTRIBUTE_
PyObject* KX_Scene::pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_Scene* self= static_cast<KX_Scene*>(self_v);
- /* Useually done by py_getattro_up but in this case we want to include m_attrlist dict */
+ /* Useually done by py_getattro_up but in this case we want to include m_attr_dict dict */
PyObject *dict_str= PyString_FromString("__dict__");
PyObject *dict= py_getattr_dict(self->PyObjectPlus::py_getattro(dict_str), Type.tp_dict);
Py_DECREF(dict_str);
- PyDict_Update(dict, self->m_attrlist);
+ PyDict_Update(dict, self->m_attr_dict);
return dict;
}
@@ -1654,28 +1657,59 @@ PyAttributeDef KX_Scene::Attributes[] = {
{ NULL } //Sentinel
};
+
+PyObject* KX_Scene::py_getattro__internal(PyObject *attr)
+{
+ py_getattro_up(PyObjectPlus);
+}
+
+int KX_Scene::py_setattro__internal(PyObject *attr, PyObject *pyvalue)
+{
+ return PyObjectPlus::py_setattro(attr, pyvalue);
+}
+
PyObject* KX_Scene::py_getattro(PyObject *attr)
{
- PyObject *object = PyDict_GetItem(m_attrlist, attr);
- if (object)
+ PyObject *object = py_getattro__internal(attr);
+
+ if (object==NULL)
{
- Py_INCREF(object);
- return object;
+ PyErr_Clear();
+ object = PyDict_GetItem(m_attr_dict, attr);
+ if(object) {
+ Py_INCREF(object);
+ }
+ else {
+ PyErr_Format(PyExc_AttributeError, "KX_Scene attribute \"%s\" not found", PyString_AsString(attr));
+ }
}
- py_getattro_up(PyObjectPlus);
+ return object;
}
-int KX_Scene::py_delattro(PyObject *attr)
+
+int KX_Scene::py_setattro(PyObject *attr, PyObject *value)
{
- PyDict_DelItem(m_attrlist, attr);
- return 0;
+ int ret= py_setattro__internal(attr, value);
+
+ if (ret==PY_SET_ATTR_MISSING) {
+ if (PyDict_SetItem(m_attr_dict, attr, value)==0) {
+ PyErr_Clear();
+ ret= PY_SET_ATTR_SUCCESS;
+ }
+ else {
+ PyErr_SetString(PyExc_AttributeError, "failed assigning value to KX_Scenes internal dictionary");
+ ret= PY_SET_ATTR_FAIL;
+ }
+ }
+
+ return ret;
}
-/* py_base_setattro_scene deals with setting the dict, it will run if this returns an error */
-int KX_Scene::py_setattro(PyObject *attr, PyObject *pyvalue)
+int KX_Scene::py_delattro(PyObject *attr)
{
- return PyObjectPlus::py_setattro(attr, pyvalue);
+ PyDict_DelItem(m_attr_dict, attr);
+ return 0;
}
KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getLightList,
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index e1e89e253ed..a06c66ec5dd 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -295,7 +295,7 @@ protected:
/**
* This stores anything from python
*/
- PyObject* m_attrlist;
+ PyObject* m_attr_dict;
struct Scene* m_blenderScene;
@@ -597,34 +597,14 @@ public:
/* for dir(), python3 uses __dir__() */
static PyObject* pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
- static int py_base_setattro_scene(PyObject * self, PyObject *attr, PyObject *value)
- {
- if (value==NULL)
- return ((PyObjectPlus*) self)->py_delattro(attr);
-
- int ret= ((PyObjectPlus*) self)->py_setattro(attr, value);
-
- if (ret==PY_SET_ATTR_MISSING) {
- if (PyDict_SetItem(((KX_Scene *) self)->m_attrlist, attr, value)==0) {
- PyErr_Clear();
- ret= PY_SET_ATTR_SUCCESS;
- }
- else {
- PyErr_Format(PyExc_AttributeError, "failed assigning value to KX_Scenes internal dictionary");
- ret= PY_SET_ATTR_FAIL;
- }
- }
-
- return ret;
- }
-
-
virtual PyObject* py_getattro(PyObject *attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */
virtual int py_setattro(PyObject *attr, PyObject *pyvalue);
virtual int py_delattro(PyObject *attr);
virtual PyObject* py_repr(void) { return PyString_FromString(GetName().ReadPtr()); }
+ PyObject* py_getattro__internal(PyObject *attr);
+ int py_setattro__internal(PyObject *attr, PyObject *pyvalue);
/**
* Sets the time the scene was suspended