2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * Contributor(s): Blender Foundation (2008).
20 * ***** END GPL LICENSE BLOCK *****
23 /** \file blender/makesrna/intern/rna_access.c
33 #include "MEM_guardedalloc.h"
36 #include "DNA_scene_types.h"
37 #include "DNA_windowmanager_types.h"
39 #include "BLI_blenlib.h"
40 #include "BLI_utildefines.h"
41 #include "BLI_dynstr.h"
42 #include "BLI_ghash.h"
45 #include "BLF_translation.h"
47 #include "BKE_animsys.h"
48 #include "BKE_context.h"
49 #include "BKE_idprop.h"
51 #include "BKE_report.h"
56 #include "RNA_access.h"
57 #include "RNA_define.h"
60 #include "DNA_object_types.h"
61 #include "BKE_depsgraph.h"
64 #include "rna_internal.h"
66 const PointerRNA PointerRNA_NULL= {{NULL}};
75 for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
76 if(!srna->cont.prophash) {
77 srna->cont.prophash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "RNA_init gh");
79 for(prop=srna->cont.properties.first; prop; prop=prop->next)
80 if(!(prop->flag & PROP_BUILTIN))
81 BLI_ghash_insert(srna->cont.prophash, (void*)prop->identifier, prop);
90 RNA_property_update_cache_free();
92 for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
93 if(srna->cont.prophash) {
94 BLI_ghash_free(srna->cont.prophash, NULL, NULL);
95 srna->cont.prophash= NULL;
99 RNA_free(&BLENDER_RNA);
104 void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr)
106 r_ptr->id.data= NULL;
107 r_ptr->type= &RNA_BlendData;
111 void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
113 StructRNA *type, *idtype= NULL;
116 PointerRNA tmp= {{NULL}};
118 idtype= rna_ID_refine(&tmp);
120 while(idtype->refine) {
121 type= idtype->refine(&tmp);
135 void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
138 StructRNA *idtype= NULL;
141 PointerRNA tmp= {{0}};
143 idtype= rna_ID_refine(&tmp);
152 while(r_ptr->type && r_ptr->type->refine) {
153 StructRNA *rtype= r_ptr->type->refine(r_ptr);
155 if(rtype == r_ptr->type)
163 static void rna_pointer_inherit_id(StructRNA *type, PointerRNA *parent, PointerRNA *ptr)
165 if(type && type->flag & STRUCT_ID) {
166 ptr->id.data= ptr->data;
169 ptr->id.data= parent->id.data;
173 void RNA_blender_rna_pointer_create(PointerRNA *r_ptr)
175 r_ptr->id.data= NULL;
176 r_ptr->type= &RNA_BlenderRNA;
177 r_ptr->data= &BLENDER_RNA;
180 PointerRNA rna_pointer_inherit_refine(PointerRNA *ptr, StructRNA *type, void *data)
186 rna_pointer_inherit_id(type, ptr, &result);
188 while(result.type->refine) {
189 type= result.type->refine(&result);
191 if(type == result.type)
199 return PointerRNA_NULL;
204 void RNA_pointer_recast(PointerRNA *ptr, PointerRNA *r_ptr)
206 #if 0 // works but this case if covered by more general code below.
207 if(RNA_struct_is_ID(ptr->type)) {
209 RNA_id_pointer_create(ptr->id.data, r_ptr);
216 *r_ptr= *ptr; /* initialize as the same incase cant recast */
218 for(base=ptr->type->base; base; base=base->base) {
219 t_ptr= rna_pointer_inherit_refine(ptr, base, ptr->data);
220 if(t_ptr.type && t_ptr.type != ptr->type) {
229 /* return a UI local ID prop definition for this prop */
230 IDProperty *rna_idproperty_ui(PropertyRNA *prop)
234 for(idprop= ((IDProperty *)prop)->prev; idprop; idprop= idprop->prev) {
235 if (strcmp(RNA_IDP_UI, idprop->name)==0)
240 for(idprop= ((IDProperty *)prop)->next; idprop; idprop= idprop->next) {
241 if (strcmp(RNA_IDP_UI, idprop->name)==0)
247 return IDP_GetPropertyTypeFromGroup(idprop, ((IDProperty *)prop)->name, IDP_GROUP);
253 IDProperty *RNA_struct_idprops(PointerRNA *ptr, int create)
255 StructRNA *type= ptr->type;
257 if(type && type->idproperties)
258 return type->idproperties(ptr, create);
263 int RNA_struct_idprops_check(StructRNA *srna)
265 return (srna && srna->idproperties) ? 1 : 0;
268 static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name)
270 IDProperty *group= RNA_struct_idprops(ptr, 0);
273 return IDP_GetPropertyFromGroup(group, name);
278 static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
280 if(prop->magic == RNA_MAGIC) {
281 int arraylen[RNA_MAX_ARRAY_DIMENSION];
282 return (prop->getlength && ptr->data)? prop->getlength(ptr, arraylen): prop->totarraylength;
285 IDProperty *idprop= (IDProperty*)prop;
287 if(idprop->type == IDP_ARRAY)
294 static int rna_ensure_property_array_check(PropertyRNA *prop)
296 if(prop->magic == RNA_MAGIC) {
297 return (prop->getlength || prop->totarraylength) ? 1:0;
300 IDProperty *idprop= (IDProperty*)prop;
302 return idprop->type == IDP_ARRAY ? 1:0;
306 static void rna_ensure_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int length[])
308 if(prop->magic == RNA_MAGIC) {
310 prop->getlength(ptr, length);
312 memcpy(length, prop->arraylength, prop->arraydimension*sizeof(int));
315 IDProperty *idprop= (IDProperty*)prop;
317 if(idprop->type == IDP_ARRAY)
318 length[0]= idprop->len;
324 static int rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDProperty *idprop)
326 /* this verifies if the idproperty actually matches the property
327 * description and otherwise removes it. this is to ensure that
328 * rna property access is type safe, e.g. if you defined the rna
329 * to have a certain array length you can count on that staying so */
331 switch(idprop->type) {
333 if(prop->type != PROP_COLLECTION)
337 if(rna_ensure_property_array_length(ptr, prop) != idprop->len)
340 if(idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT)
342 if(idprop->subtype == IDP_INT && !ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
347 if(!ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
352 if(prop->type != PROP_FLOAT)
356 if(prop->type != PROP_STRING)
360 if(prop->type != PROP_POINTER)
370 static PropertyRNA *typemap[IDP_NUMTYPES] =
371 {(PropertyRNA*)&rna_PropertyGroupItem_string,
372 (PropertyRNA*)&rna_PropertyGroupItem_int,
373 (PropertyRNA*)&rna_PropertyGroupItem_float,
375 (PropertyRNA*)&rna_PropertyGroupItem_group, NULL,
376 (PropertyRNA*)&rna_PropertyGroupItem_double,
377 (PropertyRNA*)&rna_PropertyGroupItem_idp_array};
379 static PropertyRNA *arraytypemap[IDP_NUMTYPES] =
380 {NULL, (PropertyRNA*)&rna_PropertyGroupItem_int_array,
381 (PropertyRNA*)&rna_PropertyGroupItem_float_array,
383 (PropertyRNA*)&rna_PropertyGroupItem_collection, NULL,
384 (PropertyRNA*)&rna_PropertyGroupItem_double_array};
386 IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr)
388 /* This is quite a hack, but avoids some complexity in the API. we
389 * pass IDProperty structs as PropertyRNA pointers to the outside.
390 * We store some bytes in PropertyRNA structs that allows us to
391 * distinguish it from IDProperty structs. If it is an ID property,
392 * we look up an IDP PropertyRNA based on the type, and set the data
393 * pointer to the IDProperty. */
395 if((*prop)->magic == RNA_MAGIC) {
396 if((*prop)->flag & PROP_IDPROPERTY) {
397 IDProperty *idprop= rna_idproperty_find(ptr, (*prop)->identifier);
399 if(idprop && !rna_idproperty_verify_valid(ptr, *prop, idprop)) {
400 IDProperty *group= RNA_struct_idprops(ptr, 0);
402 IDP_RemFromGroup(group, idprop);
403 IDP_FreeProperty(idprop);
415 IDProperty *idprop= (IDProperty*)(*prop);
417 if(idprop->type == IDP_ARRAY)
418 *prop= arraytypemap[(int)(idprop->subtype)];
420 *prop= typemap[(int)(idprop->type)];
426 static PropertyRNA *rna_ensure_property(PropertyRNA *prop)
428 /* the quick version if we don't need the idproperty */
430 if(prop->magic == RNA_MAGIC)
434 IDProperty *idprop= (IDProperty*)prop;
436 if(idprop->type == IDP_ARRAY)
437 return arraytypemap[(int)(idprop->subtype)];
439 return typemap[(int)(idprop->type)];
443 static const char *rna_ensure_property_identifier(PropertyRNA *prop)
445 if(prop->magic == RNA_MAGIC)
446 return prop->identifier;
448 return ((IDProperty*)prop)->name;
451 static const char *rna_ensure_property_description(PropertyRNA *prop)
453 const char *description= NULL;
455 if(prop->magic == RNA_MAGIC)
456 description= prop->description;
458 /* attempt to get the local ID values */
459 IDProperty *idp_ui= rna_idproperty_ui(prop);
462 IDProperty *item= IDP_GetPropertyTypeFromGroup(idp_ui, "description", IDP_STRING);
464 description= IDP_String(item);
467 if(description == NULL)
468 description= ((IDProperty*)prop)->name; /* XXX - not correct */
471 #ifdef WITH_INTERNATIONAL
472 if(description && (U.transopts&USER_DOTRANSLATE) && (U.transopts&USER_TR_TOOLTIPS))
473 description= BLF_gettext(description);
479 static const char *rna_ensure_property_name(PropertyRNA *prop)
483 if(prop->magic == RNA_MAGIC)
486 name= ((IDProperty*)prop)->name;
488 #ifdef WITH_INTERNATIONAL
489 if((U.transopts&USER_DOTRANSLATE) && (U.transopts&USER_TR_IFACE)) {
490 if(prop->translation_context)
491 name = BLF_pgettext(prop->translation_context, name);
493 name = BLF_gettext(name);
502 StructRNA *RNA_struct_find(const char *identifier)
506 for (type = BLENDER_RNA.structs.first; type; type = type->cont.next)
507 if (strcmp(type->identifier, identifier)==0)
513 const char *RNA_struct_identifier(StructRNA *type)
515 return type->identifier;
518 const char *RNA_struct_ui_name(StructRNA *type)
523 int RNA_struct_ui_icon(StructRNA *type)
531 const char *RNA_struct_ui_description(StructRNA *type)
533 return type->description;
536 PropertyRNA *RNA_struct_name_property(StructRNA *type)
538 return type->nameproperty;
541 PropertyRNA *RNA_struct_iterator_property(StructRNA *type)
543 return type->iteratorproperty;
546 StructRNA *RNA_struct_base(StructRNA *type)
551 int RNA_struct_is_ID(StructRNA *type)
553 return (type->flag & STRUCT_ID) != 0;
556 int RNA_struct_undo_check(StructRNA *type)
558 return (type->flag & STRUCT_UNDO) != 0;
561 int RNA_struct_idprops_register_check(StructRNA *type)
563 return (type->flag & STRUCT_NO_IDPROPERTIES) == 0;
566 /* remove an id-property */
567 int RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier)
569 IDProperty *group= RNA_struct_idprops(ptr, 0);
572 IDProperty *idp= IDP_GetPropertyFromGroup(group, identifier);
574 IDP_RemFromGroup(group, idp);
575 IDP_FreeProperty(idp);
584 int RNA_struct_is_a(StructRNA *type, StructRNA *srna)
591 /* ptr->type is always maximally refined */
592 for(base=type; base; base=base->base)
599 PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
601 if(identifier[0]=='[' && identifier[1]=='"') { // " (dummy comment to avoid confusing some function lists in text editors)
602 /* id prop lookup, not so common */
603 PropertyRNA *r_prop= NULL;
604 PointerRNA r_ptr; /* only support single level props */
605 if(RNA_path_resolve(ptr, identifier, &r_ptr, &r_prop) && r_ptr.type==ptr->type && r_ptr.data==ptr->data)
609 /* most common case */
610 PropertyRNA *iterprop= RNA_struct_iterator_property(ptr->type);
613 if(RNA_property_collection_lookup_string(ptr, iterprop, identifier, &propptr))
620 /* Find the property which uses the given nested struct */
621 PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
623 PropertyRNA *prop= NULL;
625 RNA_STRUCT_BEGIN(ptr, iprop) {
626 /* This assumes that there can only be one user of this nested struct */
627 if (RNA_property_pointer_type(ptr, iprop) == srna) {
637 int RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test)
639 /* note, prop_test could be freed memory, only use for comparison */
641 /* validate the RNA is ok */
642 PropertyRNA *iterprop;
645 iterprop= RNA_struct_iterator_property(ptr->type);
647 RNA_PROP_BEGIN(ptr, itemptr, iterprop) {
648 /* PropertyRNA *prop= itemptr.data; */
649 if(prop_test == (PropertyRNA *)itemptr.data) {
659 /* low level direct access to type->properties, note this ignores parent classes so should be used with care */
660 const struct ListBase *RNA_struct_type_properties(StructRNA *srna)
662 return &srna->cont.properties;
665 PropertyRNA *RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
667 return BLI_findstring_ptr(&srna->cont.properties, identifier, offsetof(PropertyRNA, identifier));
670 FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier)
675 for(type= ptr->type; type; type= type->base) {
676 func= (FunctionRNA *)BLI_findstring_ptr(&type->functions, identifier, offsetof(FunctionRNA, identifier));
683 /* funcitonal but slow */
686 PropertyRNA *iterprop;
689 RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr);
690 iterprop= RNA_struct_find_property(&tptr, "functions");
694 RNA_PROP_BEGIN(&tptr, funcptr, iterprop) {
695 if(strcmp(identifier, RNA_function_identifier(funcptr.data)) == 0) {
706 const struct ListBase *RNA_struct_type_functions(StructRNA *srna)
708 return &srna->functions;
711 StructRegisterFunc RNA_struct_register(StructRNA *type)
716 StructUnregisterFunc RNA_struct_unregister(StructRNA *type)
721 } while((type=type->base));
726 void **RNA_struct_instance(PointerRNA *ptr)
728 StructRNA *type= ptr->type;
732 return type->instance(ptr);
733 } while((type=type->base));
738 void *RNA_struct_py_type_get(StructRNA *srna)
740 return srna->py_type;
743 void RNA_struct_py_type_set(StructRNA *srna, void *py_type)
745 srna->py_type= py_type;
748 void *RNA_struct_blender_type_get(StructRNA *srna)
750 return srna->blender_type;
753 void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
755 srna->blender_type= blender_type;
758 char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len)
760 PropertyRNA *nameprop;
762 if(ptr->data && (nameprop = RNA_struct_name_property(ptr->type)))
763 return RNA_property_string_get_alloc(ptr, nameprop, fixedbuf, fixedlen, r_len);
768 /* Property Information */
770 const char *RNA_property_identifier(PropertyRNA *prop)
772 return rna_ensure_property_identifier(prop);
775 const char *RNA_property_description(PropertyRNA *prop)
777 return rna_ensure_property_description(prop);
780 PropertyType RNA_property_type(PropertyRNA *prop)
782 return rna_ensure_property(prop)->type;
785 PropertySubType RNA_property_subtype(PropertyRNA *prop)
787 return rna_ensure_property(prop)->subtype;
790 PropertyUnit RNA_property_unit(PropertyRNA *prop)
792 return RNA_SUBTYPE_UNIT(rna_ensure_property(prop)->subtype);
795 int RNA_property_flag(PropertyRNA *prop)
797 return rna_ensure_property(prop)->flag;
800 void *RNA_property_py_data_get(PropertyRNA *prop)
802 return prop->py_data;
805 int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
807 return rna_ensure_property_array_length(ptr, prop);
810 int RNA_property_array_check(PropertyRNA *prop)
812 return rna_ensure_property_array_check(prop);
815 /* used by BPY to make an array from the python object */
816 int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[])
818 PropertyRNA *rprop= rna_ensure_property(prop);
821 rna_ensure_property_multi_array_length(ptr, prop, length);
823 return rprop->arraydimension;
826 /* Return the size of Nth dimension. */
827 int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dim)
829 int len[RNA_MAX_ARRAY_DIMENSION];
831 rna_ensure_property_multi_array_length(ptr, prop, len);
836 char RNA_property_array_item_char(PropertyRNA *prop, int index)
838 const char *vectoritem= "XYZW";
839 const char *quatitem= "WXYZ";
840 const char *coloritem= "RGBA";
841 PropertySubType subtype= rna_ensure_property(prop)->subtype;
843 /* get string to use for array index */
844 if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
845 return quatitem[index];
847 else if((index < 4) && ELEM8(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_XYZ_LENGTH,
848 PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION, PROP_COORDS))
850 return vectoritem[index];
852 else if ((index < 4) && ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
853 return coloritem[index];
859 int RNA_property_array_item_index(PropertyRNA *prop, char name)
861 PropertySubType subtype= rna_ensure_property(prop)->subtype;
863 /* get index based on string name/alias */
864 /* maybe a function to find char index in string would be better than all the switches */
865 if (ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
877 else if(ELEM6(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ,
878 PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION))
891 else if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
908 void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
910 IntPropertyRNA *iprop= (IntPropertyRNA*)rna_ensure_property(prop);
912 if(prop->magic != RNA_MAGIC) {
913 /* attempt to get the local ID values */
914 IDProperty *idp_ui= rna_idproperty_ui(prop);
919 item= IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_INT);
920 *hardmin= item ? IDP_Int(item) : INT_MIN;
922 item= IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_INT);
923 *hardmax= item ? IDP_Int(item) : INT_MAX;
930 iprop->range(ptr, hardmin, hardmax);
933 *hardmin= iprop->hardmin;
934 *hardmax= iprop->hardmax;
938 void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
940 IntPropertyRNA *iprop= (IntPropertyRNA*)rna_ensure_property(prop);
941 int hardmin, hardmax;
943 if(prop->magic != RNA_MAGIC) {
944 /* attempt to get the local ID values */
945 IDProperty *idp_ui= rna_idproperty_ui(prop);
950 item= IDP_GetPropertyTypeFromGroup(idp_ui, "soft_min", IDP_INT);
951 *softmin= item ? IDP_Int(item) : INT_MIN;
953 item= IDP_GetPropertyTypeFromGroup(idp_ui, "soft_max", IDP_INT);
954 *softmax= item ? IDP_Int(item) : INT_MAX;
956 item= IDP_GetPropertyTypeFromGroup(idp_ui, "step", IDP_INT);
957 *step= item ? IDP_Int(item) : 1;
964 iprop->range(ptr, &hardmin, &hardmax);
965 *softmin= MAX2(iprop->softmin, hardmin);
966 *softmax= MIN2(iprop->softmax, hardmax);
969 *softmin= iprop->softmin;
970 *softmax= iprop->softmax;
976 void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
978 FloatPropertyRNA *fprop= (FloatPropertyRNA*)rna_ensure_property(prop);
980 if(prop->magic != RNA_MAGIC) {
981 /* attempt to get the local ID values */
982 IDProperty *idp_ui= rna_idproperty_ui(prop);
987 item= IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_DOUBLE);
988 *hardmin= item ? (float)IDP_Double(item) : FLT_MIN;
990 item= IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_DOUBLE);
991 *hardmax= item ? (float)IDP_Double(item) : FLT_MAX;
998 fprop->range(ptr, hardmin, hardmax);
1001 *hardmin= fprop->hardmin;
1002 *hardmax= fprop->hardmax;
1006 void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision)
1008 FloatPropertyRNA *fprop= (FloatPropertyRNA*)rna_ensure_property(prop);
1009 float hardmin, hardmax;
1011 if(prop->magic != RNA_MAGIC) {
1012 /* attempt to get the local ID values */
1013 IDProperty *idp_ui= rna_idproperty_ui(prop);
1018 item= IDP_GetPropertyTypeFromGroup(idp_ui, "soft_min", IDP_DOUBLE);
1019 *softmin= item ? (float)IDP_Double(item) : FLT_MIN;
1021 item= IDP_GetPropertyTypeFromGroup(idp_ui, "soft_max", IDP_DOUBLE);
1022 *softmax= item ? (float)IDP_Double(item) : FLT_MAX;
1024 item= IDP_GetPropertyTypeFromGroup(idp_ui, "step", IDP_DOUBLE);
1025 *step= item ? (float)IDP_Double(item) : 1.0f;
1027 item= IDP_GetPropertyTypeFromGroup(idp_ui, "precision", IDP_DOUBLE);
1028 *precision= item ? (float)IDP_Double(item) : 3.0f;
1035 fprop->range(ptr, &hardmin, &hardmax);
1036 *softmin= MAX2(fprop->softmin, hardmin);
1037 *softmax= MIN2(fprop->softmax, hardmax);
1040 *softmin= fprop->softmin;
1041 *softmax= fprop->softmax;
1045 *precision= (float)fprop->precision;
1048 int RNA_property_float_clamp(PointerRNA *ptr, PropertyRNA *prop, float *value)
1052 RNA_property_float_range(ptr, prop, &min, &max);
1058 else if(*value > max) {
1067 int RNA_property_int_clamp(PointerRNA *ptr, PropertyRNA *prop, int *value)
1071 RNA_property_int_range(ptr, prop, &min, &max);
1077 else if(*value > max) {
1086 /* this is the max length including \0 terminator.
1087 * '0' used when their is no maximum */
1088 int RNA_property_string_maxlength(PropertyRNA *prop)
1090 StringPropertyRNA *sprop= (StringPropertyRNA*)rna_ensure_property(prop);
1091 return sprop->maxlength;
1094 StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
1096 prop= rna_ensure_property(prop);
1098 if(prop->type == PROP_POINTER) {
1099 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
1102 return pprop->typef(ptr);
1103 else if(pprop->type)
1106 else if(prop->type == PROP_COLLECTION) {
1107 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1109 if(cprop->item_type)
1110 return cprop->item_type;
1112 /* ignore other types, RNA_struct_find_nested calls with unchecked props */
1114 return &RNA_UnknownType;
1117 int RNA_property_pointer_poll(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *value)
1119 prop= rna_ensure_property(prop);
1121 if(prop->type == PROP_POINTER) {
1122 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
1124 return pprop->poll(ptr, *value);
1129 printf("%s %s: is not a pointer property.\n", __func__, prop->identifier);
1133 /* Reuse for dynamic types */
1134 EnumPropertyItem DummyRNA_NULL_items[] = {
1135 {0, NULL, 0, NULL, NULL}
1138 /* Reuse for dynamic types with default value */
1139 EnumPropertyItem DummyRNA_DEFAULT_items[] = {
1140 {0, "DEFAULT", 0, "Default", ""},
1141 {0, NULL, 0, NULL, NULL}
1144 void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item, int *totitem, int *free)
1146 EnumPropertyRNA *eprop= (EnumPropertyRNA*)rna_ensure_property(prop);
1150 if(eprop->itemf && (C != NULL || (prop->flag & PROP_ENUM_NO_CONTEXT))) {
1153 if (prop->flag & PROP_ENUM_NO_CONTEXT)
1154 *item= eprop->itemf(NULL, ptr, prop, free);
1156 *item= eprop->itemf(C, ptr, prop, free);
1160 for( ; (*item)[tot].identifier; tot++);
1170 *totitem= eprop->totitem;
1174 void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item, int *totitem, int *free)
1176 RNA_property_enum_items(C, ptr, prop, item, totitem, free);
1178 #ifdef WITH_INTERNATIONAL
1179 if((U.transopts&USER_DOTRANSLATE) && (U.transopts&USER_TR_IFACE)) {
1181 EnumPropertyItem *nitem;
1189 for(i=0; (*item)[i].identifier; i++)
1192 nitem= MEM_callocN(sizeof(EnumPropertyItem)*(totitem+1), "enum_items_gettexted");
1194 for(i=0; (*item)[i].identifier; i++)
1195 nitem[i]= (*item)[i];
1200 for(i=0; nitem[i].identifier; i++) {
1201 if( nitem[i].name ) {
1202 if(prop->translation_context)
1203 nitem[i].name = BLF_pgettext(prop->translation_context, nitem[i].name);
1205 nitem[i].name = BLF_gettext(nitem[i].name);
1207 if( nitem[i].description )
1208 nitem[i].description = BLF_gettext(nitem[i].description);
1217 int RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value)
1219 EnumPropertyItem *item, *item_array;
1222 RNA_property_enum_items(C, ptr, prop, &item_array, NULL, &free);
1225 for(item= item_array; item->identifier; item++) {
1226 if(item->identifier[0] && strcmp(item->identifier, identifier)==0) {
1227 *value = item->value;
1232 found= (item->identifier != NULL); /* could be alloc'd, assign before free */
1235 MEM_freeN(item_array);
1244 int RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier)
1246 for (; item->identifier; item++) {
1247 if(item->identifier[0] && item->value==value) {
1248 *identifier = item->identifier;
1255 int RNA_enum_bitflag_identifiers(EnumPropertyItem *item, const int value, const char **identifier)
1258 for (; item->identifier; item++) {
1259 if(item->identifier[0] && item->value & value) {
1260 identifier[index++] = item->identifier;
1263 identifier[index]= NULL;
1267 int RNA_enum_name(EnumPropertyItem *item, const int value, const char **name)
1269 for (; item->identifier; item++) {
1270 if(item->identifier[0] && item->value==value) {
1278 int RNA_enum_description(EnumPropertyItem *item, const int value, const char **description)
1280 for (; item->identifier; item++) {
1281 if(item->identifier[0] && item->value==value) {
1282 *description = item->description;
1289 int RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
1291 EnumPropertyItem *item= NULL;
1294 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1296 result= RNA_enum_identifier(item, value, identifier);
1305 int RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
1307 EnumPropertyItem *item= NULL;
1310 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1312 result= RNA_enum_name(item, value, name);
1321 int RNA_property_enum_bitflag_identifiers(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
1323 EnumPropertyItem *item= NULL;
1326 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1328 result= RNA_enum_bitflag_identifiers(item, value, identifier);
1337 const char *RNA_property_ui_name(PropertyRNA *prop)
1339 return rna_ensure_property_name(prop);
1342 const char *RNA_property_ui_description(PropertyRNA *prop)
1344 return rna_ensure_property_description(prop);
1347 int RNA_property_ui_icon(PropertyRNA *prop)
1349 return rna_ensure_property(prop)->icon;
1352 int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
1354 ID *id= ptr->id.data;
1357 prop= rna_ensure_property(prop);
1358 flag= prop->editable ? prop->editable(ptr) : prop->flag;
1359 return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
1362 int RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop)
1366 prop= rna_ensure_property(prop);
1367 flag= prop->editable ? prop->editable(ptr) : prop->flag;
1368 return (flag & PROP_EDITABLE);
1371 /* same as RNA_property_editable(), except this checks individual items in an array */
1372 int RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1377 prop= rna_ensure_property(prop);
1382 flag &= prop->editable(ptr);
1384 if (prop->itemeditable)
1385 flag &= prop->itemeditable(ptr, index);
1389 return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
1392 int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
1394 /* check that base ID-block can support animation data */
1395 if (!id_type_can_have_animdata(ptr->id.data))
1398 prop= rna_ensure_property(prop);
1400 if(!(prop->flag & PROP_ANIMATABLE))
1403 return (prop->flag & PROP_EDITABLE);
1406 int RNA_property_animated(PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop))
1408 /* would need to ask animation system */
1414 /* this function is to check if its possible to create a valid path from the ID
1415 * its slow so dont call in a loop */
1416 int RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
1418 char *path= RNA_path_from_ID_to_property(ptr, prop);
1424 PropertyRNA *r_prop;
1426 RNA_id_pointer_create(ptr->id.data, &id_ptr);
1427 RNA_path_resolve(&id_ptr, path, &r_ptr, &r_prop);
1428 ret= (prop == r_prop);
1436 static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
1438 int is_rna = (prop->magic == RNA_MAGIC);
1439 prop= rna_ensure_property(prop);
1443 /* ideally no context would be needed for update, but there's some
1444 parts of the code that need it still, so we have this exception */
1445 if(prop->flag & PROP_CONTEXT_UPDATE) {
1447 if(prop->flag & PROP_CONTEXT_PROPERTY_UPDATE) {
1448 ((ContextPropUpdateFunc)prop->update)(C, ptr, prop);
1451 ((ContextUpdateFunc)prop->update)(C, ptr);
1456 prop->update(bmain, scene, ptr);
1459 WM_main_add_notifier(prop->noteflag, ptr->id.data);
1462 if(!is_rna || (prop->flag & PROP_IDPROPERTY)) {
1463 /* WARNING! This is so property drivers update the display!
1464 * not especially nice */
1465 DAG_id_tag_update(ptr->id.data, OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME);
1466 WM_main_add_notifier(NC_WINDOW, NULL);
1470 /* must keep in sync with 'rna_property_update'
1471 * note, its possible this returns a false positive in the case of PROP_CONTEXT_UPDATE
1472 * but this isnt likely to be a performance problem. */
1473 int RNA_property_update_check(PropertyRNA *prop)
1475 return (prop->magic != RNA_MAGIC || prop->update || prop->noteflag);
1478 void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
1480 rna_property_update(C, CTX_data_main(C), CTX_data_scene(C), ptr, prop);
1483 void RNA_property_update_main(Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
1485 rna_property_update(NULL, bmain, scene, ptr, prop);
1489 /* RNA Updates Cache ------------------------ */
1490 /* Overview of RNA Update cache system:
1492 * RNA Update calls need to be cached in order to maintain reasonable performance
1493 * of the animation system (i.e. maintaining a somewhat interactive framerate)
1494 * while still allowing updates to be called (necessary in particular for modifier
1495 * property updates to actually work).
1497 * The cache is structured with a dual-layer structure
1498 * - L1 = PointerRNA used as key; id.data is used (it should always be defined,
1499 * and most updates end up using just that anyways)
1500 * - L2 = Update functions to be called on those PointerRNA's
1504 typedef struct tRnaUpdateCacheElem {
1505 struct tRnaUpdateCacheElem *next, *prev;
1507 PointerRNA ptr; /* L1 key - id as primary, data secondary/ignored? */
1508 ListBase L2Funcs; /* L2 functions (LinkData<RnaUpdateFuncRef>) */
1509 } tRnaUpdateCacheElem;
1511 /* cache global (tRnaUpdateCacheElem's) - only accessible using these API calls */
1512 static ListBase rna_updates_cache = {NULL, NULL};
1514 /* ........................... */
1516 void RNA_property_update_cache_add(PointerRNA *ptr, PropertyRNA *prop)
1518 tRnaUpdateCacheElem *uce = NULL;
1519 UpdateFunc fn = NULL;
1521 short is_rna = (prop->magic == RNA_MAGIC);
1524 if (ELEM(NULL, ptr, prop))
1527 prop= rna_ensure_property(prop);
1529 /* we can only handle update calls with no context args for now (makes animsys updates easier) */
1530 if ((is_rna == 0) || (prop->update == NULL) || (prop->flag & PROP_CONTEXT_UPDATE))
1534 /* find cache element for which key matches... */
1535 for (uce = rna_updates_cache.first; uce; uce = uce->next) {
1536 /* just match by id only for now, since most update calls that we'll encounter only really care about this */
1537 /* TODO: later, the cache might need to have some nesting on L1 to cope better
1538 * with these problems + some tagging to indicate we need this */
1539 if (uce->ptr.id.data == ptr->id.data)
1543 /* create new instance */
1544 uce = MEM_callocN(sizeof(tRnaUpdateCacheElem), "tRnaUpdateCacheElem");
1545 BLI_addtail(&rna_updates_cache, uce);
1548 RNA_pointer_create(ptr->id.data, ptr->type, ptr->data, &uce->ptr);
1551 /* check on the update func */
1552 for (ld = uce->L2Funcs.first; ld; ld = ld->next) {
1553 /* stop on match - function already cached */
1557 /* else... if still here, we need to add it */
1558 BLI_addtail(&uce->L2Funcs, BLI_genericNodeN(fn));
1561 void RNA_property_update_cache_flush(Main *bmain, Scene *scene)
1563 tRnaUpdateCacheElem *uce;
1565 // TODO: should we check that bmain and scene are valid? The above stuff doesn't!
1567 /* execute the cached updates */
1568 for (uce = rna_updates_cache.first; uce; uce = uce->next) {
1571 for (ld = uce->L2Funcs.first; ld; ld = ld->next) {
1572 UpdateFunc fn = (UpdateFunc)ld->data;
1573 fn(bmain, scene, &uce->ptr);
1578 void RNA_property_update_cache_free(void)
1580 tRnaUpdateCacheElem *uce, *ucn;
1582 for (uce = rna_updates_cache.first; uce; uce = ucn) {
1586 BLI_freelistN(&uce->L2Funcs);
1589 BLI_freelinkN(&rna_updates_cache, uce);
1593 /* ---------------------------------------------------------------------- */
1597 int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
1599 BoolPropertyRNA *bprop= (BoolPropertyRNA*)prop;
1602 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1603 BLI_assert(RNA_property_array_check(prop) == 0);
1605 if((idprop=rna_idproperty_check(&prop, ptr)))
1606 return IDP_Int(idprop);
1608 return bprop->get(ptr);
1610 return bprop->defaultvalue;
1613 void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1615 BoolPropertyRNA *bprop= (BoolPropertyRNA*)prop;
1618 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1619 BLI_assert(RNA_property_array_check(prop) == 0);
1621 /* just incase other values are passed */
1624 if((idprop=rna_idproperty_check(&prop, ptr)))
1625 IDP_Int(idprop)= value;
1627 bprop->set(ptr, value);
1628 else if(prop->flag & PROP_EDITABLE) {
1629 IDPropertyTemplate val = {0};
1634 group= RNA_struct_idprops(ptr, 1);
1636 IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
1640 void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
1642 BoolPropertyRNA *bprop= (BoolPropertyRNA*)prop;
1645 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1646 BLI_assert(RNA_property_array_check(prop) != 0);
1648 if((idprop=rna_idproperty_check(&prop, ptr))) {
1649 if(prop->arraydimension == 0)
1650 values[0]= RNA_property_boolean_get(ptr, prop);
1652 memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
1654 else if(prop->arraydimension == 0)
1655 values[0]= RNA_property_boolean_get(ptr, prop);
1656 else if(bprop->getarray)
1657 bprop->getarray(ptr, values);
1658 else if(bprop->defaultarray)
1659 memcpy(values, bprop->defaultarray, sizeof(int)*prop->totarraylength);
1661 memset(values, 0, sizeof(int)*prop->totarraylength);
1664 int RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1666 int tmp[RNA_MAX_ARRAY_LENGTH];
1667 int len= rna_ensure_property_array_length(ptr, prop);
1669 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1670 BLI_assert(RNA_property_array_check(prop) != 0);
1672 if(len <= RNA_MAX_ARRAY_LENGTH) {
1673 RNA_property_boolean_get_array(ptr, prop, tmp);
1677 int *tmparray, value;
1679 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_index");
1680 RNA_property_boolean_get_array(ptr, prop, tmparray);
1681 value= tmparray[index];
1682 MEM_freeN(tmparray);
1688 void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
1690 BoolPropertyRNA *bprop= (BoolPropertyRNA*)prop;
1693 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1694 BLI_assert(RNA_property_array_check(prop) != 0);
1696 if((idprop=rna_idproperty_check(&prop, ptr))) {
1697 if(prop->arraydimension == 0)
1698 IDP_Int(idprop)= values[0];
1700 memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
1702 else if(prop->arraydimension == 0)
1703 RNA_property_boolean_set(ptr, prop, values[0]);
1704 else if(bprop->setarray)
1705 bprop->setarray(ptr, values);
1706 else if(prop->flag & PROP_EDITABLE) {
1707 IDPropertyTemplate val = {0};
1710 val.array.len= prop->totarraylength;
1711 val.array.type= IDP_INT;
1713 group= RNA_struct_idprops(ptr, 1);
1715 idprop= IDP_New(IDP_ARRAY, &val, prop->identifier);
1716 IDP_AddToGroup(group, idprop);
1717 memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
1722 void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
1724 int tmp[RNA_MAX_ARRAY_LENGTH];
1725 int len= rna_ensure_property_array_length(ptr, prop);
1727 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1728 BLI_assert(RNA_property_array_check(prop) != 0);
1730 if(len <= RNA_MAX_ARRAY_LENGTH) {
1731 RNA_property_boolean_get_array(ptr, prop, tmp);
1733 RNA_property_boolean_set_array(ptr, prop, tmp);
1738 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_index");
1739 RNA_property_boolean_get_array(ptr, prop, tmparray);
1740 tmparray[index]= value;
1741 RNA_property_boolean_set_array(ptr, prop, tmparray);
1742 MEM_freeN(tmparray);
1746 int RNA_property_boolean_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
1748 BoolPropertyRNA *bprop= (BoolPropertyRNA*)prop;
1750 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1751 BLI_assert(RNA_property_array_check(prop) == 0);
1753 return bprop->defaultvalue;
1756 void RNA_property_boolean_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int *values)
1758 BoolPropertyRNA *bprop= (BoolPropertyRNA*)prop;
1760 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1761 BLI_assert(RNA_property_array_check(prop) != 0);
1763 if(prop->arraydimension == 0)
1764 values[0]= bprop->defaultvalue;
1765 else if(bprop->defaultarray)
1766 memcpy(values, bprop->defaultarray, sizeof(int)*prop->totarraylength);
1768 memset(values, 0, sizeof(int)*prop->totarraylength);
1771 int RNA_property_boolean_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1773 int tmp[RNA_MAX_ARRAY_LENGTH];
1774 int len= rna_ensure_property_array_length(ptr, prop);
1776 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1777 BLI_assert(RNA_property_array_check(prop) != 0);
1779 if(len <= RNA_MAX_ARRAY_LENGTH) {
1780 RNA_property_boolean_get_default_array(ptr, prop, tmp);
1784 int *tmparray, value;
1786 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_default_index");
1787 RNA_property_boolean_get_default_array(ptr, prop, tmparray);
1788 value= tmparray[index];
1789 MEM_freeN(tmparray);
1795 int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
1797 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1800 BLI_assert(RNA_property_type(prop) == PROP_INT);
1801 BLI_assert(RNA_property_array_check(prop) == 0);
1803 if((idprop=rna_idproperty_check(&prop, ptr)))
1804 return IDP_Int(idprop);
1806 return iprop->get(ptr);
1808 return iprop->defaultvalue;
1811 void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1813 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1816 BLI_assert(RNA_property_type(prop) == PROP_INT);
1817 BLI_assert(RNA_property_array_check(prop) == 0);
1818 /* useful to check on bad values but set function should clamp */
1819 /* BLI_assert(RNA_property_int_clamp(ptr, prop, &value) == 0); */
1821 if((idprop=rna_idproperty_check(&prop, ptr)))
1822 IDP_Int(idprop)= value;
1824 iprop->set(ptr, value);
1825 else if(prop->flag & PROP_EDITABLE) {
1826 IDPropertyTemplate val = {0};
1831 group= RNA_struct_idprops(ptr, 1);
1833 IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
1837 void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
1839 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1842 BLI_assert(RNA_property_type(prop) == PROP_INT);
1843 BLI_assert(RNA_property_array_check(prop) != 0);
1845 if((idprop=rna_idproperty_check(&prop, ptr))) {
1846 if(prop->arraydimension == 0)
1847 values[0]= RNA_property_int_get(ptr, prop);
1849 memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
1851 else if(prop->arraydimension == 0)
1852 values[0]= RNA_property_int_get(ptr, prop);
1853 else if(iprop->getarray)
1854 iprop->getarray(ptr, values);
1855 else if(iprop->defaultarray)
1856 memcpy(values, iprop->defaultarray, sizeof(int)*prop->totarraylength);
1858 memset(values, 0, sizeof(int)*prop->totarraylength);
1861 void RNA_property_int_get_array_range(PointerRNA *ptr, PropertyRNA *prop, int values[2])
1863 const int array_len= RNA_property_array_length(ptr, prop);
1865 if(array_len <= 0) {
1869 else if (array_len == 1) {
1870 RNA_property_int_get_array(ptr, prop, values);
1871 values[1]= values[0];
1878 if(array_len > 32) {
1879 arr= MEM_mallocN(sizeof(int) * array_len, "RNA_property_int_get_array_range");
1885 RNA_property_int_get_array(ptr, prop, arr);
1886 values[0]= values[1]= arr[0];
1887 for(i= 1; i < array_len; i++) {
1888 values[0]= MIN2(values[0], arr[i]);
1889 values[1]= MAX2(values[1], arr[i]);
1892 if(arr != arr_stack) {
1898 int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1900 int tmp[RNA_MAX_ARRAY_LENGTH];
1901 int len= rna_ensure_property_array_length(ptr, prop);
1903 BLI_assert(RNA_property_type(prop) == PROP_INT);
1904 BLI_assert(RNA_property_array_check(prop) != 0);
1906 if(len <= RNA_MAX_ARRAY_LENGTH) {
1907 RNA_property_int_get_array(ptr, prop, tmp);
1911 int *tmparray, value;
1913 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_index");
1914 RNA_property_int_get_array(ptr, prop, tmparray);
1915 value= tmparray[index];
1916 MEM_freeN(tmparray);
1922 void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
1924 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1927 BLI_assert(RNA_property_type(prop) == PROP_INT);
1928 BLI_assert(RNA_property_array_check(prop) != 0);
1930 if((idprop=rna_idproperty_check(&prop, ptr))) {
1931 if(prop->arraydimension == 0)
1932 IDP_Int(idprop)= values[0];
1934 memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);\
1936 else if(prop->arraydimension == 0)
1937 RNA_property_int_set(ptr, prop, values[0]);
1938 else if(iprop->setarray)
1939 iprop->setarray(ptr, values);
1940 else if(prop->flag & PROP_EDITABLE) {
1941 IDPropertyTemplate val = {0};
1944 val.array.len= prop->totarraylength;
1945 val.array.type= IDP_INT;
1947 group= RNA_struct_idprops(ptr, 1);
1949 idprop= IDP_New(IDP_ARRAY, &val, prop->identifier);
1950 IDP_AddToGroup(group, idprop);
1951 memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
1956 void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
1958 int tmp[RNA_MAX_ARRAY_LENGTH];
1959 int len= rna_ensure_property_array_length(ptr, prop);
1961 BLI_assert(RNA_property_type(prop) == PROP_INT);
1962 BLI_assert(RNA_property_array_check(prop) != 0);
1964 if(len <= RNA_MAX_ARRAY_LENGTH) {
1965 RNA_property_int_get_array(ptr, prop, tmp);
1967 RNA_property_int_set_array(ptr, prop, tmp);
1972 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_index");
1973 RNA_property_int_get_array(ptr, prop, tmparray);
1974 tmparray[index]= value;
1975 RNA_property_int_set_array(ptr, prop, tmparray);
1976 MEM_freeN(tmparray);
1980 int RNA_property_int_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
1982 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1983 return iprop->defaultvalue;
1986 void RNA_property_int_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int *values)
1988 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1990 BLI_assert(RNA_property_type(prop) == PROP_INT);
1991 BLI_assert(RNA_property_array_check(prop) != 0);
1993 if(prop->arraydimension == 0)
1994 values[0]= iprop->defaultvalue;
1995 else if(iprop->defaultarray)
1996 memcpy(values, iprop->defaultarray, sizeof(int)*prop->totarraylength);
1998 memset(values, 0, sizeof(int)*prop->totarraylength);
2001 int RNA_property_int_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2003 int tmp[RNA_MAX_ARRAY_LENGTH];
2004 int len= rna_ensure_property_array_length(ptr, prop);
2006 if(len <= RNA_MAX_ARRAY_LENGTH) {
2007 RNA_property_int_get_default_array(ptr, prop, tmp);
2011 int *tmparray, value;
2013 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_default_index");
2014 RNA_property_int_get_default_array(ptr, prop, tmparray);
2015 value= tmparray[index];
2016 MEM_freeN(tmparray);
2022 float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
2024 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
2027 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2028 BLI_assert(RNA_property_array_check(prop) == 0);
2030 if((idprop=rna_idproperty_check(&prop, ptr))) {
2031 if(idprop->type == IDP_FLOAT)
2032 return IDP_Float(idprop);
2034 return (float)IDP_Double(idprop);
2037 return fprop->get(ptr);
2039 return fprop->defaultvalue;
2042 void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
2044 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
2047 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2048 BLI_assert(RNA_property_array_check(prop) == 0);
2049 /* useful to check on bad values but set function should clamp */
2050 /* BLI_assert(RNA_property_float_clamp(ptr, prop, &value) == 0); */
2052 if((idprop=rna_idproperty_check(&prop, ptr))) {
2053 if(idprop->type == IDP_FLOAT)
2054 IDP_Float(idprop)= value;
2056 IDP_Double(idprop)= value;
2058 else if(fprop->set) {
2059 fprop->set(ptr, value);
2061 else if(prop->flag & PROP_EDITABLE) {
2062 IDPropertyTemplate val = {0};
2067 group= RNA_struct_idprops(ptr, 1);
2069 IDP_AddToGroup(group, IDP_New(IDP_FLOAT, &val, prop->identifier));
2073 void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
2075 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
2079 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2080 BLI_assert(RNA_property_array_check(prop) != 0);
2082 if((idprop=rna_idproperty_check(&prop, ptr))) {
2083 if(prop->arraydimension == 0)
2084 values[0]= RNA_property_float_get(ptr, prop);
2085 else if(idprop->subtype == IDP_FLOAT) {
2086 memcpy(values, IDP_Array(idprop), sizeof(float)*idprop->len);
2089 for(i=0; i<idprop->len; i++)
2090 values[i]= (float)(((double*)IDP_Array(idprop))[i]);
2093 else if(prop->arraydimension == 0)
2094 values[0]= RNA_property_float_get(ptr, prop);
2095 else if(fprop->getarray)
2096 fprop->getarray(ptr, values);
2097 else if(fprop->defaultarray)
2098 memcpy(values, fprop->defaultarray, sizeof(float)*prop->totarraylength);
2100 memset(values, 0, sizeof(float)*prop->totarraylength);
2103 void RNA_property_float_get_array_range(PointerRNA *ptr, PropertyRNA *prop, float values[2])
2105 const int array_len= RNA_property_array_length(ptr, prop);
2107 if(array_len <= 0) {
2111 else if (array_len == 1) {
2112 RNA_property_float_get_array(ptr, prop, values);
2113 values[1]= values[0];
2116 float arr_stack[32];
2120 if(array_len > 32) {
2121 arr= MEM_mallocN(sizeof(float) * array_len, "RNA_property_float_get_array_range");
2127 RNA_property_float_get_array(ptr, prop, arr);
2128 values[0]= values[1]= arr[0];
2129 for(i= 1; i < array_len; i++) {
2130 values[0]= MIN2(values[0], arr[i]);
2131 values[1]= MAX2(values[1], arr[i]);
2134 if(arr != arr_stack) {
2140 float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2142 float tmp[RNA_MAX_ARRAY_LENGTH];
2143 int len= rna_ensure_property_array_length(ptr, prop);
2145 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2146 BLI_assert(RNA_property_array_check(prop) != 0);
2148 if(len <= RNA_MAX_ARRAY_LENGTH) {
2149 RNA_property_float_get_array(ptr, prop, tmp);
2153 float *tmparray, value;
2155 tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_index");
2156 RNA_property_float_get_array(ptr, prop, tmparray);
2157 value= tmparray[index];
2158 MEM_freeN(tmparray);
2165 void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
2167 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
2171 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2172 BLI_assert(RNA_property_array_check(prop) != 0);
2174 if((idprop=rna_idproperty_check(&prop, ptr))) {
2175 if(prop->arraydimension == 0) {
2176 if(idprop->type == IDP_FLOAT)
2177 IDP_Float(idprop)= values[0];
2179 IDP_Double(idprop)= values[0];
2181 else if(idprop->subtype == IDP_FLOAT) {
2182 memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len);
2185 for(i=0; i<idprop->len; i++)
2186 ((double*)IDP_Array(idprop))[i]= values[i];
2189 else if(prop->arraydimension == 0)
2190 RNA_property_float_set(ptr, prop, values[0]);
2191 else if(fprop->setarray) {
2192 fprop->setarray(ptr, values);
2194 else if(prop->flag & PROP_EDITABLE) {
2195 IDPropertyTemplate val = {0};
2198 val.array.len= prop->totarraylength;
2199 val.array.type= IDP_FLOAT;
2201 group= RNA_struct_idprops(ptr, 1);
2203 idprop= IDP_New(IDP_ARRAY, &val, prop->identifier);
2204 IDP_AddToGroup(group, idprop);
2205 memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len);
2210 void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
2212 float tmp[RNA_MAX_ARRAY_LENGTH];
2213 int len= rna_ensure_property_array_length(ptr, prop);
2215 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2216 BLI_assert(RNA_property_array_check(prop) != 0);
2218 if(len <= RNA_MAX_ARRAY_LENGTH) {
2219 RNA_property_float_get_array(ptr, prop, tmp);
2221 RNA_property_float_set_array(ptr, prop, tmp);
2226 tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_index");
2227 RNA_property_float_get_array(ptr, prop, tmparray);
2228 tmparray[index]= value;
2229 RNA_property_float_set_array(ptr, prop, tmparray);
2230 MEM_freeN(tmparray);
2234 float RNA_property_float_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2236 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
2238 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2239 BLI_assert(RNA_property_array_check(prop) == 0);
2241 return fprop->defaultvalue;
2244 void RNA_property_float_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, float *values)
2246 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
2248 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2249 BLI_assert(RNA_property_array_check(prop) != 0);
2251 if(prop->arraydimension == 0)
2252 values[0]= fprop->defaultvalue;
2253 else if(fprop->defaultarray)
2254 memcpy(values, fprop->defaultarray, sizeof(float)*prop->totarraylength);
2256 memset(values, 0, sizeof(float)*prop->totarraylength);
2259 float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2261 float tmp[RNA_MAX_ARRAY_LENGTH];
2262 int len= rna_ensure_property_array_length(ptr, prop);
2264 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2265 BLI_assert(RNA_property_array_check(prop) != 0);
2267 if(len <= RNA_MAX_ARRAY_LENGTH) {
2268 RNA_property_float_get_default_array(ptr, prop, tmp);
2272 float *tmparray, value;
2274 tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_default_index");
2275 RNA_property_float_get_default_array(ptr, prop, tmparray);
2276 value= tmparray[index];
2277 MEM_freeN(tmparray);
2283 void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
2285 StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
2288 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2290 if((idprop=rna_idproperty_check(&prop, ptr))) {
2291 /* editing bytes is not 100% supported
2292 * since they can contain NIL chars */
2293 if (idprop->subtype == IDP_STRING_SUB_BYTE) {
2294 memcpy(value, IDP_String(idprop), idprop->len);
2295 value[idprop->len]= '\0';
2298 memcpy(value, IDP_String(idprop), idprop->len);
2301 else if(sprop->get) {
2302 sprop->get(ptr, value);
2305 strcpy(value, sprop->defaultvalue);
2309 char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop,
2310 char *fixedbuf, int fixedlen, int *r_len)
2315 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2317 length= RNA_property_string_length(ptr, prop);
2319 if(length+1 < fixedlen)
2322 buf= MEM_mallocN(sizeof(char)*(length+1), "RNA_string_get_alloc");
2325 /* safety check to ensure the string is actually set */
2329 RNA_property_string_get(ptr, prop, buf);
2332 BLI_assert(buf[length] == '\0');
2342 /* this is the length without \0 terminator */
2343 int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
2345 StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
2348 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2350 if((idprop=rna_idproperty_check(&prop, ptr))) {
2351 if (idprop->subtype == IDP_STRING_SUB_BYTE) {
2356 /* these _must_ stay in sync */
2357 BLI_assert(strlen(IDP_String(idprop)) == idprop->len - 1);
2359 return idprop->len - 1;
2362 else if(sprop->length)
2363 return sprop->length(ptr);
2365 return strlen(sprop->defaultvalue);
2368 void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
2370 StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
2373 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2375 if((idprop=rna_idproperty_check(&prop, ptr)))
2376 /* both IDP_STRING_SUB_BYTE / IDP_STRING_SUB_UTF8 */
2377 IDP_AssignString(idprop, value, RNA_property_string_maxlength(prop) - 1);
2379 sprop->set(ptr, value); /* set function needs to clamp its self */
2380 else if(prop->flag & PROP_EDITABLE) {
2383 group= RNA_struct_idprops(ptr, 1);
2385 IDP_AddToGroup(group, IDP_NewString(value, prop->identifier, RNA_property_string_maxlength(prop) - 1));
2389 void RNA_property_string_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop, char *value)
2391 StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
2393 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2395 strcpy(value, sprop->defaultvalue);
2398 char *RNA_property_string_get_default_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen)
2403 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2405 length= RNA_property_string_default_length(ptr, prop);
2407 if(length+1 < fixedlen)
2410 buf= MEM_callocN(sizeof(char)*(length+1), "RNA_string_get_alloc");
2412 RNA_property_string_get_default(ptr, prop, buf);
2417 /* this is the length without \0 terminator */
2418 int RNA_property_string_default_length(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2420 StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
2422 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2424 return strlen(sprop->defaultvalue);
2427 int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
2429 EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
2432 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2434 if((idprop=rna_idproperty_check(&prop, ptr)))
2435 return IDP_Int(idprop);
2437 return eprop->get(ptr);
2439 return eprop->defaultvalue;
2442 void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
2444 EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
2447 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2449 if((idprop=rna_idproperty_check(&prop, ptr)))
2450 IDP_Int(idprop)= value;
2451 else if(eprop->set) {
2452 eprop->set(ptr, value);
2454 else if(prop->flag & PROP_EDITABLE) {
2455 IDPropertyTemplate val = {0};
2460 group= RNA_struct_idprops(ptr, 1);
2462 IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
2466 int RNA_property_enum_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2468 EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
2470 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2472 return eprop->defaultvalue;
2475 void *RNA_property_enum_py_data_get(PropertyRNA *prop)
2477 EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
2479 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2481 return eprop->py_data;
2484 PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
2486 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
2489 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2491 if((idprop=rna_idproperty_check(&prop, ptr))) {
2492 pprop= (PointerPropertyRNA*)prop;
2494 /* for groups, data is idprop itself */
2495 return rna_pointer_inherit_refine(ptr, pprop->type, idprop);
2497 else if(pprop->get) {
2498 return pprop->get(ptr);
2500 else if(prop->flag & PROP_IDPROPERTY) {
2501 /* XXX temporary hack to add it automatically, reading should
2502 never do any write ops, to ensure thread safety etc .. */
2503 RNA_property_pointer_add(ptr, prop);
2504 return RNA_property_pointer_get(ptr, prop);
2507 return PointerRNA_NULL;
2511 void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value)
2513 /*IDProperty *idprop;*/
2515 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2517 if((/*idprop=*/ rna_idproperty_check(&prop, ptr))) {
2521 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
2524 !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL) &&
2525 !((prop->flag & PROP_ID_SELF_CHECK) && ptr->id.data == ptr_value.id.data)
2527 pprop->set(ptr, ptr_value);
2532 PointerRNA RNA_property_pointer_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop))
2534 //PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
2536 // BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2538 return PointerRNA_NULL; // FIXME: there has to be a way...
2541 void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop)
2543 /*IDProperty *idprop;*/
2545 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2547 if((/*idprop=*/rna_idproperty_check(&prop, ptr))) {
2548 /* already exists */
2550 else if(prop->flag & PROP_IDPROPERTY) {
2551 IDPropertyTemplate val = {0};
2556 group= RNA_struct_idprops(ptr, 1);
2558 IDP_AddToGroup(group, IDP_New(IDP_GROUP, &val, prop->identifier));
2561 printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);
2564 void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop)
2566 IDProperty *idprop, *group;
2568 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2570 if((idprop=rna_idproperty_check(&prop, ptr))) {
2571 group= RNA_struct_idprops(ptr, 0);
2574 IDP_RemFromGroup(group, idprop);
2575 IDP_FreeProperty(idprop);
2580 printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);
2583 static void rna_property_collection_get_idp(CollectionPropertyIterator *iter)
2585 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
2587 iter->ptr.data= rna_iterator_array_get(iter);
2588 iter->ptr.type= cprop->item_type;
2589 rna_pointer_inherit_id(cprop->item_type, &iter->parent, &iter->ptr);
2592 void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter)
2596 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2598 memset(iter, 0, sizeof(*iter));
2600 if((idprop=rna_idproperty_check(&prop, ptr)) || (prop->flag & PROP_IDPROPERTY)) {
2605 rna_iterator_array_begin(iter, IDP_IDPArray(idprop), sizeof(IDProperty), idprop->len, 0, NULL);
2607 rna_iterator_array_begin(iter, NULL, sizeof(IDProperty), 0, 0, NULL);
2610 rna_property_collection_get_idp(iter);
2615 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
2616 cprop->begin(iter, ptr);
2620 void RNA_property_collection_next(CollectionPropertyIterator *iter)
2622 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(iter->prop);
2625 rna_iterator_array_next(iter);
2628 rna_property_collection_get_idp(iter);
2634 void RNA_property_collection_end(CollectionPropertyIterator *iter)
2636 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(iter->prop);
2639 rna_iterator_array_end(iter);
2644 int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
2646 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
2649 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2651 if((idprop=rna_idproperty_check(&prop, ptr))) {
2654 else if(cprop->length) {
2655 return cprop->length(ptr);
2658 CollectionPropertyIterator iter;
2661 RNA_property_collection_begin(ptr, prop, &iter);
2662 for(; iter.valid; RNA_property_collection_next(&iter))
2664 RNA_property_collection_end(&iter);
2670 void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
2673 // CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
2675 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2677 if((idprop=rna_idproperty_check(&prop, ptr))) {
2678 IDPropertyTemplate val = {0};
2681 item= IDP_New(IDP_GROUP, &val, "");
2682 IDP_AppendArray(idprop, item);
2683 // IDP_FreeProperty(item); // IDP_AppendArray does a shallow copy (memcpy), only free memory
2686 else if(prop->flag & PROP_IDPROPERTY) {
2687 IDProperty *group, *item;
2688 IDPropertyTemplate val = {0};
2690 group= RNA_struct_idprops(ptr, 1);
2692 idprop= IDP_NewIDPArray(prop->identifier);
2693 IDP_AddToGroup(group, idprop);
2695 item= IDP_New(IDP_GROUP, &val, "");
2696 IDP_AppendArray(idprop, item);
2697 // IDP_FreeProperty(item); // IDP_AppendArray does a shallow copy (memcpy), only free memory
2702 /* py api calls directly */
2704 else if(cprop->add){
2705 if(!(cprop->add->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
2706 ParameterList params;
2707 RNA_parameter_list_create(¶ms, ptr, cprop->add);
2708 RNA_function_call(NULL, NULL, ptr, cprop->add, ¶ms);
2709 RNA_parameter_list_free(¶ms);
2713 printf("%s %s.%s: not implemented for this property.\n", __func__, ptr->type->identifier, prop->identifier);*/
2718 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
2720 r_ptr->data= IDP_GetIndexArray(idprop, idprop->len-1);
2721 r_ptr->type= cprop->item_type;
2722 rna_pointer_inherit_id(NULL, ptr, r_ptr);
2725 memset(r_ptr, 0, sizeof(*r_ptr));
2729 int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
2732 // CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
2734 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2736 if((idprop=rna_idproperty_check(&prop, ptr))) {
2737 IDProperty tmp, *array;
2741 array= IDP_IDPArray(idprop);
2743 if(key >= 0 && key < len) {
2745 /* move element to be removed to the back */
2746 memcpy(&tmp, &array[key], sizeof(IDProperty));
2747 memmove(array+key, array+key+1, sizeof(IDProperty)*(len-(key+1)));
2748 memcpy(&array[len-1], &tmp, sizeof(IDProperty));
2751 IDP_ResizeIDPArray(idprop, len-1);
2756 else if(prop->flag & PROP_IDPROPERTY)
2759 /* py api calls directly */
2761 else if(cprop->remove){
2762 if(!(cprop->remove->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
2763 ParameterList params;
2764 RNA_parameter_list_create(¶ms, ptr, cprop->remove);
2765 RNA_function_call(NULL, NULL, ptr, cprop->remove, ¶ms);
2766 RNA_parameter_list_free(¶ms);
2772 printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);*/
2777 int RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos)
2781 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2783 if((idprop=rna_idproperty_check(&prop, ptr))) {
2784 IDProperty tmp, *array;
2788 array= IDP_IDPArray(idprop);
2790 if(key >= 0 && key < len && pos >= 0 && pos < len && key != pos) {
2791 memcpy(&tmp, &array[key], sizeof(IDProperty));
2793 memmove(array+pos+1, array+pos, sizeof(IDProperty)*(key - pos));
2795 memmove(array+key, array+key+1, sizeof(IDProperty)*(pos - key));
2796 memcpy(&array[pos], &tmp, sizeof(IDProperty));
2801 else if(prop->flag & PROP_IDPROPERTY)
2807 void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
2811 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2813 if((idprop=rna_idproperty_check(&prop, ptr)))
2814 IDP_ResizeIDPArray(idprop, 0);
2817 int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *t_ptr)
2819 CollectionPropertyIterator iter;
2822 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2824 RNA_property_collection_begin(ptr, prop, &iter);
2825 for(index=0; iter.valid; RNA_property_collection_next(&iter), index++) {
2826 if (iter.ptr.data == t_ptr->data)
2829 RNA_property_collection_end(&iter);
2831 /* did we find it? */
2838 int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
2840 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(prop);
2842 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2844 if(cprop->lookupint) {
2845 /* we have a callback defined, use it */
2846 return cprop->lookupint(ptr, key, r_ptr);
2849 /* no callback defined, just iterate and find the nth item */
2850 CollectionPropertyIterator iter;
2853 RNA_property_collection_begin(ptr, prop, &iter);
2854 for(i=0; iter.valid; RNA_property_collection_next(&iter), i++) {
2860 RNA_property_collection_end(&iter);
2863 memset(r_ptr, 0, sizeof(*r_ptr));
2869 int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr)
2871 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(prop);
2873 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2875 if(cprop->lookupstring) {
2876 /* we have a callback defined, use it */
2877 return cprop->lookupstring(ptr, key, r_ptr);
2880 /* no callback defined, compare with name properties if they exist */
2881 CollectionPropertyIterator iter;
2882 PropertyRNA *nameprop;
2883 char name[256], *nameptr;
2885 int keylen= strlen(key);
2888 RNA_property_collection_begin(ptr, prop, &iter);
2889 for(; iter.valid; RNA_property_collection_next(&iter)) {
2890 if(iter.ptr.data && iter.ptr.type->nameproperty) {
2891 nameprop= iter.ptr.type->nameproperty;
2893 nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name), &namelen);
2895 if((keylen == namelen) && (strcmp(nameptr, key) == 0)) {
2900 if((char *)&name != nameptr)
2907 RNA_property_collection_end(&iter);
2910 memset(r_ptr, 0, sizeof(*r_ptr));
2916 /* zero return is an assignment error */
2917 int RNA_property_collection_assign_int(PointerRNA *ptr, PropertyRNA *prop, const int key, const PointerRNA *assign_ptr)
2919 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(prop);
2921 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2923 if(cprop->assignint) {
2924 /* we have a callback defined, use it */
2925 return cprop->assignint(ptr, key, assign_ptr);
2931 int RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
2933 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2936 return ((r_ptr->type = rna_ensure_property(prop)->srna) ? 1:0);
2939 int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array)
2941 CollectionPropertyIterator iter;
2942 ArrayIterator *internal;
2945 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2947 if(!(prop->flag & PROP_RAW_ARRAY) || !(itemprop->flag & PROP_RAW_ACCESS))
2950 RNA_property_collection_begin(ptr, prop, &iter);
2953 /* get data from array iterator and item property */
2954 internal= iter.internal;
2955 arrayp= (iter.valid)? iter.ptr.data: NULL;
2957 if(internal->skip || !RNA_property_editable(&iter.ptr, itemprop)) {
2958 /* we might skip some items, so it's not a proper array */
2959 RNA_property_collection_end(&iter);
2963 array->array= arrayp + itemprop->rawoffset;
2964 array->stride= internal->itemsize;
2965 array->len= ((char*)internal->endptr - arrayp)/internal->itemsize;
2966 array->type= itemprop->rawtype;
2969 memset(array, 0, sizeof(RawArray));
2971 RNA_property_collection_end(&iter);
2976 #define RAW_GET(dtype, var, raw, a) \
2978 switch(raw.type) { \
2979 case PROP_RAW_CHAR: var = (dtype)((char*)raw.array)[a]; break; \
2980 case PROP_RAW_SHORT: var = (dtype)((short*)raw.array)[a]; break; \
2981 case PROP_RAW_INT: var = (dtype)((int*)raw.array)[a]; break; \
2982 case PROP_RAW_FLOAT: var = (dtype)((float*)raw.array)[a]; break; \
2983 case PROP_RAW_DOUBLE: var = (dtype)((double*)raw.array)[a]; break; \
2984 default: var = (dtype)0; \
2988 #define RAW_SET(dtype, raw, a, var) \
2990 switch(raw.type) { \
2991 case PROP_RAW_CHAR: ((char*)raw.array)[a] = (char)var; break; \
2992 case PROP_RAW_SHORT: ((short*)raw.array)[a] = (short)var; break; \
2993 case PROP_RAW_INT: ((int*)raw.array)[a] = (int)var; break; \
2994 case PROP_RAW_FLOAT: ((float*)raw.array)[a] = (float)var; break; \
2995 case PROP_RAW_DOUBLE: ((double*)raw.array)[a] = (double)var; break; \
3000 int RNA_raw_type_sizeof(RawPropertyType type)
3003 case PROP_RAW_CHAR: return sizeof(char);
3004 case PROP_RAW_SHORT: return sizeof(short);
3005 case PROP_RAW_INT: return sizeof(int);
3006 case PROP_RAW_FLOAT: return sizeof(float);
3007 case PROP_RAW_DOUBLE: return sizeof(double);
3012 static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname, void *inarray, RawPropertyType intype, int inlen, int set)
3016 PropertyRNA *itemprop, *iprop;
3017 PropertyType itemtype=0;
3021 /* initialize in array, stride assumed 0 in following code */
3027 ptype= RNA_property_pointer_type(ptr, prop);
3029 /* try to get item property pointer */
3030 RNA_pointer_create(NULL, ptype, NULL, &itemptr);
3031 itemprop= RNA_struct_find_property(&itemptr, propname);
3034 /* we have item property pointer */
3038 itemtype= RNA_property_type(itemprop);
3040 if(!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
3041 BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported");
3045 /* check item array */
3046 itemlen= RNA_property_array_length(&itemptr, itemprop);
3048 /* try to access as raw array */
3049 if(RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
3050 int arraylen = (itemlen == 0) ? 1 : itemlen;
3051 if(in.len != arraylen*out.len) {
3052 BKE_reportf(reports, RPT_ERROR, "Array length mismatch (expected %d, got %d)", out.len*arraylen, in.len);
3056 /* matching raw types */
3057 if(out.type == in.type) {
3058 void *inp= in.array;
3059 void *outp= out.array;
3062 size= RNA_raw_type_sizeof(out.type) * arraylen;
3064 for(a=0; a<out.len; a++) {
3065 if(set) memcpy(outp, inp, size);
3066 else memcpy(inp, outp, size);
3068 inp= (char*)inp + size;
3069 outp= (char*)outp + out.stride;
3075 /* could also be faster with non-matching types,
3076 * for now we just do slower loop .. */
3081 void *tmparray= NULL;
3083 int err= 0, j, a= 0;
3086 if (((itemtype == PROP_BOOLEAN || itemtype == PROP_INT) && in.type == PROP_RAW_INT) ||
3087 (itemtype == PROP_FLOAT && in.type == PROP_RAW_FLOAT))
3088 /* avoid creating temporary buffer if the data type match */
3091 /* no item property pointer, can still be id property, or
3092 * property of a type derived from the collection pointer type */
3093 RNA_PROP_BEGIN(ptr, itemptr, prop) {
3096 /* we got the property already */
3100 /* not yet, look it up and verify if it is valid */
3101 iprop= RNA_struct_find_property(&itemptr, propname);
3104 itemlen= RNA_property_array_length(&itemptr, iprop);
3105 itemtype= RNA_property_type(iprop);
3108 BKE_reportf(reports, RPT_ERROR, "Property named %s not found", propname);
3113 if(!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
3114 BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported");
3120 /* editable check */
3121 if(!set || RNA_property_editable(&itemptr, iprop)) {
3122 if(a+itemlen > in.len) {
3123 BKE_reportf(reports, RPT_ERROR, "Array length mismatch (got %d, expected more)", in.len);
3129 /* handle conversions */
3132 case PROP_BOOLEAN: {
3134 RAW_GET(int, b, in, a);
3135 RNA_property_boolean_set(&itemptr, iprop, b);
3140 RAW_GET(int, i, in, a);
3141 RNA_property_int_set(&itemptr, iprop, i);
3146 RAW_GET(float, f, in, a);
3147 RNA_property_float_set(&itemptr, iprop, f);
3156 case PROP_BOOLEAN: {
3157 int b= RNA_property_boolean_get(&itemptr, iprop);
3158 RAW_SET(int, in, a, b);
3162 int i= RNA_property_int_get(&itemptr, iprop);
3163 RAW_SET(int, in, a, i);
3167 float f= RNA_property_float_get(&itemptr, iprop);
3168 RAW_SET(float, in, a, f);
3177 else if (needconv == 1) {
3178 /* allocate temporary array if needed */
3179 if(tmparray && tmplen != itemlen) {
3180 MEM_freeN(tmparray);
3184 tmparray= MEM_callocN(sizeof(float)*itemlen, "RNA tmparray\n");
3188 /* handle conversions */
3191 case PROP_BOOLEAN: {
3192 for(j=0; j<itemlen; j++, a++)
3193 RAW_GET(int, ((int*)tmparray)[j], in, a);
3194 RNA_property_boolean_set_array(&itemptr, iprop, tmparray);
3198 for(j=0; j<itemlen; j++, a++)
3199 RAW_GET(int, ((int*)tmparray)[j], in, a);
3200 RNA_property_int_set_array(&itemptr, iprop, tmparray);
3204 for(j=0; j<itemlen; j++, a++)
3205 RAW_GET(float, ((float*)tmparray)[j], in, a);
3206 RNA_property_float_set_array(&itemptr, iprop, tmparray);
3215 case PROP_BOOLEAN: {
3216 RNA_property_boolean_get_array(&itemptr, iprop, tmparray);
3217 for(j=0; j<itemlen; j++, a++)
3218 RAW_SET(int, in, a, ((int*)tmparray)[j]);
3222 RNA_property_int_get_array(&itemptr, iprop, tmparray);
3223 for(j=0; j<itemlen; j++, a++)
3224 RAW_SET(int, in, a, ((int*)tmparray)[j]);
3228 RNA_property_float_get_array(&itemptr, iprop, tmparray);
3229 for(j=0; j<itemlen; j++, a++)
3230 RAW_SET(float, in, a, ((float*)tmparray)[j]);
3241 case PROP_BOOLEAN: {
3242 RNA_property_boolean_set_array(&itemptr, iprop, &((int*)in.array)[a]);
3247 RNA_property_int_set_array(&itemptr, iprop, &((int*)in.array)[a]);
3252 RNA_property_float_set_array(&itemptr, iprop, &((float*)in.array)[a]);