diff options
author | Campbell Barton <ideasman42@gmail.com> | 2008-11-29 20:58:17 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2008-11-29 20:58:17 +0300 |
commit | 2ff4ac139ba430e606accf44874a3fce10e9c635 (patch) | |
tree | 60fac6db4e4ad9c9f975a8a043ab8a5af9136557 /source/blender/python/intern | |
parent | 3b59a18f53581d4682d9c4b4c87444c9fae5cf1e (diff) |
PyRNA - can write variables now (float, int, bool, enums, strings - but not pointers, RNA limitation too).
also fixed reading enums.
Diffstat (limited to 'source/blender/python/intern')
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 250 |
1 files changed, 239 insertions, 11 deletions
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index d2ab2a6d8df..dfecf6fb010 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -84,13 +84,22 @@ static PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) 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 @@ static PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) 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 @@ static PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop) 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 @@ static PyObject * pyrna_prop_to_py_index(PointerRNA *ptr, PropertyRNA *prop, int 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 @@ static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key ) 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 @@ static PyObject *pyrna_struct_getattr( BPy_StructRNA * self, char *name ) 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 @@ PyTypeObject pyrna_struct_Type = { /* 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 */ |