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

Campbell Barton ideasman42 at gmail.com
Tue Apr 7 13:06:35 CEST 2009


Revision: 19579
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19579
Author:   campbellbarton
Date:     2009-04-07 13:06:35 +0200 (Tue, 07 Apr 2009)

Log Message:
-----------
BGE Python API

Use each types dictionary to store attributes PyAttributeDef's so it uses pythons hash lookup (which it was already doing for methods) rather then doing a string lookup on the array each time.

This also means attributes can be found in the type without having to do a dir() on the instance.

Modified Paths:
--------------
    trunk/blender/source/gameengine/Converter/BL_ActionActuator.cpp
    trunk/blender/source/gameengine/Converter/BL_ShapeActionActuator.cpp
    trunk/blender/source/gameengine/Expressions/PyObjectPlus.cpp
    trunk/blender/source/gameengine/Expressions/PyObjectPlus.h
    trunk/blender/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_DelaySensor.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_ISensor.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_MouseSensor.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_PropertySensor.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_PythonController.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_RandomActuator.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_RandomSensor.cpp
    trunk/blender/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
    trunk/blender/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
    trunk/blender/source/gameengine/Ketsji/KX_CDActuator.cpp
    trunk/blender/source/gameengine/Ketsji/KX_Camera.cpp
    trunk/blender/source/gameengine/Ketsji/KX_CameraActuator.cpp
    trunk/blender/source/gameengine/Ketsji/KX_GameActuator.cpp
    trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp
    trunk/blender/source/gameengine/Ketsji/KX_IpoActuator.cpp
    trunk/blender/source/gameengine/Ketsji/KX_MeshProxy.cpp
    trunk/blender/source/gameengine/Ketsji/KX_NearSensor.cpp
    trunk/blender/source/gameengine/Ketsji/KX_ParentActuator.cpp
    trunk/blender/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
    trunk/blender/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
    trunk/blender/source/gameengine/Ketsji/KX_RadarSensor.cpp
    trunk/blender/source/gameengine/Ketsji/KX_RaySensor.cpp
    trunk/blender/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
    trunk/blender/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
    trunk/blender/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
    trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp
    trunk/blender/source/gameengine/Ketsji/KX_SceneActuator.cpp
    trunk/blender/source/gameengine/Ketsji/KX_TouchSensor.cpp
    trunk/blender/source/gameengine/Ketsji/KX_TrackToActuator.cpp
    trunk/blender/source/gameengine/Ketsji/KX_VisibilityActuator.cpp

Modified: trunk/blender/source/gameengine/Converter/BL_ActionActuator.cpp
===================================================================
--- trunk/blender/source/gameengine/Converter/BL_ActionActuator.cpp	2009-04-07 10:16:26 UTC (rev 19578)
+++ trunk/blender/source/gameengine/Converter/BL_ActionActuator.cpp	2009-04-07 11:06:35 UTC (rev 19579)
@@ -1037,21 +1037,14 @@
 };
 
 PyObject* BL_ActionActuator::py_getattro(PyObject *attr) {
-	PyObject* object = py_getattro_self(Attributes, this, attr);
-	if (object != NULL)
-		return object;
 	py_getattro_up(SCA_IActuator);
 }
 
 int BL_ActionActuator::py_setattro(PyObject *attr, PyObject* value) {
-	int ret = py_setattro_self(Attributes, this, attr, value);
-	if (ret >= 0)
-		return ret;
-	return SCA_IActuator::py_setattro(attr, value);
+	py_setattro_up(SCA_IActuator);
 }
 
 
