[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [19511] trunk/blender/source/gameengine: BGE Python

Campbell Barton ideasman42 at gmail.com
Fri Apr 3 04:16:57 CEST 2009


Revision: 19511
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19511
Author:   campbellbarton
Date:     2009-04-03 04:16:56 +0200 (Fri, 03 Apr 2009)

Log Message:
-----------
BGE Python
- Bugfix for running dir() on all BGE python objects. was not getting the immediate methods and attributes for each class.
- Use attributes for KX_Scene (so they are included with dir())
- Override __dict__ attributes for KX_Scene and KX_GameObject so custom properties are included with a dir()

Modified Paths:
--------------
    trunk/blender/source/gameengine/Expressions/PyObjectPlus.h
    trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp
    trunk/blender/source/gameengine/Ketsji/KX_GameObject.h
    trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp
    trunk/blender/source/gameengine/Ketsji/KX_Scene.h

Modified: trunk/blender/source/gameengine/Expressions/PyObjectPlus.h
===================================================================
--- trunk/blender/source/gameengine/Expressions/PyObjectPlus.h	2009-04-02 23:22:00 UTC (rev 19510)
+++ trunk/blender/source/gameengine/Expressions/PyObjectPlus.h	2009-04-03 02:16:56 UTC (rev 19511)
@@ -100,9 +100,8 @@
 		PyErr_Clear(); \
 		rvalue = Parent::_getattr(attr); \
 	} \
-	if ((rvalue == NULL) && !strcmp(attr, "__dict__")) {\
-		PyErr_Clear(); \
-		rvalue = _getattr_dict(Parent::_getattr(attr), Methods, Attributes); \
+	if (strcmp(attr, "__dict__")==0) {\
+		rvalue = _getattr_dict(rvalue, Methods, Attributes); \
 	} \
 	return rvalue; \
 

Modified: trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp	2009-04-02 23:22:00 UTC (rev 19510)
+++ trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp	2009-04-03 02:16:56 UTC (rev 19511)
@@ -942,14 +942,14 @@
 }
 
 
-
+static MT_Point3 dummy_point= MT_Point3(0.0, 0.0, 0.0);
 const MT_Point3& KX_GameObject::NodeGetWorldPosition() const
 {
 	// check on valid node in case a python controller holds a reference to a deleted object
 	if (GetSGNode())
 		return GetSGNode()->GetWorldPosition();
 	else
-		return MT_Point3(0.0, 0.0, 0.0);
+		return dummy_point;
 }
 
 /* Suspend/ resume: for the dynamic behaviour, there is a simple
@@ -1043,6 +1043,7 @@
 	KX_PYATTRIBUTE_RW_FUNCTION("scaling",	KX_GameObject, pyattr_get_scaling,	pyattr_set_scaling),
 	KX_PYATTRIBUTE_RW_FUNCTION("timeOffset",KX_GameObject, pyattr_get_timeOffset,pyattr_set_timeOffset),
 	KX_PYATTRIBUTE_RW_FUNCTION("state",		KX_GameObject, pyattr_get_state,	pyattr_set_state),
+	KX_PYATTRIBUTE_RO_FUNCTION("__dict__",	KX_GameObject, pyattr_get_dir_dict),
 	{NULL} //Sentinel
 };
 
@@ -1412,16 +1413,37 @@
 	return 0;
 }
 
+/* __dict__ only for the purpose of giving useful dir() results */
+PyObject* KX_GameObject::pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+	KX_GameObject* self= static_cast<KX_GameObject*>(self_v);
+	PyObject *dict= _getattr_dict(self->SCA_IObject::_getattr("__dict__"), KX_GameObject::Methods, KX_GameObject::Attributes);
+	
+	if(dict==NULL)
+		return NULL;
+	
+	/* Not super fast getting as a list then making into dict keys but its only for dir() */
+	PyObject *list= self->ConvertKeysToPython();
+	if(list)
+	{
+		int i;
+		for(i=0; i<PyList_Size(list); i++)
+			PyDict_SetItem(dict, PyList_GET_ITEM(list, i), Py_None);
+	}
+	else
+		PyErr_Clear();
+	
+	Py_DECREF(list);
+	
+	return dict;
+}
+
 PyObject* KX_GameObject::_getattr(const char *attr)
 {
 	PyObject* object = _getattr_self(Attributes, this, attr);
 	if (object != NULL)
 		return object;
 	
-	if (!strcmp(attr, "__dict__")) { /* python 3.0 uses .__dir__()*/
-		return _getattr_dict(SCA_IObject::_getattr(attr), Methods, Attributes);
-	}
-	
 	_getattr_up(SCA_IObject);
 }
 

Modified: trunk/blender/source/gameengine/Ketsji/KX_GameObject.h
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_GameObject.h	2009-04-02 23:22:00 UTC (rev 19510)
+++ trunk/blender/source/gameengine/Ketsji/KX_GameObject.h	2009-04-03 02:16:56 UTC (rev 19511)
@@ -822,6 +822,9 @@
 	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);
 	
