[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [22767] branches/blender2.5/blender/source /gameengine: patch from Mitchell Stokes adding dictionary like access to a scene.

Campbell Barton ideasman42 at gmail.com
Tue Aug 25 15:43:21 CEST 2009


Revision: 22767
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22767
Author:   campbellbarton
Date:     2009-08-25 15:43:21 +0200 (Tue, 25 Aug 2009)

Log Message:
-----------
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)

Modified Paths:
--------------
    branches/blender2.5/blender/source/gameengine/Ketsji/KX_Scene.cpp
    branches/blender2.5/blender/source/gameengine/Ketsji/KX_Scene.h
    branches/blender2.5/blender/source/gameengine/PyDoc/GameTypes.py

Modified: branches/blender2.5/blender/source/gameengine/Ketsji/KX_Scene.cpp
===================================================================
--- branches/blender2.5/blender/source/gameengine/Ketsji/KX_Scene.cpp	2009-08-25 12:43:25 UTC (rev 22766)
+++ branches/blender2.5/blender/source/gameengine/Ketsji/KX_Scene.cpp	2009-08-25 13:43:21 UTC (rev 22767)
@@ -1615,7 +1615,10 @@
 	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,9 +1635,116 @@
 	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)
 {
 	KX_Scene* self= static_cast<KX_Scene*>(self_v);
@@ -1765,3 +1875,22 @@
 	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;
+}

Modified: branches/blender2.5/blender/source/gameengine/Ketsji/KX_Scene.h
===================================================================
--- branches/blender2.5/blender/source/gameengine/Ketsji/KX_Scene.h	2009-08-25 12:43:25 UTC (rev 22766)
+++ branches/blender2.5/blender/source/gameengine/Ketsji/KX_Scene.h	2009-08-25 13:43:21 UTC (rev 22767)
@@ -90,6 +90,7 @@
 class KX_Scene : public PyObjectPlus, public SCA_IScene
 {
 	Py_Header;
+	PyObject*	m_attr_dict;
 
 	struct CullingInfo {
 		int m_layer;
@@ -262,15 +263,10 @@
 
 	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 @@
 	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 @@
 	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
 	 */ 

Modified: branches/blender2.5/blender/source/gameengine/PyDoc/GameTypes.py
===================================================================
--- branches/blender2.5/blender/source/gameengine/PyDoc/GameTypes.py	2009-08-25 12:43:25 UTC (rev 22766)
+++ branches/blender2.5/blender/source/gameengine/PyDoc/GameTypes.py	2009-08-25 13:43:21 UTC (rev 22767)
@@ -3868,6 +3868,12 @@
 		
 		@rtype: L{KX_GameObject}
 		"""
+	
+	def get(key, default=None):
+		"""
+		Return the value matching key, or the default value if its not found.
+		@return: The key value or a default.
+		"""
 
 class KX_SceneActuator(SCA_IActuator):
 	"""





More information about the Bf-blender-cvs mailing list