From 82cf2aebba1c340c1c4fffde1e89fc80a4591fea Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 26 Dec 2008 20:38:52 +0000 Subject: RNA: * Added support for using pointers + collections as operator properties, but with the restriction that they must point to other type derived from ID property groups. The "add" function for these properties will allocate a new ID property group and point to that. * Added support for arrays with type IDP_GROUP in ID properties. * Fix bug getting/setting float array values. Example code for collections, note the "OperatorMousePath" type is defined in rna_wm.c and has a float[2] property named "loc". Defining the operator property: prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath); Adding values: PointerRNA itemptr; float loc[2] = {1, 1}, RNA_collection_add(op->ptr, "path", &itemptr); RNA_float_set_array(&itemptr, "loc", loc); Iterating: RNA_BEGIN(op->ptr, itemptr, "path") { float loc[2]; RNA_float_get_array(&itemptr, "loc", loc); printf("Location: %f %f\n", loc[0], loc[1]); } RNA_END; --- source/blender/blenkernel/intern/idprop.c | 68 ++++++-- source/blender/blenloader/intern/readfile.c | 28 ++-- source/blender/blenloader/intern/writefile.c | 8 + source/blender/makesrna/RNA_access.h | 26 ++- source/blender/makesrna/RNA_define.h | 1 + source/blender/makesrna/RNA_types.h | 1 + source/blender/makesrna/intern/makesrna.c | 24 +-- source/blender/makesrna/intern/rna_ID.c | 5 +- source/blender/makesrna/intern/rna_access.c | 224 +++++++++++++++++++++++--- source/blender/makesrna/intern/rna_define.c | 27 ++++ source/blender/makesrna/intern/rna_internal.h | 1 + source/blender/makesrna/intern/rna_wm.c | 21 +++ 12 files changed, 379 insertions(+), 55 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 542a1dff651..bd6dc7d6ed5 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -61,6 +61,34 @@ static char idp_size_table[] = { /* ----------- Array Type ----------- */ +static void idp_resize_group_array(IDProperty *prop, int newlen, void *newarr) +{ + if(prop->subtype != IDP_GROUP) + return; + + if(newlen >= prop->len) { + /* bigger */ + IDProperty **array= newarr; + IDPropertyTemplate val; + int a; + + for(a=prop->len; adata.pointer; + int a; + + for(a=newlen; alen; a++) { + IDP_FreeProperty(array[a]); + MEM_freeN(array[a]); + } + } +} + /*this function works for strings too!*/ void IDP_ResizeArray(IDProperty *prop, int newlen) { @@ -70,6 +98,7 @@ void IDP_ResizeArray(IDProperty *prop, int newlen) /*first check if the array buffer size has room*/ /*if newlen is 200 chars less then totallen, reallocate anyway*/ if (newlen <= prop->totallen && prop->totallen - newlen < 200) { + idp_resize_group_array(prop, newlen, newarr); prop->len = newlen; return; } @@ -84,11 +113,17 @@ void IDP_ResizeArray(IDProperty *prop, int newlen) */ newsize = (newsize >> 3) + (newsize < 9 ? 3 : 6) + newsize; - newarr = MEM_callocN(idp_size_table[prop->type]*newsize, "idproperty array resized"); - /*newlen is bigger*/ - if (newlen >= prop->len) memcpy(newarr, prop->data.pointer, prop->len*idp_size_table[prop->type]); - /*newlen is smaller*/ - else memcpy(newarr, prop->data.pointer, newlen*prop->len*idp_size_table[prop->type]); + newarr = MEM_callocN(idp_size_table[prop->subtype]*newsize, "idproperty array resized"); + if (newlen >= prop->len) { + /* newlen is bigger*/ + memcpy(newarr, prop->data.pointer, prop->len*idp_size_table[prop->subtype]); + idp_resize_group_array(prop, newlen, newarr); + } + else { + /* newlen is smaller*/ + idp_resize_group_array(prop, newlen, newarr); + memcpy(newarr, prop->data.pointer, newlen*prop->len*idp_size_table[prop->subtype]); + } MEM_freeN(prop->data.pointer); prop->data.pointer = newarr; @@ -96,10 +131,12 @@ void IDP_ResizeArray(IDProperty *prop, int newlen) prop->totallen = newsize; } - void IDP_FreeArray(IDProperty *prop) +void IDP_FreeArray(IDProperty *prop) { - if (prop->data.pointer) + if (prop->data.pointer) { + idp_resize_group_array(prop, 0, NULL); MEM_freeN(prop->data.pointer); + } } @@ -120,7 +157,17 @@ IDProperty *IDP_CopyArray(IDProperty *prop) { IDProperty *newp = idp_generic_copy(prop); - if (prop->data.pointer) newp->data.pointer = MEM_dupallocN(prop->data.pointer); + if (prop->data.pointer) { + newp->data.pointer = MEM_dupallocN(prop->data.pointer); + + if(prop->type == IDP_GROUP) { + IDProperty **array= newp->data.pointer; + int a; + + for(a=0; alen; a++) + array[a]= IDP_CopyProperty(array[a]); + } + } newp->len = prop->len; newp->subtype = prop->subtype; newp->totallen = prop->totallen; @@ -381,11 +428,12 @@ IDProperty *IDP_New(int type, IDPropertyTemplate val, char *name) case IDP_ARRAY: { /*for now, we only support float and int and double arrays*/ - if (val.array.type == IDP_FLOAT || val.array.type == IDP_INT || val.array.type == IDP_DOUBLE) { + if (val.array.type == IDP_FLOAT || val.array.type == IDP_INT || val.array.type == IDP_DOUBLE || val.array.type == IDP_GROUP) { prop = MEM_callocN(sizeof(IDProperty), "IDProperty array"); - prop->len = prop->totallen = val.array.len; prop->subtype = val.array.type; prop->data.pointer = MEM_callocN(idp_size_table[val.array.type]*val.array.len, "id property array"); + idp_resize_group_array(prop, val.array.len, prop->data.pointer); + prop->len = prop->totallen = val.array.len; break; } else { return NULL; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 2ef315d6841..9de56801dea 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1345,11 +1345,12 @@ static void test_pointer_array(FileData *fd, void **mat) /* ************ READ ID Properties *************** */ -void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, void *fd); -void IDP_LibLinkProperty(IDProperty *prop, int switch_endian, void *fd); +void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, FileData *fd); +void IDP_LibLinkProperty(IDProperty *prop, int switch_endian, FileData *fd); -static void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, void *fd) +static void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, FileData *fd) { + IDProperty **array; int i; /*since we didn't save the extra buffer, set totallen to len.*/ @@ -1357,26 +1358,33 @@ static void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, void *fd) prop->data.pointer = newdataadr(fd, prop->data.pointer); if (switch_endian) { - if (prop->subtype != IDP_DOUBLE) { + if(prop->subtype == IDP_GROUP) { + test_pointer_array(fd, prop->data.pointer); + array= prop->data.pointer; + + for(i=0; ilen; i++) + IDP_DirectLinkProperty(array[i], switch_endian, fd); + } + else if(prop->subtype == IDP_DOUBLE) { for (i=0; ilen; i++) { - SWITCH_INT(((int*)prop->data.pointer)[i]); + SWITCH_LONGINT(((double*)prop->data.pointer)[i]); } } else { for (i=0; ilen; i++) { - SWITCH_LONGINT(((double*)prop->data.pointer)[i]); + SWITCH_INT(((int*)prop->data.pointer)[i]); } } } } -static void IDP_DirectLinkString(IDProperty *prop, int switch_endian, void *fd) +static void IDP_DirectLinkString(IDProperty *prop, int switch_endian, FileData *fd) { /*since we didn't save the extra string buffer, set totallen to len.*/ prop->totallen = prop->len; prop->data.pointer = newdataadr(fd, prop->data.pointer); } -static void IDP_DirectLinkGroup(IDProperty *prop, int switch_endian, void *fd) +static void IDP_DirectLinkGroup(IDProperty *prop, int switch_endian, FileData *fd) { ListBase *lb = &prop->data.group; IDProperty *loop; @@ -1389,7 +1397,7 @@ static void IDP_DirectLinkGroup(IDProperty *prop, int switch_endian, void *fd) } } -void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, void *fd) +void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, FileData *fd) { switch (prop->type) { case IDP_GROUP: @@ -1423,7 +1431,7 @@ void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, void *fd) } /*stub function*/ -void IDP_LibLinkProperty(IDProperty *prop, int switch_endian, void *fd) +void IDP_LibLinkProperty(IDProperty *prop, int switch_endian, FileData *fd) { } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 33f33c79e31..7c7325ab8fa 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -390,6 +390,14 @@ static void IDP_WriteArray(IDProperty *prop, void *wd) /*REMEMBER to set totalen to len in the linking code!!*/ if (prop->data.pointer) { writedata(wd, DATA, MEM_allocN_len(prop->data.pointer), prop->data.pointer); + + if(prop->type == IDP_GROUP) { + IDProperty **array= prop->data.pointer; + int a; + + for(a=0; alen; a++) + IDP_WriteProperty(array[a], wd); + } } } diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 56325079ad2..17a0556e65e 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -50,7 +50,6 @@ extern StructRNA RNA_CollectionProperty; extern StructRNA RNA_CollisionSensor; extern StructRNA RNA_ColorSequence; extern StructRNA RNA_Constraint; -// ... constraint types... extern StructRNA RNA_Controller; extern StructRNA RNA_Curve; extern StructRNA RNA_CurveMap; @@ -119,6 +118,7 @@ extern StructRNA RNA_NodeTree; extern StructRNA RNA_NorController; extern StructRNA RNA_Object; extern StructRNA RNA_Operator; +extern StructRNA RNA_OperatorMousePath; extern StructRNA RNA_OperatorProperties; extern StructRNA RNA_OrController; extern StructRNA RNA_PackedFile; @@ -266,6 +266,11 @@ int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop); int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr); int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr); +/* to create ID property groups */ +void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop); +void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr); +void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop); + /* Path * * Experimental method to refer to structs and properties with a string, @@ -329,6 +334,25 @@ char *RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, in int RNA_string_length(PointerRNA *ptr, const char *name); void RNA_string_set(PointerRNA *ptr, const char *name, const char *value); +void RNA_pointer_get(PointerRNA *ptr, const char *name, PointerRNA *r_value); +void RNA_pointer_add(PointerRNA *ptr, const char *name); + +void RNA_collection_begin(PointerRNA *ptr, const char *name, CollectionPropertyIterator *iter); +int RNA_collection_length(PointerRNA *ptr, const char *name); +void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value); +void RNA_collection_clear(PointerRNA *ptr, const char *name); + +#define RNA_BEGIN(sptr, itemptr, propname) \ + { \ + CollectionPropertyIterator rna_macro_iter; \ + for(RNA_collection_begin(sptr, propname, &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) { \ + PointerRNA itemptr= rna_macro_iter.ptr; + +#define RNA_END \ + } \ + RNA_property_collection_end(&rna_macro_iter); \ + } + /* check if the idproperty exists, for operators */ int RNA_property_is_set(PointerRNA *ptr, const char *name); diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h index d7df58ca61c..12711a1b95d 100644 --- a/source/blender/makesrna/RNA_define.h +++ b/source/blender/makesrna/RNA_define.h @@ -69,6 +69,7 @@ void RNA_def_property_range(PropertyRNA *prop, double min, double max); void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item); void RNA_def_property_string_maxlength(PropertyRNA *prop, int maxlength); void RNA_def_property_struct_type(PropertyRNA *prop, const char *type); +void RNA_def_property_struct_runtime(PropertyRNA *prop, StructRNA *type); void RNA_def_property_boolean_default(PropertyRNA *prop, int value); void RNA_def_property_boolean_array_default(PropertyRNA *prop, const int *array); diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index fac42821e09..e4aceb0a81b 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -110,6 +110,7 @@ typedef struct CollectionPropertyIterator { PointerRNA parent; struct PropertyRNA *prop; void *internal; + int idprop; int valid; PointerRNA ptr; diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index ed408a26c9a..86b40e6a828 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -525,17 +525,19 @@ static void rna_def_property_funcs(FILE *f, PropertyDefRNA *dp) cprop->length= (void*)rna_def_property_length_func(f, srna, prop, dp); } - if(!cprop->begin) { - fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a begin function.\n", srna->identifier, prop->identifier); - DefRNA.error= 1; - } - if(!cprop->next) { - fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a next function.\n", srna->identifier, prop->identifier); - DefRNA.error= 1; - } - if(!cprop->get) { - fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a get function.\n", srna->identifier, prop->identifier); - DefRNA.error= 1; + if(!(prop->flag & PROP_IDPROPERTY)) { + if(!cprop->begin) { + fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a begin function.\n", srna->identifier, prop->identifier); + DefRNA.error= 1; + } + if(!cprop->next) { + fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a next function.\n", srna->identifier, prop->identifier); + DefRNA.error= 1; + } + if(!cprop->get) { + fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a get function.\n", srna->identifier, prop->identifier); + DefRNA.error= 1; + } } if(!cprop->structtype && !cprop->type) { fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have either type function or fixed type.\n", srna->identifier, prop->identifier); diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 0d927f332dc..ba252f30994 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -110,7 +110,6 @@ static void rna_def_ID_properties(BlenderRNA *brna) srna= RNA_def_struct(brna, "IDProperty", NULL); RNA_def_struct_ui_text(srna, "ID Property", "stores arbitrary properties"); - /* IDP_STRING */ prop= RNA_def_property(srna, "string", PROP_STRING, PROP_NONE); RNA_def_property_flag(prop, PROP_EXPORT|PROP_IDPROPERTY); @@ -144,6 +143,10 @@ static void rna_def_ID_properties(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EXPORT|PROP_NOT_EDITABLE|PROP_IDPROPERTY); RNA_def_property_struct_type(prop, "IDPropertyGroup"); + prop= RNA_def_property(srna, "collection", PROP_COLLECTION, PROP_NONE); + RNA_def_property_flag(prop, PROP_EXPORT|PROP_IDPROPERTY); + RNA_def_property_struct_type(prop, "IDPropertyGroup"); + /* IDP_ID -- not implemented yet in id properties */ /* ID property groups > level 0, since level 0 group is merged diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 1fb5699b79d..1d29efa2463 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -101,7 +101,7 @@ IDProperty *rna_idproperties_get(StructRNA *type, void *data, int create) { if(type->flag & STRUCT_ID) return IDP_GetProperties(data, create); - else if(type == &RNA_IDPropertyGroup) + else if(type == &RNA_IDPropertyGroup || type->from == &RNA_IDPropertyGroup) return data; else if(type->from == &RNA_OperatorProperties) { IDProperty **properties= (IDProperty**)data; @@ -109,7 +109,7 @@ IDProperty *rna_idproperties_get(StructRNA *type, void *data, int create) if(create && !*properties) { IDPropertyTemplate val; val.i = 0; /* silence MSVC warning about uninitialized var when debugging */ - *properties= IDP_New(IDP_GROUP, val, "property"); + *properties= IDP_New(IDP_GROUP, val, "RNA_OperatorProperties group"); } return *properties; @@ -141,7 +141,11 @@ static int rna_idproperty_verify_valid(PropertyRNA *prop, IDProperty *idprop) switch(idprop->type) { case IDP_ARRAY: - if(prop->arraylength != idprop->len) + if(idprop->subtype == IDP_GROUP) { + if(prop->type != PROP_COLLECTION) + return 0; + } + else if(prop->arraylength != idprop->len) return 0; if(idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT) @@ -214,7 +218,8 @@ IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr) static PropertyRNA *arraytypemap[IDP_NUMTYPES] = {NULL, (PropertyRNA*)&rna_IDProperty_intarray, (PropertyRNA*)&rna_IDProperty_floatarray, - NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, + (PropertyRNA*)&rna_IDProperty_collection, NULL, (PropertyRNA*)&rna_IDProperty_doublearray}; IDProperty *idprop= (IDProperty*)(*prop); @@ -702,7 +707,7 @@ float RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, int index IDProperty *idprop; if((idprop=rna_idproperty_check(&prop, ptr))) { - if(idprop->type == IDP_FLOAT) + if(idprop->subtype == IDP_FLOAT) return ((float*)IDP_Array(idprop))[index]; else return (float)(((double*)IDP_Array(idprop))[index]); @@ -719,7 +724,7 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, int index, IDProperty *idprop; if((idprop=rna_idproperty_check(&prop, ptr))) { - if(idprop->type == IDP_FLOAT) + if(idprop->subtype == IDP_FLOAT) ((float*)IDP_Array(idprop))[index]= value; else ((double*)IDP_Array(idprop))[index]= value; @@ -889,6 +894,27 @@ void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *pt pprop->set(ptr, ptr_value->data); } +void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop) +{ + IDProperty *idprop; + + if((idprop=rna_idproperty_check(&prop, ptr))) { + /* already exists */ + } + else if(prop->flag & PROP_IDPROPERTY) { + IDPropertyTemplate val; + IDProperty *group; + + val.i= 0; + + group= rna_idproperties_get(ptr->type, ptr->data, 1); + if(group) + IDP_AddToGroup(group, IDP_New(IDP_GROUP, val, (char*)prop->identifier)); + } + else + printf("RNA_property_pointer_add %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier); +} + static StructRNA *rna_property_collection_type(CollectionPropertyIterator *iter) { CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop; @@ -920,49 +946,95 @@ static void rna_property_collection_get(CollectionPropertyIterator *iter) memset(&iter->ptr, 0, sizeof(iter->ptr)); } +static void rna_property_collection_get_idp(CollectionPropertyIterator *iter) +{ + CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop; + + iter->ptr.data= rna_iterator_array_dereference_get(iter); + iter->ptr.type= cprop->structtype; + rna_pointer_inherit_id(cprop->structtype, &iter->parent, &iter->ptr); +} + void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter) { - CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop; + IDProperty *idprop; - if(cprop->begin) { + if((idprop=rna_idproperty_check(&prop, ptr)) || (prop->flag & PROP_IDPROPERTY)) { iter->parent= *ptr; iter->prop= prop; - cprop->begin(iter, ptr); + + if(idprop) + rna_iterator_array_begin(iter, IDP_Array(idprop), sizeof(void*), idprop->len, NULL); + else + rna_iterator_array_begin(iter, NULL, sizeof(void*), 0, NULL); if(iter->valid) - rna_property_collection_get(iter); + rna_property_collection_get_idp(iter); else memset(&iter->ptr, 0, sizeof(iter->ptr)); + + iter->idprop= 1; + } + else { + CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop; + + if(cprop->begin) { + iter->parent= *ptr; + iter->prop= prop; + iter->idprop= 0; + cprop->begin(iter, ptr); + + if(iter->valid) + rna_property_collection_get(iter); + else + memset(&iter->ptr, 0, sizeof(iter->ptr)); + } + else + memset(iter, 0, sizeof(*iter)); } - else - memset(iter, 0, sizeof(*iter)); } void RNA_property_collection_next(CollectionPropertyIterator *iter) { CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop; - cprop->next(iter); + if(iter->idprop) { + rna_iterator_array_next(iter); - if(iter->valid) - rna_property_collection_get(iter); - else - memset(&iter->ptr, 0, sizeof(iter->ptr)); + if(iter->valid) + rna_property_collection_get_idp(iter); + else + memset(&iter->ptr, 0, sizeof(iter->ptr)); + } + else { + cprop->next(iter); + + if(iter->valid) + rna_property_collection_get(iter); + else + memset(&iter->ptr, 0, sizeof(iter->ptr)); + } } void RNA_property_collection_end(CollectionPropertyIterator *iter) { CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop; - if(cprop->end) + if(iter->idprop) + rna_iterator_array_end(iter); + else if(cprop->end) cprop->end(iter); } int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop) { CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop; + IDProperty *idprop; - if(cprop->length) { + if((idprop=rna_idproperty_check(&prop, ptr))) { + return idprop->len; + } + else if(cprop->length) { return cprop->length(ptr); } else { @@ -978,6 +1050,51 @@ int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop) } } +void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr) +{ + IDProperty *idprop; + + if((idprop=rna_idproperty_check(&prop, ptr))) { + IDP_ResizeArray(idprop, idprop->len+1); + } + else if(prop->flag & PROP_IDPROPERTY) { + IDPropertyTemplate val; + IDProperty *group; + + val.array.len= 1; + val.array.type= IDP_GROUP; + + group= rna_idproperties_get(ptr->type, ptr->data, 1); + if(group) { + idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier); + IDP_AddToGroup(group, idprop); + } + } + else + printf("RNA_property_collection_add %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier); + + if(r_ptr) { + if(idprop) { + CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop; + IDProperty **array= (IDProperty**)IDP_Array(idprop); + + r_ptr->data= array[idprop->len-1]; + r_ptr->type= cprop->structtype; + rna_pointer_inherit_id(NULL, ptr, r_ptr); + } + else + memset(r_ptr, 0, sizeof(*r_ptr)); + } +} + +void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop) +{ + IDProperty *idprop; + + if((idprop=rna_idproperty_check(&prop, ptr))) + IDP_FreeArray(idprop); +} + int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr) { CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop; @@ -1666,6 +1783,69 @@ void RNA_string_set(PointerRNA *ptr, const char *name, const char *value) printf("RNA_string_set: %s.%s not found.\n", ptr->type->identifier, name); } +void RNA_pointer_get(PointerRNA *ptr, const char *name, PointerRNA *r_value) +{ + PropertyRNA *prop= RNA_struct_find_property(ptr, name); + + if(prop) + RNA_property_pointer_get(ptr, prop, r_value); + else + printf("RNA_pointer_get: %s.%s not found.\n", ptr->type->identifier, name); +} + +void RNA_pointer_add(PointerRNA *ptr, const char *name) +{ + PropertyRNA *prop= RNA_struct_find_property(ptr, name); + + if(prop) + RNA_property_pointer_add(ptr, prop); + else + printf("RNA_pointer_set: %s.%s not found.\n", ptr->type->identifier, name); +} + +void RNA_collection_begin(PointerRNA *ptr, const char *name, CollectionPropertyIterator *iter) +{ + PropertyRNA *prop= RNA_struct_find_property(ptr, name); + + if(prop) + RNA_property_collection_begin(ptr, prop, iter); + else + printf("RNA_collection_begin: %s.%s not found.\n", ptr->type->identifier, name); +} + +void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value) +{ + PropertyRNA *prop= RNA_struct_find_property(ptr, name); + + if(prop) + RNA_property_collection_add(ptr, prop, r_value); + else + printf("RNA_collection_add: %s.%s not found.\n", ptr->type->identifier, name); +} + +void RNA_collection_clear(PointerRNA *ptr, const char *name) +{ + PropertyRNA *prop= RNA_struct_find_property(ptr, name); + + if(prop) + RNA_property_collection_clear(ptr, prop); + else + printf("RNA_collection_clear: %s.%s not found.\n", ptr->type->identifier, name); +} + +int RNA_collection_length(PointerRNA *ptr, const char *name) +{ + PropertyRNA *prop= RNA_struct_find_property(ptr, name); + + if(prop) { + return RNA_property_collection_length(ptr, prop); + } + else { + printf("RNA_collection_length: %s.%s not found.\n", ptr->type->identifier, name); + return 0; + } +} + int RNA_property_is_set(PointerRNA *ptr, const char *name) { PropertyRNA *prop= RNA_struct_find_property(ptr, name); @@ -1679,8 +1859,8 @@ int RNA_property_is_set(PointerRNA *ptr, const char *name) } } -/* string representation of a property, python compatible but - * cant be used for display too*/ +/* string representation of a property, python + * compatible but can be used for display too*/ char *RNA_property_as_string(PointerRNA *ptr, PropertyRNA *prop) { int type = RNA_property_type(ptr, prop); @@ -1768,4 +1948,4 @@ char *RNA_property_as_string(PointerRNA *ptr, PropertyRNA *prop) cstring = BLI_dynstr_get_cstring(dynstr); BLI_dynstr_free(dynstr); return cstring; -} \ No newline at end of file +} diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 14e4763d2c0..05dba91757b 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -804,6 +804,33 @@ void RNA_def_property_struct_type(PropertyRNA *prop, const char *type) } } +void RNA_def_property_struct_runtime(PropertyRNA *prop, StructRNA *type) +{ + StructRNA *srna= DefRNA.laststruct; + + if(DefRNA.preprocess) { + fprintf(stderr, "RNA_def_property_struct_runtime: only at runtime.\n"); + return; + } + + switch(prop->type) { + case PROP_POINTER: { + PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop; + pprop->structtype = type; + break; + } + case PROP_COLLECTION: { + CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop; + cprop->structtype = type; + break; + } + default: + fprintf(stderr, "RNA_def_property_struct_runtime: %s.%s, invalid type for struct type.\n", srna->identifier, prop->identifier); + DefRNA.error= 1; + break; + } +} + void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item) { StructRNA *srna= DefRNA.laststruct; diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index d296238edae..435f00c9c2b 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -140,6 +140,7 @@ extern IntPropertyRNA rna_IDProperty_intarray; extern FloatPropertyRNA rna_IDProperty_float; extern FloatPropertyRNA rna_IDProperty_floatarray; extern PointerPropertyRNA rna_IDProperty_group; +extern CollectionPropertyRNA rna_IDProperty_collection; extern FloatPropertyRNA rna_IDProperty_double; extern FloatPropertyRNA rna_IDProperty_doublearray; diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index a7a510bc428..1b9efa92a1b 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -92,6 +92,26 @@ static void rna_def_operator(BlenderRNA *brna) srna= RNA_def_struct(brna, "OperatorProperties", NULL); RNA_def_struct_ui_text(srna, "Operator Properties", "DOC_BROKEN"); RNA_def_struct_funcs(srna, NULL, "rna_OperatorProperties_refine"); + + +} + +static void rna_def_operator_utils(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "OperatorMousePath", "IDPropertyGroup"); + RNA_def_struct_ui_text(srna, "Operator Mouse Path", "Mouse path values for operators."); + + prop= RNA_def_property(srna, "loc", PROP_FLOAT, PROP_VECTOR); + RNA_def_property_flag(prop, PROP_IDPROPERTY); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_text(prop, "Location", "Mouse location."); + + prop= RNA_def_property(srna, "time", PROP_FLOAT, PROP_NONE); + RNA_def_property_flag(prop, PROP_IDPROPERTY); + RNA_def_property_ui_text(prop, "Time", "Time of mouse location."); } static void rna_def_windowmanager(BlenderRNA *brna) @@ -111,6 +131,7 @@ static void rna_def_windowmanager(BlenderRNA *brna) void RNA_def_wm(BlenderRNA *brna) { rna_def_operator(brna); + rna_def_operator_utils(brna); rna_def_windowmanager(brna); } -- cgit v1.2.3