-
 PyObject* BL_ActionActuator::pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
 {
 	BL_ActionActuator* self= static_cast<BL_ActionActuator*>(self_v);

Modified: trunk/blender/source/gameengine/Converter/BL_ShapeActionActuator.cpp
===================================================================
--- trunk/blender/source/gameengine/Converter/BL_ShapeActionActuator.cpp	2009-04-07 10:16:26 UTC (rev 19578)
+++ trunk/blender/source/gameengine/Converter/BL_ShapeActionActuator.cpp	2009-04-07 11:06:35 UTC (rev 19579)
@@ -486,17 +486,11 @@
 
 
 PyObject* BL_ShapeActionActuator::py_getattro(PyObject* attr) {
-	PyObject* object = py_getattro_self(Attributes, this, attr);
-	if (object != NULL)
-		return object;
 	py_getattro_up(SCA_IActuator);
 }
 
 int BL_ShapeActionActuator::py_setattro(PyObject *attr, PyObject* value) {
-	int ret = py_setattro_self(Attributes, this, attr, value);
-	if (ret >= 0)
-		return ret;
-	return SCA_IActuator::py_setattro(attr, value);
+	py_setattro_up(SCA_IActuator);
 }
 
 /*     setStart                                                              */

Modified: trunk/blender/source/gameengine/Expressions/PyObjectPlus.cpp
===================================================================
--- trunk/blender/source/gameengine/Expressions/PyObjectPlus.cpp	2009-04-07 10:16:26 UTC (rev 19578)
+++ trunk/blender/source/gameengine/Expressions/PyObjectPlus.cpp	2009-04-07 11:06:35 UTC (rev 19579)
@@ -98,6 +98,10 @@
   {NULL, NULL}		/* Sentinel */
 };
 
+PyAttributeDef PyObjectPlus::Attributes[] = {
+	{NULL} //Sentinel
+};
+
 /*------------------------------
  * PyObjectPlus Parents		-- Every class, even the abstract one should have parents
 ------------------------------*/
@@ -136,561 +140,574 @@
 	return 1;
 }
 
