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 */
 


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to