+	/* for dir(), python3 uses __dir__() */
+	static PyObject*	pyattr_get_dir_dict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+	
 	/* getitem/setitem */
 	static int					Map_Len(PyObject* self);
 	static PyMappingMethods	Mapping;

Modified: trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp	2009-04-02 23:22:00 UTC (rev 19510)
+++ trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp	2009-04-03 02:16:56 UTC (rev 19511)
@@ -32,7 +32,6 @@
 #pragma warning (disable : 4786)
 #endif //WIN32
 
-
 #include "KX_Scene.h"
 #include "MT_assert.h"
 
@@ -1551,35 +1550,57 @@
 	{NULL,NULL} //Sentinel
 };
 
+PyObject* KX_Scene::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+	KX_Scene* self= static_cast<KX_Scene*>(self_v);
+	return PyString_FromString(self->GetName().ReadPtr());
+}
+
+PyObject* KX_Scene::pyattr_get_objects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+	KX_Scene* self= static_cast<KX_Scene*>(self_v);
+	return self->GetObjectList()->AddRef();
+}
+
+PyObject* KX_Scene::pyattr_get_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+	KX_Scene* self= static_cast<KX_Scene*>(self_v);
+	return self->GetActiveCamera()->AddRef();
+}
+
+/* __dict__ only for the purpose of giving useful dir() results */
+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 _getattr_up but in this case we want to include m_attrlist dict */
+	PyObject *dict= _getattr_dict(self->PyObjectPlus::_getattr("__dict__"), KX_Scene::Methods, KX_Scene::Attributes);
+	
+	PyDict_Update(dict, self->m_attrlist);
+	return dict;
+}
+
 PyAttributeDef KX_Scene::Attributes[] = {
+	KX_PYATTRIBUTE_RO_FUNCTION("name",			KX_Scene, pyattr_get_name),
+	KX_PYATTRIBUTE_RO_FUNCTION("objects",		KX_Scene, pyattr_get_objects),
+	KX_PYATTRIBUTE_RO_FUNCTION("active_camera",	KX_Scene, pyattr_get_active_camera),
+	KX_PYATTRIBUTE_BOOL_RO("suspended",			KX_Scene, m_suspend),
+	KX_PYATTRIBUTE_BOOL_RO("activity_culling",	KX_Scene, m_activity_culling),
+	KX_PYATTRIBUTE_FLOAT_RW("activity_culling_radius", 0.5f, FLT_MAX, KX_Scene, m_activity_box_radius),
+	KX_PYATTRIBUTE_RO_FUNCTION("__dict__",		KX_Scene, pyattr_get_dir_dict),
 	{ NULL }	//Sentinel
 };
 
 PyObject* KX_Scene::_getattr(const char *attr)
 {
-	if (!strcmp(attr, "name"))
-		return PyString_FromString(GetName());
+	PyObject* object = _getattr_self(Attributes, this, attr);
+	if (object != NULL)
+		return object;
 	
-	if (!strcmp(attr, "objects"))
-		return (PyObject*) m_objectlist->AddRef();
-	
-	if (!strcmp(attr, "active_camera"))
-		return (PyObject*) GetActiveCamera()->AddRef();
-	
-	if (!strcmp(attr, "suspended"))
-		return PyInt_FromLong(m_suspend);
-	
-	if (!strcmp(attr, "activity_culling"))
-		return PyInt_FromLong(m_activity_culling);
-	
-	if (!strcmp(attr, "activity_culling_radius"))
-		return PyFloat_FromDouble(m_activity_box_radius);
-	
-	PyObject* value = PyDict_GetItemString(m_attrlist, attr);
-	if (value)
+	object = PyDict_GetItemString(m_attrlist, attr);
+	if (object)
 	{
-		Py_INCREF(value);
-		return value;
+		Py_INCREF(object);
+		return object;
 	}
 	
 	_getattr_up(PyObjectPlus);

Modified: trunk/blender/source/gameengine/Ketsji/KX_Scene.h
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_Scene.h	2009-04-02 23:22:00 UTC (rev 19510)
+++ trunk/blender/source/gameengine/Ketsji/KX_Scene.h	2009-04-03 02:16:56 UTC (rev 19511)
@@ -565,6 +565,15 @@
 	KX_PYMETHOD_DOC(KX_Scene, setSceneViewport);
 	*/
 
+	/* attributes */
+	static PyObject*	pyattr_get_name(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+	static PyObject*	pyattr_get_objects(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+	static PyObject*	pyattr_get_active_camera(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);
+	
+
 	virtual PyObject* _getattr(const char *attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */
 	virtual int _setattr(const char *attr, PyObject *pyvalue);
 	virtual int _delattr(const char *attr);





More information about the Bf-blender-cvs mailing list