-PyObject *PyObjectPlus::py_getattro_self(const PyAttributeDef attrlist[], void *self, PyObject *attr)
+PyObject *PyObjectPlus::py_get_attrdef(void *self, const PyAttributeDef *attrdef)
 {
-	char *attr_str= PyString_AsString(attr);
-
-	const PyAttributeDef *attrdef;
-	for (attrdef=attrlist; attrdef->m_name != NULL; attrdef++)
+	if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_DUMMY)
 	{
-		if (!strcmp(attr_str, attrdef->m_name))
+		// fake attribute, ignore
+		return NULL;
+	}
+	if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_FUNCTION)
+	{
+		// the attribute has no field correspondance, handover processing to function.
+		if (attrdef->m_getFunction == NULL)
+			return NULL;
+		return (*attrdef->m_getFunction)(self, attrdef);
+	}
+	char *ptr = reinterpret_cast<char*>(self)+attrdef->m_offset;
+	if (attrdef->m_length > 1)
+	{
+		PyObject* resultlist = PyList_New(attrdef->m_length);
+		for (unsigned int i=0; i<attrdef->m_length; i++)
 		{
-			if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_DUMMY)
+			switch (attrdef->m_type) {
+			case KX_PYATTRIBUTE_TYPE_BOOL:
+				{
+					bool *val = reinterpret_cast<bool*>(ptr);
+					ptr += sizeof(bool);
+					PyList_SetItem(resultlist,i,PyInt_FromLong(*val));
+					break;
+				}
+			case KX_PYATTRIBUTE_TYPE_SHORT:
+				{
+					short int *val = reinterpret_cast<short int*>(ptr);
+					ptr += sizeof(short int);
+					PyList_SetItem(resultlist,i,PyInt_FromLong(*val));
+					break;
+				}
+			case KX_PYATTRIBUTE_TYPE_ENUM:
+				// enum are like int, just make sure the field size is the same
+				if (sizeof(int) != attrdef->m_size)
+				{
+					Py_DECREF(resultlist);
+					return NULL;
+				}
+				// walkthrough
+			case KX_PYATTRIBUTE_TYPE_INT:
+				{
+					int *val = reinterpret_cast<int*>(ptr);
+					ptr += sizeof(int);
+					PyList_SetItem(resultlist,i,PyInt_FromLong(*val));
+					break;
+				}
+			case KX_PYATTRIBUTE_TYPE_FLOAT:
+				{
+					float *val = reinterpret_cast<float*>(ptr);
+					ptr += sizeof(float);
+					PyList_SetItem(resultlist,i,PyFloat_FromDouble(*val));
+					break;
+				}
+			default:
+				// no support for array of complex data
+				Py_DECREF(resultlist);
+				return NULL;
+			}
+		}
+		return resultlist;
+	}
+	else
+	{
+		switch (attrdef->m_type) {
+		case KX_PYATTRIBUTE_TYPE_BOOL:
 			{
-				// fake attribute, ignore
+				bool *val = reinterpret_cast<bool*>(ptr);
+				return PyInt_FromLong(*val);
+			}
+		case KX_PYATTRIBUTE_TYPE_SHORT:
+			{
+				short int *val = reinterpret_cast<short int*>(ptr);
+				return PyInt_FromLong(*val);
+			}
+		case KX_PYATTRIBUTE_TYPE_ENUM:
+			// enum are like int, just make sure the field size is the same
+			if (sizeof(int) != attrdef->m_size)
+			{
 				return NULL;
 			}
-			if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_FUNCTION)
+			// walkthrough
+		case KX_PYATTRIBUTE_TYPE_INT:
 			{
-				// the attribute has no field correspondance, handover processing to function.
-				if (attrdef->m_getFunction == NULL)
-					return NULL;
-				return (*attrdef->m_getFunction)(self, attrdef);
+				int *val = reinterpret_cast<int*>(ptr);
+				return PyInt_FromLong(*val);
 			}
-			char *ptr = reinterpret_cast<char*>(self)+attrdef->m_offset;
-			if (attrdef->m_length > 1)
+		case KX_PYATTRIBUTE_TYPE_FLOAT:
 			{
-				PyObject* resultlist = PyList_New(attrdef->m_length);
-				for (unsigned int i=0; i<attrdef->m_length; i++)
-				{
-					switch (attrdef->m_type) {
-					case KX_PYATTRIBUTE_TYPE_BOOL:
-						{
-							bool *val = reinterpret_cast<bool*>(ptr);
-							ptr += sizeof(bool);
-							PyList_SetItem(resultlist,i,PyInt_FromLong(*val));
-							break;
-						}
-					case KX_PYATTRIBUTE_TYPE_SHORT:
-						{
-							short int *val = reinterpret_cast<short int*>(ptr);
-							ptr += sizeof(short int);
-							PyList_SetItem(resultlist,i,PyInt_FromLong(*val));
-							break;
-						}
-					case KX_PYATTRIBUTE_TYPE_ENUM:
-						// enum are like int, just make sure the field size is the same
-						if (sizeof(int) != attrdef->m_size)
-						{
-							Py_DECREF(resultlist);
-							return NULL;
-						}
-						// walkthrough
-					case KX_PYATTRIBUTE_TYPE_INT:
-						{
-							int *val = reinterpret_cast<int*>(ptr);
-							ptr += sizeof(int);
-							PyList_SetItem(resultlist,i,PyInt_FromLong(*val));
-							break;
-						}
-					case KX_PYATTRIBUTE_TYPE_FLOAT:
-						{
-							float *val = reinterpret_cast<float*>(ptr);
-							ptr += sizeof(float);
-							PyList_SetItem(resultlist,i,PyFloat_FromDouble(*val));
-							break;
-						}
-					default:
-						// no support for array of complex data
-						Py_DECREF(resultlist);
-						return NULL;
-					}
-				}
-				return resultlist;
+				float *val = reinterpret_cast<float*>(ptr);
+				return PyFloat_FromDouble(*val);
 			}
-			else
+		case KX_PYATTRIBUTE_TYPE_STRING:
 			{
-				switch (attrdef->m_type) {
-				case KX_PYATTRIBUTE_TYPE_BOOL:
-					{
-						bool *val = reinterpret_cast<bool*>(ptr);
-						return PyInt_FromLong(*val);
-					}
-				case KX_PYATTRIBUTE_TYPE_SHORT:
-					{
-						short int *val = reinterpret_cast<short int*>(ptr);
-						return PyInt_FromLong(*val);
-					}
-				case KX_PYATTRIBUTE_TYPE_ENUM:
-					// enum are like int, just make sure the field size is the same
-					if (sizeof(int) != attrdef->m_size)
-					{
-						return NULL;
-					}
-					// walkthrough
-				case KX_PYATTRIBUTE_TYPE_INT:
-					{
-						int *val = reinterpret_cast<int*>(ptr);
-						return PyInt_FromLong(*val);
-					}
-				case KX_PYATTRIBUTE_TYPE_FLOAT:
-					{
-						float *val = reinterpret_cast<float*>(ptr);
-						return PyFloat_FromDouble(*val);
-					}
-				case KX_PYATTRIBUTE_TYPE_STRING:
-					{
-						STR_String *val = reinterpret_cast<STR_String*>(ptr);
-						return PyString_FromString(*val);
-					}
-				default:
-					return NULL;
-				}
+				STR_String *val = reinterpret_cast<STR_String*>(ptr);
+				return PyString_FromString(*val);
 			}
+		default:
+			return NULL;
 		}
 	}
