- new property attribute - default_array, which returns a variable size array useful...
authorCampbell Barton <ideasman42@gmail.com>
Tue, 15 Sep 2009 10:01:20 +0000 (10:01 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 15 Sep 2009 10:01:20 +0000 (10:01 +0000)
- updated python api to check for array types rather then the length since a variable length array can be 1 or 0 length.
- python docgen added .0 to the end of floats which messed up values like 1e-05

source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_particle.c
source/blender/makesrna/intern/rna_rna.c
source/blender/python/epy_doc_gen.py
source/blender/python/intern/bpy_rna.c

index 05f39d738427cb28aa4e7da3bf774a776bb2c6fa..ca3ac62ba00313ac5be54a0c4113cbb48d26a75c 100644 (file)
@@ -586,6 +586,7 @@ PropertyUnit RNA_property_unit(PropertyRNA *prop);
 int RNA_property_flag(PropertyRNA *prop);
 
 int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop);
+int RNA_property_array_check(PointerRNA *ptr, PropertyRNA *prop);
 int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dimension);
 int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[]);
 char RNA_property_array_item_char(PropertyRNA *prop, int index);
index e4bda24cf20171b919d3819771472404c4df39bc..9472cdb300cebb476e5b3c1f0b1cb01cc9efd727 100644 (file)
@@ -225,6 +225,18 @@ static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
        }
 }
 
