[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17625] branches/blender2.5/blender/source /blender/python/intern/bpy_rna.c: PyRNA - can write variables now (float, int, bool, enums, strings - but not pointers, RNA limitation too).

Campbell Barton ideasman42 at gmail.com
Sat Nov 29 18:58:20 CET 2008


Revision: 17625
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17625
Author:   campbellbarton
Date:     2008-11-29 18:58:17 +0100 (Sat, 29 Nov 2008)

Log Message:
-----------
PyRNA - can write variables now (float, int, bool, enums, strings - but not pointers, RNA limitation too).
also fixed reading enums.

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c

Modified: branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c
===================================================================
--- branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c	2008-11-29 16:52:06 UTC (rev 17624)
+++ branches/blender2.5/blender/source/blender/python/intern/bpy_rna.c	2008-11-29 17:58:17 UTC (rev 17625)
@@ -84,13 +84,22 @@
 	case PROP_ENUM:
 	{		
 		const EnumPropertyItem *item;
-		int totitem;
+		int totitem, i, val;
+
+		val = RNA_property_enum_get(ptr, prop);
 		
 		RNA_property_enum_items(ptr, prop, &item, &totitem);
-		ret = PyUnicode_FromString( item->identifier );
 		
-		if (ret==NULL) {
+		for (i=0; i<totitem; i++) {
+			if (item[i].value == val)
+				break;
+		}
+		
+		if (i<totitem) {
+			ret = PyUnicode_FromString( item[i].identifier );
+		} else {
 			PyErr_SetString(PyExc_AttributeError, "enum not found");
+			ret = NULL;
 		}
 		
 		break;
@@ -111,7 +120,7 @@
 		ret = pyrna_prop_CreatePyObject(ptr, prop);
 		break;
 	default:
-		printf("Warning, unsupported type %d\n", type);
+		PyErr_SetString(PyExc_AttributeError, "unknown type (pyrna_prop_to_py)");
 		ret = NULL;
 		break;
 	}
@@ -119,6 +128,117 @@
 	return ret;
 }
 
+
+static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
+{
+	int ret = 0;
+	int type = RNA_property_type(ptr, prop);
+	int len = RNA_property_array_length(ptr, prop);
+	/* resolve path */
+	
+	if (len > 0) {
+		/* resolve the array from a new pytype */
+		PyErr_SetString(PyExc_TypeError, "array type, cant assign");
+		return -1;
+	}
+	
+	/* see if we can coorce into a python type - PropertyType */
+	switch (type) {
+	case PROP_BOOLEAN:
+	{
+		int param = PyObject_IsTrue( value );
+		
+		if( param == -1 ) {
+			PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
+			ret = -1;
+		} else {
+			RNA_property_boolean_set(ptr, prop, param);
+		}
+		break;
+	}
+	case PROP_INT:
+	{
+		int param = PyLong_AsSsize_t(value);
+		if (PyErr_Occurred()) {
+			PyErr_SetString(PyExc_TypeError, "expected an int type");
+			ret = -1;
+		} else {
+			RNA_property_int_set(ptr, prop, param);
+		}
+		break;
+	}
+	case PROP_FLOAT:
+	{
+		float param = PyFloat_AsDouble(value);
+		if (PyErr_Occurred()) {
+			PyErr_SetString(PyExc_TypeError, "expected a float type");
+			ret = -1;
+		} else {
+			RNA_property_float_set(ptr, prop, param);
+		}
+		break;
+	}
+	case PROP_STRING:
+	{
+		char *param = _PyUnicode_AsString(value);
+		
+		if (param==NULL) {
+			PyErr_SetString(PyExc_TypeError, "expected a string type");
+			ret = -1;
+		} else {
+			RNA_property_string_set(ptr, prop, param);
+		}
+		break;
+	}
+	case PROP_ENUM:
+	{
+		char *param = _PyUnicode_AsString(value);
+		
+		if (param==NULL) {
+			PyErr_SetString(PyExc_TypeError, "expected a string type");
+			ret = -1;
+		} else {
+			const EnumPropertyItem *item;
+			int totitem, i, val;
+			
+			RNA_property_enum_items(ptr, prop, &item, &totitem);
+			
+			for (i=0; i<totitem; i++) {
+				if (strcmp(item[i].identifier, param)==0) {
+					val = item[i].value;
+					break;
+				}
+			}
+			
+			if (i<totitem) {
+				RNA_property_enum_set(ptr, prop, val);
+			} else {
+				PyErr_Format(PyExc_AttributeError, "enum \"%s\" not found", param);
+				ret = -1;
+			}
+		}
+		
+		break;
+	}
+	case PROP_POINTER:
+	{
+		PyErr_SetString(PyExc_AttributeError, "cant assign pointers yet");
+		ret = -1;
+		break;
+	}
+	case PROP_COLLECTION:
+		PyErr_SetString(PyExc_AttributeError, "cant assign to collections");
+		break;
+	default:
+		PyErr_SetString(PyExc_AttributeError, "unknown property type (pyrna_py_to_prop)");
+		ret = -1;
+		break;
+	}
+	
+	return ret;
+}
+
+
 static PyObject * pyrna_prop_to_py_index(PointerRNA *ptr, PropertyRNA *prop, int index)
 {
 	PyObject *ret;
@@ -146,6 +266,57 @@
 	return ret;
 }
 