+}
+
+#if 0
+PyObject *PyObjectPlus::py_getattro_self(const PyAttributeDef attrlist[], void *self, PyObject *attr)
+{
+	char *attr_str= PyString_AsString(attr);
+	const PyAttributeDef *attrdef;
+	
+	for (attrdef=attrlist; attrdef->m_name != NULL; attrdef++)
+		if (!strcmp(attr_str, attrdef->m_name))
+			return py_get_attrdef(self, attrdef);
+	
 	return NULL;
 }
+#endif
 
-int PyObjectPlus::py_setattro_self(const PyAttributeDef attrlist[], void *self, PyObject *attr, PyObject *value)
+int PyObjectPlus::py_set_attrdef(void *self, const PyAttributeDef *attrdef, PyObject *value)
 {
-	const PyAttributeDef *attrdef;
 	void *undoBuffer = NULL;
 	void *sourceBuffer = NULL;
 	size_t bufferSize = 0;
-	char *attr_str= PyString_AsString(attr);
-
-	for (attrdef=attrlist; attrdef->m_name != NULL; attrdef++)
+	
+	char *ptr = reinterpret_cast<char*>(self)+attrdef->m_offset;
+	if (attrdef->m_length > 1)
 	{
-		if (!strcmp(attr_str, attrdef->m_name))
+		if (!PySequence_Check(value)) 
 		{
-			if (attrdef->m_access == KX_PYATTRIBUTE_RO ||
-				attrdef->m_type == KX_PYATTRIBUTE_TYPE_DUMMY)
+			PyErr_SetString(PyExc_TypeError, "expected a sequence");
+			return 1;
+		}
+		if (PySequence_Size(value) != attrdef->m_length)
+		{
+			PyErr_SetString(PyExc_TypeError, "incorrect number of elements in sequence");
+			return 1;
+		}
+		switch (attrdef->m_type) 
+		{
+		case KX_PYATTRIBUTE_TYPE_FUNCTION:
+			if (attrdef->m_setFunction == NULL) 
 			{
-				PyErr_SetString(PyExc_AttributeError, "property is read-only");
+				PyErr_SetString(PyExc_AttributeError, "function attribute without function, report to blender.org");
 				return 1;
 			}
-			char *ptr = reinterpret_cast<char*>(self)+attrdef->m_offset;
-			if (attrdef->m_length > 1)
+			return (*attrdef->m_setFunction)(self, attrdef, value);
+		case KX_PYATTRIBUTE_TYPE_BOOL:
+			bufferSize = sizeof(bool);
+			break;
+		case KX_PYATTRIBUTE_TYPE_SHORT:
+			bufferSize = sizeof(short int);
+			break;
+		case KX_PYATTRIBUTE_TYPE_ENUM:
+		case KX_PYATTRIBUTE_TYPE_INT:
+			bufferSize = sizeof(int);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list