diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-08-25 17:43:21 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-08-25 17:43:21 +0400 |
commit | 855974dad931bcba8a63260d1f642da49902d569 (patch) | |
tree | 09f71f7f16aee22229f41e91583a1535ce701b7a /source/gameengine/Ketsji | |
parent | 8aa6f672bab266986c7d775cfb01c48d834d3ad9 (diff) |
patch from Mitchell Stokes adding dictionary like access to a scene. (like KX_GameObjects have)
val = scene["prop"]
scene["prop"] = newval
if "prop" in scene: ...
val = scene.get("prop", fallback_val)
Diffstat (limited to 'source/gameengine/Ketsji')
-rw-r--r-- | source/gameengine/Ketsji/KX_Scene.cpp | 131 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_Scene.h | 16 |
2 files changed, 139 insertions, 8 deletions
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 5c19911fe58..a9bb583bba7 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -1615,7 +1615,10 @@ PyTypeObject KX_Scene::Type = { 0, 0, py_base_repr, - 0,0,0,0,0,0,0,0,0, + 0, + &Sequence, + &Mapping, + 0,0,0,0,0,0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 0,0,0,0,0,0,0, Methods, @@ -1632,8 +1635,115 @@ PyMethodDef KX_Scene::Methods[] = { KX_PYMETHODTABLE_NOARGS(KX_Scene, getName), KX_PYMETHODTABLE(KX_Scene, addObject), + /* dict style access */ + KX_PYMETHODTABLE(KX_Scene, get), + {NULL,NULL} //Sentinel }; +static PyObject *Map_GetItem(PyObject *self_v, PyObject *item) +{ + KX_Scene* self= static_cast<KX_Scene*>BGE_PROXY_REF(self_v); + const char *attr_str= _PyUnicode_AsString(item); + PyObject* pyconvert; + + if (self==NULL) { + PyErr_SetString(PyExc_SystemError, "val = scene[key]: KX_Scene, "BGE_PROXY_ERROR_MSG); + return NULL; + } + + if (self->m_attr_dict && (pyconvert=PyDict_GetItem(self->m_attr_dict, item))) { + + if (attr_str) + PyErr_Clear(); + Py_INCREF(pyconvert); + return pyconvert; + } + else { + if(attr_str) PyErr_Format(PyExc_KeyError, "value = scene[key]: KX_Scene, key \"%s\" does not exist", attr_str); + else PyErr_SetString(PyExc_KeyError, "value = scene[key]: KX_Scene, key does not exist"); + return NULL; + } + +} + +static int Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val) +{ + KX_Scene* self= static_cast<KX_Scene*>BGE_PROXY_REF(self_v); + const char *attr_str= _PyUnicode_AsString(key); + if(attr_str==NULL) + PyErr_Clear(); + + if (self==NULL) { + PyErr_SetString(PyExc_SystemError, "scene[key] = value: KX_Scene, "BGE_PROXY_ERROR_MSG); + return -1; + } + + if (val==NULL) { /* del ob["key"] */ + int del= 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, "scene[key] = value: KX_Scene, key \"%s\" could not be set", attr_str); + else PyErr_SetString(PyExc_KeyError, "del scene[key]: KX_Scene, key could not be deleted"); + return -1; + } + else if (self->m_attr_dict) { + PyErr_Clear(); /* PyDict_DelItem sets an error when it fails */ + } + } + else { /* ob["key"] = value */ + int set = 0; + + if (self->m_attr_dict==NULL) /* lazy init */ + self->m_attr_dict= PyDict_New(); + + + if(PyDict_SetItem(self->m_attr_dict, key, val)==0) + set= 1; + else + PyErr_SetString(PyExc_KeyError, "scene[key] = value: KX_Scene, key not be added to internal dictionary"); + + if(set==0) + return -1; /* pythons error value */ + + } + + return 0; /* success */ +} + +static int Seq_Contains(PyObject *self_v, PyObject *value) +{ + KX_Scene* self= static_cast<KX_Scene*>BGE_PROXY_REF(self_v); + + if (self==NULL) { + PyErr_SetString(PyExc_SystemError, "val in scene: KX_Scene, "BGE_PROXY_ERROR_MSG); + return -1; + } + + if (self->m_attr_dict && PyDict_GetItem(self->m_attr_dict, value)) + return 1; + + return 0; +} + +PyMappingMethods KX_Scene::Mapping = { + (lenfunc)NULL , /*inquiry mp_length */ + (binaryfunc)Map_GetItem, /*binaryfunc mp_subscript */ + (objobjargproc)Map_SetItem, /*objobjargproc mp_ass_subscript */ +}; + +PySequenceMethods KX_Scene::Sequence = { + NULL, /* Cant set the len otherwise it can evaluate as false */ + NULL, /* sq_concat */ + NULL, /* sq_repeat */ + NULL, /* sq_item */ + NULL, /* sq_slice */ + NULL, /* sq_ass_item */ + NULL, /* sq_ass_slice */ + (objobjproc)Seq_Contains, /* sq_contains */ +}; PyObject* KX_Scene::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { @@ -1765,3 +1875,22 @@ KX_PYMETHODDEF_DOC(KX_Scene, addObject, replica->Release(); return replica->GetProxy(); } + +/* Matches python dict.get(key, [default]) */ +KX_PYMETHODDEF_DOC(KX_Scene, get, "") +{ + PyObject *key; + PyObject* def = Py_None; + PyObject* ret; + + if (!PyArg_ParseTuple(args, "O|O:get", &key, &def)) + return NULL; + + if (m_attr_dict && (ret=PyDict_GetItem(m_attr_dict, key))) { + Py_INCREF(ret); + return ret; + } + + Py_INCREF(def); + return def; +} diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index f48e9520f53..8d7c0ad8dec 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -90,6 +90,7 @@ struct KX_ClientObjectInfo; class KX_Scene : public PyObjectPlus, public SCA_IScene { Py_Header; + PyObject* m_attr_dict; struct CullingInfo { int m_layer; @@ -262,15 +263,10 @@ protected: double m_suspendedtime; double m_suspendeddelta; - - /** - * This stores anything from python - */ - PyObject* m_attr_dict; struct Scene* m_blenderScene; -public: +public: KX_Scene(class SCA_IInputDevice* keyboarddevice, class SCA_IInputDevice* mousedevice, class NG_NetworkDeviceInterface* ndi, @@ -525,6 +521,8 @@ public: KX_PYMETHOD_DOC_NOARGS(KX_Scene, getObjectList); KX_PYMETHOD_DOC_NOARGS(KX_Scene, getName); KX_PYMETHOD_DOC(KX_Scene, addObject); + KX_PYMETHOD_DOC(KX_Scene, get); + /* KX_PYMETHOD_DOC(KX_Scene, getActiveCamera); KX_PYMETHOD_DOC(KX_Scene, getActiveCamera); @@ -549,7 +547,11 @@ public: static int pyattr_set_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); virtual PyObject* py_repr(void) { return PyUnicode_FromString(GetName().ReadPtr()); } - + + /* getitem/setitem */ + static PyMappingMethods Mapping; + static PySequenceMethods Sequence; + /** * Sets the time the scene was suspended */ |