+static int rna_ensure_property_array_check(PointerRNA *ptr, PropertyRNA *prop)
+{
+       if(prop->magic == RNA_MAGIC) {
+               return (prop->getlength || prop->totarraylength) ? 1:0;
+       }
+       else {
+               IDProperty *idprop= (IDProperty*)prop;
+
+               return idprop->type == IDP_ARRAY ? 1:0;
+       }
+}
+
 static void rna_ensure_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int length[])
 {
        if(prop->magic == RNA_MAGIC) {
@@ -574,6 +586,11 @@ int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
        return rna_ensure_property_array_length(ptr, prop);
 }
 
+int RNA_property_array_check(PointerRNA *ptr, PropertyRNA *prop)
+{
+       return rna_ensure_property_array_check(ptr, prop);
+}
+
 /* used by BPY to make an array from the python object */
 int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[])
 {
index e6f0a462f030514736c2f88175ec640b4fb8b73c..bbbb13c6e97760d17fa0bd4e269a6ad7505f2524 100644 (file)
@@ -254,7 +254,7 @@ static void rna_Particle_redo_child(bContext *C, PointerRNA *ptr)
 }
 static void rna_Particle_hair_dynamics(bContext *C, PointerRNA *ptr)
 {
-       Scene *scene = CTX_data_scene(C);
+       /* Scene *scene = CTX_data_scene(C); */
        ParticleSystem *psys = (ParticleSystem*)ptr->data;
        
        if(psys && !psys->clmd) {
index 8df6398f1f4808f04bab65683d9f29661de24fbf..196d25ada86e6d15abea272e744a59dae011ba26 100644 (file)
@@ -458,6 +458,62 @@ static int rna_IntProperty_default_get(PointerRNA *ptr)
        rna_idproperty_check(&prop, ptr);
        return ((IntPropertyRNA*)prop)->defaultvalue;
 }
+/* int/float/bool */
+static int rna_NumberProperty_default_array_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
+{
+       PropertyRNA *prop= (PropertyRNA*)ptr->data;
+       rna_idproperty_check(&prop, ptr);
+
+       length[0]= prop->totarraylength;
+
+       return length[0];
+}
+static void rna_IntProperty_default_array_get(PointerRNA *ptr, int *values)
+{
+       PropertyRNA *prop= (PropertyRNA*)ptr->data;
+       IntPropertyRNA *nprop= (IntPropertyRNA*)prop;
+       rna_idproperty_check(&prop, ptr);
+
+       if(nprop->defaultarray) {
+               memcpy(values, nprop->defaultarray, prop->totarraylength * sizeof(int));
+       }
+       else {
+               int i;
+               for(i=0; i < prop->totarraylength; i++)
+                       values[i]= nprop->defaultvalue;
+       }
+}
+static void rna_BoolProperty_default_array_get(PointerRNA *ptr, int *values)
+{
+       PropertyRNA *prop= (PropertyRNA*)ptr->data;
+       BooleanPropertyRNA *nprop= (BooleanPropertyRNA*)prop;
+       rna_idproperty_check(&prop, ptr);
+
+       if(nprop->defaultarray) {
+               memcpy(values, nprop->defaultarray, prop->totarraylength * sizeof(int));
+       }
+       else {
+               int i;
+               for(i=0; i < prop->totarraylength; i++)
+                       values[i]= nprop->defaultvalue;
+       }
+}
+static void rna_FloatProperty_default_array_get(PointerRNA *ptr, float *values)
+{
+       PropertyRNA *prop= (PropertyRNA*)ptr->data;
+       FloatPropertyRNA *nprop= (FloatPropertyRNA*)prop;
+       rna_idproperty_check(&prop, ptr);
+
+       if(nprop->defaultarray) {
+               memcpy(values, nprop->defaultarray, prop->totarraylength * sizeof(float));
+       }
+       else {
+               int i;
+               for(i=0; i < prop->totarraylength; i++)
+                       values[i]= nprop->defaultvalue;
+       }
+}
+
 static int rna_IntProperty_hard_min_get(PointerRNA *ptr)
 {
        PropertyRNA *prop= (PropertyRNA*)ptr->data;
@@ -932,13 +988,27 @@ static void rna_def_number_property(StructRNA *srna, PropertyType type)
        }
 
 
-#if 0 // XXX - Variable length arrays
        prop= RNA_def_property(srna, "default_array", type, PROP_NONE);
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-       if(type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_default_array_get", NULL, NULL);
-       else RNA_def_property_float_funcs(prop, "rna_FloatProperty_default_array_get", NULL, NULL);
-       RNA_def_property_ui_text(prop, "Default", "Default value for this number");
-#endif
+       RNA_def_property_array(prop, RNA_MAX_ARRAY_DIMENSION); /* no fixed default length, important its not 0 though */
+       RNA_def_property_flag(prop, PROP_DYNAMIC);
+       RNA_def_property_dynamic_array_funcs(prop, "rna_NumberProperty_default_array_get_length"); /* same for all types */
+
+       switch(type) {
+               case PROP_BOOLEAN:
+                       RNA_def_property_boolean_funcs(prop, "rna_BoolProperty_default_array_get", NULL);
+                       break;
+               case PROP_INT:
+                       RNA_def_property_int_funcs(prop, "rna_IntProperty_default_array_get", NULL, NULL);
+                       break;
+               case PROP_FLOAT:
+                       RNA_def_property_float_funcs(prop, "rna_FloatProperty_default_array_get", NULL, NULL);
+                       break;
+               default:
+                       break;
+       }
+       RNA_def_property_ui_text(prop, "Default Array", "Default value for this array");
+
 
        prop= RNA_def_property(srna, "array_length", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
index c2ef6bbc0d09b96dfefac21f32250e369c977140..4ff5c8102e20e86e888ecf7a45df5ebca2ebaaf2 100644 (file)
@@ -225,7 +225,7 @@ def write_func(rna, ident, out, func_type):
                        elif rna_prop_type=='float':
                                if length==0:
                                        val_str= '%g' % val
-                                       if '.' not in val_str:
+                                       if '.' not in val_str and '-' not in val_str: # value could be 1e-05
                                                val_str += '.0'
                                else:
                                        # array
index dd6bc35fc0a8ec7d631d74ea6602d2f71ece6776..820f96f1e817d458c2659d9ec24575af3528479b 100644 (file)
@@ -349,9 +349,8 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
 {
        PyObject *ret;
        int type = RNA_property_type(prop);
-       int len = RNA_property_array_length(ptr, prop);
 
-       if (len > 0) {
+       if (RNA_property_array_check(ptr, prop)) {
                return pyrna_py_from_array(ptr, prop);
        }
        
@@ -521,9 +520,10 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
 {
        /* XXX hard limits should be checked here */
        int type = RNA_property_type(prop);
-       int len = RNA_property_array_length(ptr, prop);
        
-       if (len > 0) {
+
+       if (RNA_property_array_check(ptr, prop)) {
+
                /* char error_str[512]; */
                int ok= 1;
 
@@ -819,13 +819,11 @@ static Py_ssize_t pyrna_prop_len( BPy_PropertyRNA * self )
        
        if (RNA_property_type(self->prop) == PROP_COLLECTION) {
                len = RNA_property_collection_length(&self->ptr, self->prop);
-       } else {
+       } else if (RNA_property_array_check(&self->ptr, self->prop)) {
                len = pyrna_prop_array_length(self);
-               
-               if (len==0) { /* not an array*/
-                       PyErr_SetString(PyExc_AttributeError, "len() only available for collection and array RNA types");
-                       return -1;
-               }
+       } else {
+               PyErr_SetString(PyExc_AttributeError, "len() only available for collection and array RNA types");
+               len = -1; /* error value */
        }
        
        return len;
@@ -979,7 +977,7 @@ static PyObject *pyrna_prop_subscript( BPy_PropertyRNA * self, PyObject *key )
 {
        if (RNA_property_type(self->prop) == PROP_COLLECTION) {
                return prop_subscript_collection(self, key);
-       } else if (RNA_property_array_length(&self->ptr, self->prop)) { /* zero length means its not an array */
+       } else if (RNA_property_array_check(&self->ptr, self->prop)) {
                return prop_subscript_array(self, key);
        } 
 
@@ -1681,32 +1679,31 @@ static  PyObject *pyrna_prop_foreach_set(BPy_PropertyRNA *self, PyObject *args)
 PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
 {
        /* Try get values from a collection */
-       PyObject *ret = pyrna_prop_values(self);
+       PyObject *ret;
        
-       if (ret==NULL) {
-               /* collection did not work, try array */
+       if(RNA_property_array_check(&self->ptr, self->prop)) {
                int len = pyrna_prop_array_length(self);
+               int i;
+               PyErr_Clear();
+               ret = PyList_New(len);
                
-               if (len) {
-                       int i;
-                       PyErr_Clear();
-                       ret = PyList_New(len);
-                       
-                       for (i=0; i < len; i++) {
-                               PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(self, i));
-                       }
+               for (i=0; i < len; i++) {
+                       PyList_SET_ITEM(ret, i, pyrna_prop_to_py_index(self, i));
                }
        }
-       
-       if (ret) {
-               /* we know this is a list so no need to PyIter_Check */
-               PyObject *iter = PyObject_GetIter(ret); 
-               Py_DECREF(ret);
-               return iter;
+       else if (ret = pyrna_prop_values(self)) {
+               /* do nothing */
+       }
+       else {
+               PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not iterable" );
+               return NULL;
        }
        
-       PyErr_SetString( PyExc_TypeError, "this BPy_PropertyRNA object is not iterable" );
-       return NULL;
+       
+       /* we know this is a list so no need to PyIter_Check */
+       PyObject *iter = PyObject_GetIter(ret);
+       Py_DECREF(ret);
+       return iter;
 }
 
 static struct PyMethodDef pyrna_struct_methods[] = {
@@ -1776,11 +1773,12 @@ PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
 {
        PyObject *ret;
        int type = RNA_property_type(prop);
-       int len = RNA_property_array_length(ptr, prop);
 
        int a;
 
-       if(len > 0) {
+       if(RNA_property_array_check(ptr, prop)) {
+               int len = RNA_property_array_length(ptr, prop);
+
                /* resolve the array from a new pytype */
                ret = PyTuple_New(len);