+static int pyrna_py_to_prop_index(PointerRNA *ptr, PropertyRNA *prop, int index, PyObject *value)
+{
+	int ret = 0;
+	int type = RNA_property_type(ptr, prop);
+	
+	/* resolve path */
+	
+	/* see if we can coorce into a python type - PropertyType */
+	switch (type) {
+	case PROP_BOOLEAN:
+	{
+		int param = PyObject_IsTrue( value );
+		
+		if( param == -1 ) {
+			PyErr_SetString(PyExc_TypeError, "expected True/False or 0/1");
+			ret = -1;
+		} else {
+			RNA_property_boolean_set_array(ptr, prop, index, param);
+		}
+		break;
+	}
+	case PROP_INT:
+	{
+		int param = PyLong_AsSsize_t(value);
+		if (PyErr_Occurred()) {
+			PyErr_SetString(PyExc_TypeError, "expected an int type");
+			ret = -1;
+		} else {
+			RNA_property_int_set_array(ptr, prop, index, param);
+		}
+		break;
+	}
+	case PROP_FLOAT:
+	{
+		float param = PyFloat_AsDouble(value);
+		if (PyErr_Occurred()) {
+			PyErr_SetString(PyExc_TypeError, "expected a float type");
+			ret = -1;
+		} else {
+			RNA_property_float_set_array(ptr, prop, index, param);
+		}
+		break;
+	}
+	default:
+		PyErr_SetString(PyExc_AttributeError, "not an array type");
+		ret = -1;
+		break;
+	}
+	
+	return ret;
+}
 
 //---------------sequence-------------------------------------------
 static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA * self )
@@ -216,10 +387,53 @@
 	return ret;
 }
 
+
+static int pyrna_prop_assign_subscript( BPy_PropertyRNA * self, PyObject *key, PyObject *value )
+{
+	int ret = 0;
+	int keynum;
+	char *keyname = NULL;
+	
+	if (PyUnicode_Check(key)) {
+		keyname = _PyUnicode_AsString(key);
+	} else if (PyLong_Check(key)) {
+		keynum = PyLong_AsSsize_t(key);
+	} else {
+		PyErr_SetString(PyExc_AttributeError, "invalid key, key must be a string or an int");
+		return -1;
+	}
+	
+	if (RNA_property_type(&self->ptr, self->prop) == PROP_COLLECTION) {
+		PyErr_SetString(PyExc_AttributeError, "assignment is not supported for collections (yet)");
+		ret = -1;
+	} else if (keyname) {
+		PyErr_SetString(PyExc_AttributeError, "string keys are only supported for collections");
+		ret = -1;
+	} else {
+		int len = RNA_property_array_length(&self->ptr, self->prop);
+		
+		if (len==0) { /* not an array*/
+			PyErr_Format(PyExc_AttributeError, "not an array or collection %d", keynum);
+			ret = -1;
+		}
+		
+		if (keynum >= len){
+			PyErr_SetString(PyExc_AttributeError, "index out of range");
+			ret = -1;
+		} else { /* not an array*/
+			ret = pyrna_py_to_prop_index(&self->ptr, self->prop, keynum, value);
+		}
+	}
+	
+	return ret;
+}
+
+
+
 static PyMappingMethods pyrna_prop_as_mapping = {
 	( inquiry ) pyrna_prop_len,	/* mp_length */
 	( binaryfunc ) pyrna_prop_subscript,	/* mp_subscript */
-	( objobjargproc ) 0,	/* mp_ass_subscript */
+	( objobjargproc ) pyrna_prop_assign_subscript,	/* mp_ass_subscript */
 };
 
 //---------------getattr--------------------------------------------
@@ -257,18 +471,32 @@
 			ret = NULL;
 		} else {
 			ret = pyrna_prop_to_py(&self->ptr, prop);
-			
-			if (ret==NULL) {
-				PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" could not be converted to a python type", name);
-			}
 		}
 	}
 	
+	return ret;
+}
 
+//--------------- setattr-------------------------------------------
+static int pyrna_struct_setattr( BPy_StructRNA * self, char *name, PyObject * value )
+{
+	int ret = 0;
+	PropertyRNA *prop;
 	
+	prop = RNA_struct_find_property(&self->ptr, name);
+	
+	if (prop==NULL) {
+		PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" not found", name);
+		ret = -1;
+	} else {
+		/* pyrna_py_to_prop sets its own exceptions */
+		ret = pyrna_py_to_prop(&self->ptr, prop, value);
+	}
+	
 	return ret;
 }
 
+
 PyObject *pyrna_prop_keys(BPy_PropertyRNA *self)
 {
 	PyObject *ret;
@@ -397,8 +625,8 @@
 	/* methods */
 	NULL,						/* tp_dealloc */
 	NULL,                       /* printfunc tp_print; */
-	( getattrfunc ) pyrna_struct_getattr,			/* getattrfunc tp_getattr; */
-	NULL,                       /* setattrfunc tp_setattr; */
+	( getattrfunc ) pyrna_struct_getattr,		/* getattrfunc tp_getattr; */
+	( setattrfunc ) pyrna_struct_setattr,		/* setattrfunc tp_setattr; */
 	( cmpfunc ) pyrna_struct_compare,	/* tp_compare */
 	( reprfunc ) pyrna_struct_repr,	/* tp_repr */
 





More information about the Bf-blender-cvs mailing list