4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * Contributor(s): Blender Foundation (2008).
22 * ***** END GPL LICENSE BLOCK *****
25 /** \file blender/makesrna/intern/rna_access.c
35 #include "MEM_guardedalloc.h"
38 #include "DNA_scene_types.h"
39 #include "DNA_windowmanager_types.h"
41 #include "BLI_blenlib.h"
42 #include "BLI_utildefines.h"
43 #include "BLI_dynstr.h"
44 #include "BLI_ghash.h"
46 #include "BKE_animsys.h"
47 #include "BKE_context.h"
48 #include "BKE_idprop.h"
50 #include "BKE_report.h"
55 #include "RNA_access.h"
56 #include "RNA_define.h"
59 #include "DNA_object_types.h"
60 #include "BKE_depsgraph.h"
63 #include "rna_internal.h"
65 const PointerRNA PointerRNA_NULL= {{NULL}};
74 for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
75 if(!srna->cont.prophash) {
76 srna->cont.prophash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "RNA_init gh");
78 for(prop=srna->cont.properties.first; prop; prop=prop->next)
79 if(!(prop->flag & PROP_BUILTIN))
80 BLI_ghash_insert(srna->cont.prophash, (void*)prop->identifier, prop);
89 for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
90 if(srna->cont.prophash) {
91 BLI_ghash_free(srna->cont.prophash, NULL, NULL);
92 srna->cont.prophash= NULL;
96 RNA_free(&BLENDER_RNA);
101 void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr)
103 r_ptr->id.data= NULL;
104 r_ptr->type= &RNA_BlendData;
108 void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
110 StructRNA *type, *idtype= NULL;
113 PointerRNA tmp= {{NULL}};
115 idtype= rna_ID_refine(&tmp);
117 while(idtype->refine) {
118 type= idtype->refine(&tmp);
132 void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
135 StructRNA *idtype= NULL;
138 PointerRNA tmp= {{0}};
140 idtype= rna_ID_refine(&tmp);
149 while(r_ptr->type && r_ptr->type->refine) {
150 StructRNA *rtype= r_ptr->type->refine(r_ptr);
152 if(rtype == r_ptr->type)
160 static void rna_pointer_inherit_id(StructRNA *type, PointerRNA *parent, PointerRNA *ptr)
162 if(type && type->flag & STRUCT_ID) {
163 ptr->id.data= ptr->data;
166 ptr->id.data= parent->id.data;
170 void RNA_blender_rna_pointer_create(PointerRNA *r_ptr)
172 r_ptr->id.data= NULL;
173 r_ptr->type= &RNA_BlenderRNA;
174 r_ptr->data= &BLENDER_RNA;
177 PointerRNA rna_pointer_inherit_refine(PointerRNA *ptr, StructRNA *type, void *data)
183 rna_pointer_inherit_id(type, ptr, &result);
185 while(result.type->refine) {
186 type= result.type->refine(&result);
188 if(type == result.type)
196 return PointerRNA_NULL;
201 void RNA_pointer_recast(PointerRNA *ptr, PointerRNA *r_ptr)
203 #if 0 // works but this case if covered by more general code below.
204 if(RNA_struct_is_ID(ptr->type)) {
206 RNA_id_pointer_create(ptr->id.data, r_ptr);
213 *r_ptr= *ptr; /* initialize as the same incase cant recast */
215 for(base=ptr->type->base; base; base=base->base) {
216 t_ptr= rna_pointer_inherit_refine(ptr, base, ptr->data);
217 if(t_ptr.type && t_ptr.type != ptr->type) {
226 /* return a UI local ID prop definition for this prop */
227 IDProperty *rna_idproperty_ui(PropertyRNA *prop)
231 for(idprop= ((IDProperty *)prop)->prev; idprop; idprop= idprop->prev) {
232 if (strcmp(RNA_IDP_UI, idprop->name)==0)
237 for(idprop= ((IDProperty *)prop)->next; idprop; idprop= idprop->next) {
238 if (strcmp(RNA_IDP_UI, idprop->name)==0)
244 return IDP_GetPropertyTypeFromGroup(idprop, ((IDProperty *)prop)->name, IDP_GROUP);
250 IDProperty *RNA_struct_idprops(PointerRNA *ptr, int create)
252 StructRNA *type= ptr->type;
254 if(type && type->idproperties)
255 return type->idproperties(ptr, create);
260 int RNA_struct_idprops_check(StructRNA *srna)
262 return (srna && srna->idproperties) ? 1 : 0;
265 static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name)
267 IDProperty *group= RNA_struct_idprops(ptr, 0);
270 return IDP_GetPropertyFromGroup(group, name);
275 static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
277 if(prop->magic == RNA_MAGIC) {
278 int arraylen[RNA_MAX_ARRAY_DIMENSION];
279 return (prop->getlength && ptr->data)? prop->getlength(ptr, arraylen): prop->totarraylength;
282 IDProperty *idprop= (IDProperty*)prop;
284 if(idprop->type == IDP_ARRAY)
291 static int rna_ensure_property_array_check(PointerRNA *ptr, PropertyRNA *prop)
293 if(prop->magic == RNA_MAGIC) {
294 return (prop->getlength || prop->totarraylength) ? 1:0;
297 IDProperty *idprop= (IDProperty*)prop;
299 return idprop->type == IDP_ARRAY ? 1:0;
303 static void rna_ensure_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int length[])
305 if(prop->magic == RNA_MAGIC) {
307 prop->getlength(ptr, length);
309 memcpy(length, prop->arraylength, prop->arraydimension*sizeof(int));
312 IDProperty *idprop= (IDProperty*)prop;
314 if(idprop->type == IDP_ARRAY)
315 length[0]= idprop->len;
321 static int rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDProperty *idprop)
323 /* this verifies if the idproperty actually matches the property
324 * description and otherwise removes it. this is to ensure that
325 * rna property access is type safe, e.g. if you defined the rna
326 * to have a certain array length you can count on that staying so */
328 switch(idprop->type) {
330 if(prop->type != PROP_COLLECTION)
334 if(rna_ensure_property_array_length(ptr, prop) != idprop->len)
337 if(idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT)
339 if(idprop->subtype == IDP_INT && !ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
344 if(!ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
349 if(prop->type != PROP_FLOAT)
353 if(prop->type != PROP_STRING)
357 if(prop->type != PROP_POINTER)
367 static PropertyRNA *typemap[IDP_NUMTYPES] =
368 {(PropertyRNA*)&rna_PropertyGroupItem_string,
369 (PropertyRNA*)&rna_PropertyGroupItem_int,
370 (PropertyRNA*)&rna_PropertyGroupItem_float,
372 (PropertyRNA*)&rna_PropertyGroupItem_group, NULL,
373 (PropertyRNA*)&rna_PropertyGroupItem_double,
374 (PropertyRNA*)&rna_PropertyGroupItem_idp_array};
376 static PropertyRNA *arraytypemap[IDP_NUMTYPES] =
377 {NULL, (PropertyRNA*)&rna_PropertyGroupItem_int_array,
378 (PropertyRNA*)&rna_PropertyGroupItem_float_array,
380 (PropertyRNA*)&rna_PropertyGroupItem_collection, NULL,
381 (PropertyRNA*)&rna_PropertyGroupItem_double_array};
383 IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr)
385 /* This is quite a hack, but avoids some complexity in the API. we
386 * pass IDProperty structs as PropertyRNA pointers to the outside.
387 * We store some bytes in PropertyRNA structs that allows us to
388 * distinguish it from IDProperty structs. If it is an ID property,
389 * we look up an IDP PropertyRNA based on the type, and set the data
390 * pointer to the IDProperty. */
392 if((*prop)->magic == RNA_MAGIC) {
393 if((*prop)->flag & PROP_IDPROPERTY) {
394 IDProperty *idprop= rna_idproperty_find(ptr, (*prop)->identifier);
396 if(idprop && !rna_idproperty_verify_valid(ptr, *prop, idprop)) {
397 IDProperty *group= RNA_struct_idprops(ptr, 0);
399 IDP_RemFromGroup(group, idprop);
400 IDP_FreeProperty(idprop);
412 IDProperty *idprop= (IDProperty*)(*prop);
414 if(idprop->type == IDP_ARRAY)
415 *prop= arraytypemap[(int)(idprop->subtype)];
417 *prop= typemap[(int)(idprop->type)];
423 static PropertyRNA *rna_ensure_property(PropertyRNA *prop)
425 /* the quick version if we don't need the idproperty */
427 if(prop->magic == RNA_MAGIC)
431 IDProperty *idprop= (IDProperty*)prop;
433 if(idprop->type == IDP_ARRAY)
434 return arraytypemap[(int)(idprop->subtype)];
436 return typemap[(int)(idprop->type)];
440 static const char *rna_ensure_property_identifier(PropertyRNA *prop)
442 if(prop->magic == RNA_MAGIC)
443 return prop->identifier;
445 return ((IDProperty*)prop)->name;
448 static const char *rna_ensure_property_description(PropertyRNA *prop)
450 if(prop->magic == RNA_MAGIC)
451 return prop->description;
453 /* attempt to get the local ID values */
454 IDProperty *idp_ui= rna_idproperty_ui(prop);
457 IDProperty *item= IDP_GetPropertyTypeFromGroup(idp_ui, "description", IDP_STRING);
459 return IDP_String(item);
462 return ((IDProperty*)prop)->name; /* XXX - not correct */
466 static const char *rna_ensure_property_name(PropertyRNA *prop)
468 if(prop->magic == RNA_MAGIC)
471 return ((IDProperty*)prop)->name;
476 const char *RNA_struct_identifier(StructRNA *type)
478 return type->identifier;
481 const char *RNA_struct_ui_name(StructRNA *type)
486 int RNA_struct_ui_icon(StructRNA *type)
494 const char *RNA_struct_ui_description(StructRNA *type)
496 return type->description;
499 PropertyRNA *RNA_struct_name_property(StructRNA *type)
501 return type->nameproperty;
504 PropertyRNA *RNA_struct_iterator_property(StructRNA *type)
506 return type->iteratorproperty;
509 StructRNA *RNA_struct_base(StructRNA *type)
514 int RNA_struct_is_ID(StructRNA *type)
516 return (type->flag & STRUCT_ID) != 0;
519 int RNA_struct_idprops_register_check(StructRNA *type)
521 return (type->flag & STRUCT_NO_IDPROPERTIES) == 0;
524 int RNA_struct_is_a(StructRNA *type, StructRNA *srna)
531 /* ptr->type is always maximally refined */
532 for(base=type; base; base=base->base)
539 PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
541 if(identifier[0]=='[' && identifier[1]=='"') { // " (dummy comment to avoid confusing some function lists in text editors)
542 /* id prop lookup, not so common */
543 PropertyRNA *r_prop= NULL;
544 PointerRNA r_ptr; /* only support single level props */
545 if(RNA_path_resolve(ptr, identifier, &r_ptr, &r_prop) && r_ptr.type==ptr->type && r_ptr.data==ptr->data)
549 /* most common case */
550 PropertyRNA *iterprop= RNA_struct_iterator_property(ptr->type);
553 if(RNA_property_collection_lookup_string(ptr, iterprop, identifier, &propptr))
560 /* Find the property which uses the given nested struct */
561 PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
563 PropertyRNA *prop= NULL;
565 RNA_STRUCT_BEGIN(ptr, iprop) {
566 /* This assumes that there can only be one user of this nested struct */
567 if (RNA_property_pointer_type(ptr, iprop) == srna) {
577 int RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test)
579 /* note, prop_test could be freed memory, only use for comparison */
581 /* validate the RNA is ok */
582 PropertyRNA *iterprop;
585 iterprop= RNA_struct_iterator_property(ptr->type);
587 RNA_PROP_BEGIN(ptr, itemptr, iterprop) {
588 /* PropertyRNA *prop= itemptr.data; */
589 if(prop_test == (PropertyRNA *)itemptr.data) {
599 /* low level direct access to type->properties, note this ignores parent classes so should be used with care */
600 const struct ListBase *RNA_struct_type_properties(StructRNA *srna)
602 return &srna->cont.properties;
605 PropertyRNA *RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
607 return BLI_findstring_ptr(&srna->cont.properties, identifier, offsetof(PropertyRNA, identifier));
610 FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier)
615 for(type= ptr->type; type; type= type->base) {
616 func= (FunctionRNA *)BLI_findstring_ptr(&type->functions, identifier, offsetof(FunctionRNA, identifier));
623 /* funcitonal but slow */
626 PropertyRNA *iterprop;
629 RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr);
630 iterprop= RNA_struct_find_property(&tptr, "functions");
634 RNA_PROP_BEGIN(&tptr, funcptr, iterprop) {
635 if(strcmp(identifier, RNA_function_identifier(funcptr.data)) == 0) {
646 const struct ListBase *RNA_struct_type_functions(StructRNA *srna)
648 return &srna->functions;
651 StructRegisterFunc RNA_struct_register(StructRNA *type)
656 StructUnregisterFunc RNA_struct_unregister(StructRNA *type)
661 } while((type=type->base));
666 void *RNA_struct_py_type_get(StructRNA *srna)
668 return srna->py_type;
671 void RNA_struct_py_type_set(StructRNA *srna, void *py_type)
673 srna->py_type= py_type;
676 void *RNA_struct_blender_type_get(StructRNA *srna)
678 return srna->blender_type;
681 void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
683 srna->blender_type= blender_type;
686 char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen)
688 PropertyRNA *nameprop;
690 if(ptr->data && (nameprop = RNA_struct_name_property(ptr->type)))
691 return RNA_property_string_get_alloc(ptr, nameprop, fixedbuf, fixedlen);
696 /* Property Information */
698 const char *RNA_property_identifier(PropertyRNA *prop)
700 return rna_ensure_property_identifier(prop);
703 const char *RNA_property_description(PropertyRNA *prop)
705 return rna_ensure_property_description(prop);
708 PropertyType RNA_property_type(PropertyRNA *prop)
710 return rna_ensure_property(prop)->type;
713 PropertySubType RNA_property_subtype(PropertyRNA *prop)
715 return rna_ensure_property(prop)->subtype;
718 PropertyUnit RNA_property_unit(PropertyRNA *prop)
720 return RNA_SUBTYPE_UNIT(rna_ensure_property(prop)->subtype);
723 int RNA_property_flag(PropertyRNA *prop)
725 return rna_ensure_property(prop)->flag;
728 int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
730 return rna_ensure_property_array_length(ptr, prop);
733 int RNA_property_array_check(PointerRNA *ptr, PropertyRNA *prop)
735 return rna_ensure_property_array_check(ptr, prop);
738 /* used by BPY to make an array from the python object */
739 int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[])
741 PropertyRNA *rprop= rna_ensure_property(prop);
744 rna_ensure_property_multi_array_length(ptr, prop, length);
746 return rprop->arraydimension;
749 /* Return the size of Nth dimension. */
750 int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dim)
752 int len[RNA_MAX_ARRAY_DIMENSION];
754 rna_ensure_property_multi_array_length(ptr, prop, len);
759 char RNA_property_array_item_char(PropertyRNA *prop, int index)
761 const char *vectoritem= "XYZW";
762 const char *quatitem= "WXYZ";
763 const char *coloritem= "RGBA";
764 PropertySubType subtype= rna_ensure_property(prop)->subtype;
766 /* get string to use for array index */
767 if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE))
768 return quatitem[index];
769 else if((index < 4) && ELEM7(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_XYZ_LENGTH, PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION))
770 return vectoritem[index];
771 else if ((index < 4) && ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA))
772 return coloritem[index];
777 int RNA_property_array_item_index(PropertyRNA *prop, char name)
779 PropertySubType subtype= rna_ensure_property(prop)->subtype;
783 /* get index based on string name/alias */
784 /* maybe a function to find char index in string would be better than all the switches */
785 if (ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
797 else if(ELEM6(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION)) {
809 else if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
826 void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
828 IntPropertyRNA *iprop= (IntPropertyRNA*)rna_ensure_property(prop);
830 if(prop->magic != RNA_MAGIC) {
831 /* attempt to get the local ID values */
832 IDProperty *idp_ui= rna_idproperty_ui(prop);
837 item= IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_INT);
838 *hardmin= item ? IDP_Int(item) : INT_MIN;
840 item= IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_INT);
841 *hardmax= item ? IDP_Int(item) : INT_MAX;
848 iprop->range(ptr, hardmin, hardmax);
851 *hardmin= iprop->hardmin;
852 *hardmax= iprop->hardmax;
856 void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
858 IntPropertyRNA *iprop= (IntPropertyRNA*)rna_ensure_property(prop);
859 int hardmin, hardmax;
861 if(prop->magic != RNA_MAGIC) {
862 /* attempt to get the local ID values */
863 IDProperty *idp_ui= rna_idproperty_ui(prop);
868 item= IDP_GetPropertyTypeFromGroup(idp_ui, "soft_min", IDP_INT);
869 *softmin= item ? IDP_Int(item) : INT_MIN;
871 item= IDP_GetPropertyTypeFromGroup(idp_ui, "soft_max", IDP_INT);
872 *softmax= item ? IDP_Int(item) : INT_MAX;
874 item= IDP_GetPropertyTypeFromGroup(idp_ui, "step", IDP_INT);
875 *step= item ? IDP_Int(item) : 1;
882 iprop->range(ptr, &hardmin, &hardmax);
883 *softmin= MAX2(iprop->softmin, hardmin);
884 *softmax= MIN2(iprop->softmax, hardmax);
887 *softmin= iprop->softmin;
888 *softmax= iprop->softmax;
894 void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
896 FloatPropertyRNA *fprop= (FloatPropertyRNA*)rna_ensure_property(prop);
898 if(prop->magic != RNA_MAGIC) {
899 /* attempt to get the local ID values */
900 IDProperty *idp_ui= rna_idproperty_ui(prop);
905 item= IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_DOUBLE);
906 *hardmin= item ? IDP_Double(item) : FLT_MIN;
908 item= IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_DOUBLE);
909 *hardmax= item ? IDP_Double(item) : FLT_MAX;
916 fprop->range(ptr, hardmin, hardmax);
919 *hardmin= fprop->hardmin;
920 *hardmax= fprop->hardmax;
924 void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision)
926 FloatPropertyRNA *fprop= (FloatPropertyRNA*)rna_ensure_property(prop);
927 float hardmin, hardmax;
929 if(prop->magic != RNA_MAGIC) {
930 /* attempt to get the local ID values */
931 IDProperty *idp_ui= rna_idproperty_ui(prop);
936 item= IDP_GetPropertyTypeFromGroup(idp_ui, "soft_min", IDP_DOUBLE);
937 *softmin= item ? IDP_Double(item) : FLT_MIN;
939 item= IDP_GetPropertyTypeFromGroup(idp_ui, "soft_max", IDP_DOUBLE);
940 *softmax= item ? IDP_Double(item) : FLT_MAX;
942 item= IDP_GetPropertyTypeFromGroup(idp_ui, "step", IDP_DOUBLE);
943 *step= item ? IDP_Double(item) : 1.0f;
945 item= IDP_GetPropertyTypeFromGroup(idp_ui, "precision", IDP_DOUBLE);
946 *precision= item ? IDP_Double(item) : 3.0f;
953 fprop->range(ptr, &hardmin, &hardmax);
954 *softmin= MAX2(fprop->softmin, hardmin);
955 *softmax= MIN2(fprop->softmax, hardmax);
958 *softmin= fprop->softmin;
959 *softmax= fprop->softmax;
963 *precision= (float)fprop->precision;
966 int RNA_property_float_clamp(PointerRNA *ptr, PropertyRNA *prop, float *value)
970 RNA_property_float_range(ptr, prop, &min, &max);
976 else if(*value > max) {
985 int RNA_property_int_clamp(PointerRNA *ptr, PropertyRNA *prop, int *value)
989 RNA_property_int_range(ptr, prop, &min, &max);
995 else if(*value > max) {
1004 /* this is the max length including \0 terminator.
1005 * '0' used when their is no maximum */
1006 int RNA_property_string_maxlength(PropertyRNA *prop)
1008 StringPropertyRNA *sprop= (StringPropertyRNA*)rna_ensure_property(prop);
1009 return sprop->maxlength;
1012 StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
1014 prop= rna_ensure_property(prop);
1016 if(prop->type == PROP_POINTER) {
1017 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
1020 return pprop->typef(ptr);
1021 else if(pprop->type)
1024 else if(prop->type == PROP_COLLECTION) {
1025 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1027 if(cprop->item_type)
1028 return cprop->item_type;
1031 return &RNA_UnknownType;
1034 int RNA_property_pointer_poll(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *value)
1036 prop= rna_ensure_property(prop);
1038 if(prop->type == PROP_POINTER) {
1039 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
1041 return pprop->poll(ptr, *value);
1046 printf("RNA_property_pointer_poll %s: is not a pointer property.\n", prop->identifier);
1050 /* Reuse for dynamic types */
1051 EnumPropertyItem DummyRNA_NULL_items[] = {
1052 {0, NULL, 0, NULL, NULL}
1055 /* Reuse for dynamic types with default value */
1056 EnumPropertyItem DummyRNA_DEFAULT_items[] = {
1057 {0, "DEFAULT", 0, "Default", ""},
1058 {0, NULL, 0, NULL, NULL}
1061 void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item, int *totitem, int *free)
1063 EnumPropertyRNA *eprop= (EnumPropertyRNA*)rna_ensure_property(prop);
1067 if(eprop->itemf && (C != NULL || (prop->flag & PROP_ENUM_NO_CONTEXT))) {
1070 if (prop->flag & PROP_ENUM_NO_CONTEXT)
1071 *item= eprop->itemf(NULL, ptr, free);
1073 *item= eprop->itemf(C, ptr, free);
1077 for( ; (*item)[tot].identifier; tot++);
1086 *totitem= eprop->totitem;
1090 int RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value)
1092 EnumPropertyItem *item, *item_array;
1095 RNA_property_enum_items(C, ptr, prop, &item_array, NULL, &free);
1097 for(item= item_array; item->identifier; item++) {
1098 if(item->identifier[0] && strcmp(item->identifier, identifier)==0) {
1099 *value = item->value;
1104 found= (item->identifier != NULL); /* could be alloc'd, assign before free */
1107 MEM_freeN(item_array);
1112 int RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier)
1114 for (; item->identifier; item++) {
1115 if(item->identifier[0] && item->value==value) {
1116 *identifier = item->identifier;
1123 int RNA_enum_bitflag_identifiers(EnumPropertyItem *item, const int value, const char **identifier)
1126 for (; item->identifier; item++) {
1127 if(item->identifier[0] && item->value & value) {
1128 identifier[index++] = item->identifier;
1131 identifier[index]= NULL;
1135 int RNA_enum_name(EnumPropertyItem *item, const int value, const char **name)
1137 for (; item->identifier; item++) {
1138 if(item->identifier[0] && item->value==value) {
1146 int RNA_enum_description(EnumPropertyItem *item, const int value, const char **description)
1148 for (; item->identifier; item++) {
1149 if(item->identifier[0] && item->value==value) {
1150 *description = item->description;
1157 int RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
1159 EnumPropertyItem *item= NULL;
1162 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1164 result= RNA_enum_identifier(item, value, identifier);
1173 int RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
1175 EnumPropertyItem *item= NULL;
1178 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1180 result= RNA_enum_name(item, value, name);
1189 int RNA_property_enum_bitflag_identifiers(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
1191 EnumPropertyItem *item= NULL;
1194 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1196 result= RNA_enum_bitflag_identifiers(item, value, identifier);
1205 const char *RNA_property_ui_name(PropertyRNA *prop)
1207 return rna_ensure_property_name(prop);
1210 const char *RNA_property_ui_description(PropertyRNA *prop)
1212 return rna_ensure_property_description(prop);
1215 int RNA_property_ui_icon(PropertyRNA *prop)
1217 return rna_ensure_property(prop)->icon;
1220 int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
1222 ID *id= ptr->id.data;
1225 prop= rna_ensure_property(prop);
1226 flag= prop->editable ? prop->editable(ptr) : prop->flag;
1227 return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
1230 int RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop)
1234 prop= rna_ensure_property(prop);
1235 flag= prop->editable ? prop->editable(ptr) : prop->flag;
1236 return (flag & PROP_EDITABLE);
1239 /* same as RNA_property_editable(), except this checks individual items in an array */
1240 int RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1245 prop= rna_ensure_property(prop);
1250 flag &= prop->editable(ptr);
1252 if (prop->itemeditable)
1253 flag &= prop->itemeditable(ptr, index);
1257 return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
1260 int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
1262 /* check that base ID-block can support animation data */
1263 if (!id_type_can_have_animdata(ptr->id.data))
1266 prop= rna_ensure_property(prop);
1268 if(!(prop->flag & PROP_ANIMATABLE))
1271 return (prop->flag & PROP_EDITABLE);
1274 int RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop)
1276 /* would need to ask animation system */
1282 /* this function is to check if its possible to create a valid path from the ID
1283 * its slow so dont call in a loop */
1284 int RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
1286 char *path= RNA_path_from_ID_to_property(ptr, prop);
1292 PropertyRNA *r_prop;
1294 RNA_id_pointer_create(ptr->id.data, &id_ptr);
1295 RNA_path_resolve(&id_ptr, path, &r_ptr, &r_prop);
1296 ret= (prop == r_prop);
1304 static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
1306 int is_rna = (prop->magic == RNA_MAGIC);
1307 prop= rna_ensure_property(prop);
1311 /* ideally no context would be needed for update, but there's some
1312 parts of the code that need it still, so we have this exception */
1313 if(prop->flag & PROP_CONTEXT_UPDATE) {
1314 if(C) ((ContextUpdateFunc)prop->update)(C, ptr);
1317 prop->update(bmain, scene, ptr);
1320 WM_main_add_notifier(prop->noteflag, ptr->id.data);
1323 /* WARNING! This is so property drivers update the display!
1324 * not especially nice */
1325 DAG_id_tag_update(ptr->id.data, OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME);
1326 WM_main_add_notifier(NC_WINDOW, NULL);
1331 /* must keep in sync with 'rna_property_update'
1332 * note, its possible this returns a false positive in the case of PROP_CONTEXT_UPDATE
1333 * but this isnt likely to be a performance problem. */
1334 int RNA_property_update_check(PropertyRNA *prop)
1336 return (prop->magic != RNA_MAGIC || prop->update || prop->noteflag);
1339 void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
1341 rna_property_update(C, CTX_data_main(C), CTX_data_scene(C), ptr, prop);
1344 void RNA_property_update_main(Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
1346 rna_property_update(NULL, bmain, scene, ptr, prop);
1351 int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
1353 BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1356 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1358 if((idprop=rna_idproperty_check(&prop, ptr)))
1359 return IDP_Int(idprop);
1361 return bprop->get(ptr);
1363 return bprop->defaultvalue;
1366 void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1368 BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1371 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1373 /* just incase other values are passed */
1376 if((idprop=rna_idproperty_check(&prop, ptr)))
1377 IDP_Int(idprop)= value;
1379 bprop->set(ptr, value);
1380 else if(prop->flag & PROP_EDITABLE) {
1381 IDPropertyTemplate val = {0};
1386 group= RNA_struct_idprops(ptr, 1);
1388 IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
1392 void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
1394 BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1397 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1399 if((idprop=rna_idproperty_check(&prop, ptr))) {
1400 if(prop->arraydimension == 0)
1401 values[0]= RNA_property_boolean_get(ptr, prop);
1403 memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
1405 else if(prop->arraydimension == 0)
1406 values[0]= RNA_property_boolean_get(ptr, prop);
1407 else if(bprop->getarray)
1408 bprop->getarray(ptr, values);
1409 else if(bprop->defaultarray)
1410 memcpy(values, bprop->defaultarray, sizeof(int)*prop->totarraylength);
1412 memset(values, 0, sizeof(int)*prop->totarraylength);
1415 int RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1417 int tmp[RNA_MAX_ARRAY_LENGTH];
1418 int len= rna_ensure_property_array_length(ptr, prop);
1420 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1422 if(len <= RNA_MAX_ARRAY_LENGTH) {
1423 RNA_property_boolean_get_array(ptr, prop, tmp);
1427 int *tmparray, value;
1429 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_index");
1430 RNA_property_boolean_get_array(ptr, prop, tmparray);
1431 value= tmparray[index];
1432 MEM_freeN(tmparray);
1438 void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
1440 BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1443 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1445 if((idprop=rna_idproperty_check(&prop, ptr))) {
1446 if(prop->arraydimension == 0)
1447 IDP_Int(idprop)= values[0];
1449 memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
1451 else if(prop->arraydimension == 0)
1452 RNA_property_boolean_set(ptr, prop, values[0]);
1453 else if(bprop->setarray)
1454 bprop->setarray(ptr, values);
1455 else if(prop->flag & PROP_EDITABLE) {
1456 IDPropertyTemplate val = {0};
1459 val.array.len= prop->totarraylength;
1460 val.array.type= IDP_INT;
1462 group= RNA_struct_idprops(ptr, 1);
1464 idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
1465 IDP_AddToGroup(group, idprop);
1466 memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
1471 void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
1473 int tmp[RNA_MAX_ARRAY_LENGTH];
1474 int len= rna_ensure_property_array_length(ptr, prop);
1476 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1478 if(len <= RNA_MAX_ARRAY_LENGTH) {
1479 RNA_property_boolean_get_array(ptr, prop, tmp);
1481 RNA_property_boolean_set_array(ptr, prop, tmp);
1486 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_index");
1487 RNA_property_boolean_get_array(ptr, prop, tmparray);
1488 tmparray[index]= value;
1489 RNA_property_boolean_set_array(ptr, prop, tmparray);
1490 MEM_freeN(tmparray);
1494 int RNA_property_boolean_get_default(PointerRNA *ptr, PropertyRNA *prop)
1496 BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1498 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1500 return bprop->defaultvalue;
1503 void RNA_property_boolean_get_default_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
1505 BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1507 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1509 if(prop->arraydimension == 0)
1510 values[0]= bprop->defaultvalue;
1511 else if(bprop->defaultarray)
1512 memcpy(values, bprop->defaultarray, sizeof(int)*prop->totarraylength);
1514 memset(values, 0, sizeof(int)*prop->totarraylength);
1517 int RNA_property_boolean_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1519 int tmp[RNA_MAX_ARRAY_LENGTH];
1520 int len= rna_ensure_property_array_length(ptr, prop);
1522 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1524 if(len <= RNA_MAX_ARRAY_LENGTH) {
1525 RNA_property_boolean_get_default_array(ptr, prop, tmp);
1529 int *tmparray, value;
1531 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_default_index");
1532 RNA_property_boolean_get_default_array(ptr, prop, tmparray);
1533 value= tmparray[index];
1534 MEM_freeN(tmparray);
1540 int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
1542 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1545 BLI_assert(RNA_property_type(prop) == PROP_INT);
1547 if((idprop=rna_idproperty_check(&prop, ptr)))
1548 return IDP_Int(idprop);
1550 return iprop->get(ptr);
1552 return iprop->defaultvalue;
1555 void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1557 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1560 BLI_assert(RNA_property_type(prop) == PROP_INT);
1562 if((idprop=rna_idproperty_check(&prop, ptr)))
1563 IDP_Int(idprop)= value;
1565 iprop->set(ptr, value);
1566 else if(prop->flag & PROP_EDITABLE) {
1567 IDPropertyTemplate val = {0};
1572 group= RNA_struct_idprops(ptr, 1);
1574 IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
1578 void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
1580 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1583 BLI_assert(RNA_property_type(prop) == PROP_INT);
1585 if((idprop=rna_idproperty_check(&prop, ptr))) {
1586 if(prop->arraydimension == 0)
1587 values[0]= RNA_property_int_get(ptr, prop);
1589 memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
1591 else if(prop->arraydimension == 0)
1592 values[0]= RNA_property_int_get(ptr, prop);
1593 else if(iprop->getarray)
1594 iprop->getarray(ptr, values);
1595 else if(iprop->defaultarray)
1596 memcpy(values, iprop->defaultarray, sizeof(int)*prop->totarraylength);
1598 memset(values, 0, sizeof(int)*prop->totarraylength);
1601 int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1603 int tmp[RNA_MAX_ARRAY_LENGTH];
1604 int len= rna_ensure_property_array_length(ptr, prop);
1606 BLI_assert(RNA_property_type(prop) == PROP_INT);
1608 if(len <= RNA_MAX_ARRAY_LENGTH) {
1609 RNA_property_int_get_array(ptr, prop, tmp);
1613 int *tmparray, value;
1615 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_index");
1616 RNA_property_int_get_array(ptr, prop, tmparray);
1617 value= tmparray[index];
1618 MEM_freeN(tmparray);
1624 void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
1626 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1629 BLI_assert(RNA_property_type(prop) == PROP_INT);
1631 if((idprop=rna_idproperty_check(&prop, ptr))) {
1632 if(prop->arraydimension == 0)
1633 IDP_Int(idprop)= values[0];
1635 memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);\
1637 else if(prop->arraydimension == 0)
1638 RNA_property_int_set(ptr, prop, values[0]);
1639 else if(iprop->setarray)
1640 iprop->setarray(ptr, values);
1641 else if(prop->flag & PROP_EDITABLE) {
1642 IDPropertyTemplate val = {0};
1645 val.array.len= prop->totarraylength;
1646 val.array.type= IDP_INT;
1648 group= RNA_struct_idprops(ptr, 1);
1650 idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
1651 IDP_AddToGroup(group, idprop);
1652 memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
1657 void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
1659 int tmp[RNA_MAX_ARRAY_LENGTH];
1660 int len= rna_ensure_property_array_length(ptr, prop);
1662 BLI_assert(RNA_property_type(prop) == PROP_INT);
1664 if(len <= RNA_MAX_ARRAY_LENGTH) {
1665 RNA_property_int_get_array(ptr, prop, tmp);
1667 RNA_property_int_set_array(ptr, prop, tmp);
1672 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_index");
1673 RNA_property_int_get_array(ptr, prop, tmparray);
1674 tmparray[index]= value;
1675 RNA_property_int_set_array(ptr, prop, tmparray);
1676 MEM_freeN(tmparray);
1680 int RNA_property_int_get_default(PointerRNA *ptr, PropertyRNA *prop)
1682 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1683 return iprop->defaultvalue;
1686 void RNA_property_int_get_default_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
1688 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1690 BLI_assert(RNA_property_type(prop) == PROP_INT);
1692 if(prop->arraydimension == 0)
1693 values[0]= iprop->defaultvalue;
1694 else if(iprop->defaultarray)
1695 memcpy(values, iprop->defaultarray, sizeof(int)*prop->totarraylength);
1697 memset(values, 0, sizeof(int)*prop->totarraylength);
1700 int RNA_property_int_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1702 int tmp[RNA_MAX_ARRAY_LENGTH];
1703 int len= rna_ensure_property_array_length(ptr, prop);
1705 if(len <= RNA_MAX_ARRAY_LENGTH) {
1706 RNA_property_int_get_default_array(ptr, prop, tmp);
1710 int *tmparray, value;
1712 tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_default_index");
1713 RNA_property_int_get_default_array(ptr, prop, tmparray);
1714 value= tmparray[index];
1715 MEM_freeN(tmparray);
1721 float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
1723 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1726 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
1728 if((idprop=rna_idproperty_check(&prop, ptr))) {
1729 if(idprop->type == IDP_FLOAT)
1730 return IDP_Float(idprop);
1732 return (float)IDP_Double(idprop);
1735 return fprop->get(ptr);
1737 return fprop->defaultvalue;
1740 void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
1742 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1745 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
1747 if((idprop=rna_idproperty_check(&prop, ptr))) {
1748 if(idprop->type == IDP_FLOAT)
1749 IDP_Float(idprop)= value;
1751 IDP_Double(idprop)= value;
1753 else if(fprop->set) {
1754 fprop->set(ptr, value);
1756 else if(prop->flag & PROP_EDITABLE) {
1757 IDPropertyTemplate val = {0};
1762 group= RNA_struct_idprops(ptr, 1);
1764 IDP_AddToGroup(group, IDP_New(IDP_FLOAT, val, (char*)prop->identifier));
1768 void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
1770 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1774 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
1776 if((idprop=rna_idproperty_check(&prop, ptr))) {
1777 if(prop->arraydimension == 0)
1778 values[0]= RNA_property_float_get(ptr, prop);
1779 else if(idprop->subtype == IDP_FLOAT) {
1780 memcpy(values, IDP_Array(idprop), sizeof(float)*idprop->len);
1783 for(i=0; i<idprop->len; i++)
1784 values[i]= (float)(((double*)IDP_Array(idprop))[i]);
1787 else if(prop->arraydimension == 0)
1788 values[0]= RNA_property_float_get(ptr, prop);
1789 else if(fprop->getarray)
1790 fprop->getarray(ptr, values);
1791 else if(fprop->defaultarray)
1792 memcpy(values, fprop->defaultarray, sizeof(float)*prop->totarraylength);
1794 memset(values, 0, sizeof(float)*prop->totarraylength);
1797 float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1799 float tmp[RNA_MAX_ARRAY_LENGTH];
1800 int len= rna_ensure_property_array_length(ptr, prop);
1802 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
1804 if(len <= RNA_MAX_ARRAY_LENGTH) {
1805 RNA_property_float_get_array(ptr, prop, tmp);
1809 float *tmparray, value;
1811 tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_index");
1812 RNA_property_float_get_array(ptr, prop, tmparray);
1813 value= tmparray[index];
1814 MEM_freeN(tmparray);
1821 void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
1823 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1827 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
1829 if((idprop=rna_idproperty_check(&prop, ptr))) {
1830 if(prop->arraydimension == 0) {
1831 if(idprop->type == IDP_FLOAT)
1832 IDP_Float(idprop)= values[0];
1834 IDP_Double(idprop)= values[0];
1836 else if(idprop->subtype == IDP_FLOAT) {
1837 memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len);
1840 for(i=0; i<idprop->len; i++)
1841 ((double*)IDP_Array(idprop))[i]= values[i];
1844 else if(prop->arraydimension == 0)
1845 RNA_property_float_set(ptr, prop, values[0]);
1846 else if(fprop->setarray) {
1847 fprop->setarray(ptr, values);
1849 else if(prop->flag & PROP_EDITABLE) {
1850 IDPropertyTemplate val = {0};
1853 val.array.len= prop->totarraylength;
1854 val.array.type= IDP_FLOAT;
1856 group= RNA_struct_idprops(ptr, 1);
1858 idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
1859 IDP_AddToGroup(group, idprop);
1860 memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len);
1865 void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
1867 float tmp[RNA_MAX_ARRAY_LENGTH];
1868 int len= rna_ensure_property_array_length(ptr, prop);
1870 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
1872 if(len <= RNA_MAX_ARRAY_LENGTH) {
1873 RNA_property_float_get_array(ptr, prop, tmp);
1875 RNA_property_float_set_array(ptr, prop, tmp);
1880 tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_index");
1881 RNA_property_float_get_array(ptr, prop, tmparray);
1882 tmparray[index]= value;
1883 RNA_property_float_set_array(ptr, prop, tmparray);
1884 MEM_freeN(tmparray);
1888 float RNA_property_float_get_default(PointerRNA *ptr, PropertyRNA *prop)
1890 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1892 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
1894 return fprop->defaultvalue;
1897 void RNA_property_float_get_default_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
1899 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1901 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
1903 if(prop->arraydimension == 0)
1904 values[0]= fprop->defaultvalue;
1905 else if(fprop->defaultarray)
1906 memcpy(values, fprop->defaultarray, sizeof(float)*prop->totarraylength);
1908 memset(values, 0, sizeof(float)*prop->totarraylength);
1911 float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1913 float tmp[RNA_MAX_ARRAY_LENGTH];
1914 int len= rna_ensure_property_array_length(ptr, prop);
1916 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
1918 if(len <= RNA_MAX_ARRAY_LENGTH) {
1919 RNA_property_float_get_default_array(ptr, prop, tmp);
1923 float *tmparray, value;
1925 tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_default_index");
1926 RNA_property_float_get_default_array(ptr, prop, tmparray);
1927 value= tmparray[index];
1928 MEM_freeN(tmparray);
1934 void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
1936 StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1939 BLI_assert(RNA_property_type(prop) == PROP_STRING);
1941 if((idprop=rna_idproperty_check(&prop, ptr)))
1942 strcpy(value, IDP_String(idprop));
1944 sprop->get(ptr, value);
1946 strcpy(value, sprop->defaultvalue);
1949 char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen)
1954 BLI_assert(RNA_property_type(prop) == PROP_STRING);
1956 length= RNA_property_string_length(ptr, prop);
1958 if(length+1 < fixedlen)
1961 buf= MEM_callocN(sizeof(char)*(length+1), "RNA_string_get_alloc");
1963 RNA_property_string_get(ptr, prop, buf);
1968 /* this is the length without \0 terminator */
1969 int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
1971 StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1974 BLI_assert(RNA_property_type(prop) == PROP_STRING);
1976 if((idprop=rna_idproperty_check(&prop, ptr)))
1977 return strlen(IDP_String(idprop));
1978 else if(sprop->length)
1979 return sprop->length(ptr);
1981 return strlen(sprop->defaultvalue);
1984 void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
1986 StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1989 BLI_assert(RNA_property_type(prop) == PROP_STRING);
1991 if((idprop=rna_idproperty_check(&prop, ptr)))
1992 IDP_AssignString(idprop, (char*)value, RNA_property_string_maxlength(prop) - 1);
1994 sprop->set(ptr, value); /* set function needs to clamp its self */
1995 else if(prop->flag & PROP_EDITABLE) {
1998 group= RNA_struct_idprops(ptr, 1);
2000 IDP_AddToGroup(group, IDP_NewString((char*)value, (char*)prop->identifier, RNA_property_string_maxlength(prop) - 1));
2004 void RNA_property_string_get_default(PointerRNA *ptr, PropertyRNA *prop, char *value)
2006 StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
2008 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2010 strcpy(value, sprop->defaultvalue);
2013 char *RNA_property_string_get_default_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen)
2018 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2020 length= RNA_property_string_default_length(ptr, prop);
2022 if(length+1 < fixedlen)
2025 buf= MEM_callocN(sizeof(char)*(length+1), "RNA_string_get_alloc");
2027 RNA_property_string_get_default(ptr, prop, buf);
2032 /* this is the length without \0 terminator */
2033 int RNA_property_string_default_length(PointerRNA *ptr, PropertyRNA *prop)
2035 StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
2037 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2039 return strlen(sprop->defaultvalue);
2042 int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
2044 EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
2047 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2049 if((idprop=rna_idproperty_check(&prop, ptr)))
2050 return IDP_Int(idprop);
2052 return eprop->get(ptr);
2054 return eprop->defaultvalue;
2057 void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
2059 EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
2062 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2064 if((idprop=rna_idproperty_check(&prop, ptr)))
2065 IDP_Int(idprop)= value;
2066 else if(eprop->set) {
2067 eprop->set(ptr, value);
2069 else if(prop->flag & PROP_EDITABLE) {
2070 IDPropertyTemplate val = {0};
2075 group= RNA_struct_idprops(ptr, 1);
2077 IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
2081 int RNA_property_enum_get_default(PointerRNA *ptr, PropertyRNA *prop)
2083 EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
2085 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2087 return eprop->defaultvalue;
2091 PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
2093 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
2096 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2098 if((idprop=rna_idproperty_check(&prop, ptr))) {
2099 pprop= (PointerPropertyRNA*)prop;
2101 /* for groups, data is idprop itself */
2102 return rna_pointer_inherit_refine(ptr, pprop->type, idprop);
2104 else if(pprop->get) {
2105 return pprop->get(ptr);
2107 else if(prop->flag & PROP_IDPROPERTY) {
2108 /* XXX temporary hack to add it automatically, reading should
2109 never do any write ops, to ensure thread safety etc .. */
2110 RNA_property_pointer_add(ptr, prop);
2111 return RNA_property_pointer_get(ptr, prop);
2114 return PointerRNA_NULL;
2118 void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value)
2120 /*IDProperty *idprop;*/
2122 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2124 if((/*idprop=*/ rna_idproperty_check(&prop, ptr))) {
2128 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
2131 !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL) &&
2132 !((prop->flag & PROP_ID_SELF_CHECK) && ptr->id.data == ptr_value.id.data)
2134 pprop->set(ptr, ptr_value);
2139 PointerRNA RNA_property_pointer_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop))
2141 //PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
2143 // BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2145 return PointerRNA_NULL; // FIXME: there has to be a way...
2148 void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop)
2150 /*IDProperty *idprop;*/
2152 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2154 if((/*idprop=*/rna_idproperty_check(&prop, ptr))) {
2155 /* already exists */
2157 else if(prop->flag & PROP_IDPROPERTY) {
2158 IDPropertyTemplate val = {0};
2163 group= RNA_struct_idprops(ptr, 1);
2165 IDP_AddToGroup(group, IDP_New(IDP_GROUP, val, (char*)prop->identifier));
2168 printf("RNA_property_pointer_add %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);
2171 void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop)
2173 IDProperty *idprop, *group;
2175 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2177 if((idprop=rna_idproperty_check(&prop, ptr))) {
2178 group= RNA_struct_idprops(ptr, 0);
2181 IDP_RemFromGroup(group, idprop);
2182 IDP_FreeProperty(idprop);
2187 printf("RNA_property_pointer_remove %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);
2190 static void rna_property_collection_get_idp(CollectionPropertyIterator *iter)
2192 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
2194 iter->ptr.data= rna_iterator_array_get(iter);
2195 iter->ptr.type= cprop->item_type;
2196 rna_pointer_inherit_id(cprop->item_type, &iter->parent, &iter->ptr);
2199 void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter)
2203 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2205 memset(iter, 0, sizeof(*iter));
2207 if((idprop=rna_idproperty_check(&prop, ptr)) || (prop->flag & PROP_IDPROPERTY)) {
2212 rna_iterator_array_begin(iter, IDP_IDPArray(idprop), sizeof(IDProperty), idprop->len, 0, NULL);
2214 rna_iterator_array_begin(iter, NULL, sizeof(IDProperty), 0, 0, NULL);
2217 rna_property_collection_get_idp(iter);
2222 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
2223 cprop->begin(iter, ptr);
2227 void RNA_property_collection_next(CollectionPropertyIterator *iter)
2229 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(iter->prop);
2232 rna_iterator_array_next(iter);
2235 rna_property_collection_get_idp(iter);
2241 void RNA_property_collection_end(CollectionPropertyIterator *iter)
2243 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(iter->prop);
2246 rna_iterator_array_end(iter);
2251 int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
2253 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
2256 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2258 if((idprop=rna_idproperty_check(&prop, ptr))) {
2261 else if(cprop->length) {
2262 return cprop->length(ptr);
2265 CollectionPropertyIterator iter;
2268 RNA_property_collection_begin(ptr, prop, &iter);
2269 for(; iter.valid; RNA_property_collection_next(&iter))
2271 RNA_property_collection_end(&iter);
2277 void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
2280 // CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
2282 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2284 if((idprop=rna_idproperty_check(&prop, ptr))) {
2285 IDPropertyTemplate val = {0};
2288 item= IDP_New(IDP_GROUP, val, "");
2289 IDP_AppendArray(idprop, item);
2290 // IDP_FreeProperty(item); // IDP_AppendArray does a shallow copy (memcpy), only free memory
2293 else if(prop->flag & PROP_IDPROPERTY) {
2294 IDProperty *group, *item;
2295 IDPropertyTemplate val = {0};
2297 group= RNA_struct_idprops(ptr, 1);
2299 idprop= IDP_NewIDPArray(prop->identifier);
2300 IDP_AddToGroup(group, idprop);
2302 item= IDP_New(IDP_GROUP, val, "");
2303 IDP_AppendArray(idprop, item);
2304 // IDP_FreeProperty(item); // IDP_AppendArray does a shallow copy (memcpy), only free memory
2309 /* py api calls directly */
2311 else if(cprop->add){
2312 if(!(cprop->add->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
2313 ParameterList params;
2314 RNA_parameter_list_create(¶ms, ptr, cprop->add);
2315 RNA_function_call(NULL, NULL, ptr, cprop->add, ¶ms);
2316 RNA_parameter_list_free(¶ms);
2320 printf("RNA_property_collection_add %s.%s: not implemented for this property.\n", ptr->type->identifier, prop->identifier);*/
2325 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
2327 r_ptr->data= IDP_GetIndexArray(idprop, idprop->len-1);
2328 r_ptr->type= cprop->item_type;
2329 rna_pointer_inherit_id(NULL, ptr, r_ptr);
2332 memset(r_ptr, 0, sizeof(*r_ptr));
2336 int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
2339 // CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
2341 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2343 if((idprop=rna_idproperty_check(&prop, ptr))) {
2344 IDProperty tmp, *array;
2348 array= IDP_IDPArray(idprop);
2350 if(key >= 0 && key < len) {
2352 /* move element to be removed to the back */
2353 memcpy(&tmp, &array[key], sizeof(IDProperty));
2354 memmove(array+key, array+key+1, sizeof(IDProperty)*(len-(key+1)));
2355 memcpy(&array[len-1], &tmp, sizeof(IDProperty));
2358 IDP_ResizeIDPArray(idprop, len-1);
2363 else if(prop->flag & PROP_IDPROPERTY)
2366 /* py api calls directly */
2368 else if(cprop->remove){
2369 if(!(cprop->remove->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
2370 ParameterList params;
2371 RNA_parameter_list_create(¶ms, ptr, cprop->remove);
2372 RNA_function_call(NULL, NULL, ptr, cprop->remove, ¶ms);
2373 RNA_parameter_list_free(¶ms);
2379 printf("RNA_property_collection_remove %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);*/
2384 int RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos)
2388 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2390 if((idprop=rna_idproperty_check(&prop, ptr))) {
2391 IDProperty tmp, *array;
2395 array= IDP_IDPArray(idprop);
2397 if(key >= 0 && key < len && pos >= 0 && pos < len && key != pos) {
2398 memcpy(&tmp, &array[key], sizeof(IDProperty));
2400 memmove(array+pos+1, array+pos, sizeof(IDProperty)*(key - pos));
2402 memmove(array+key, array+key+1, sizeof(IDProperty)*(pos - key));
2403 memcpy(&array[pos], &tmp, sizeof(IDProperty));
2408 else if(prop->flag & PROP_IDPROPERTY)
2414 void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
2418 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2420 if((idprop=rna_idproperty_check(&prop, ptr)))
2421 IDP_ResizeIDPArray(idprop, 0);
2424 int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *t_ptr)
2426 CollectionPropertyIterator iter;
2429 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2431 RNA_property_collection_begin(ptr, prop, &iter);
2432 for(index=0; iter.valid; RNA_property_collection_next(&iter), index++) {
2433 if (iter.ptr.data == t_ptr->data)
2436 RNA_property_collection_end(&iter);
2438 /* did we find it? */
2445 int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
2447 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(prop);
2449 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2451 if(cprop->lookupint) {
2452 /* we have a callback defined, use it */
2453 return cprop->lookupint(ptr, key, r_ptr);
2456 /* no callback defined, just iterate and find the nth item */
2457 CollectionPropertyIterator iter;
2460 RNA_property_collection_begin(ptr, prop, &iter);
2461 for(i=0; iter.valid; RNA_property_collection_next(&iter), i++) {
2467 RNA_property_collection_end(&iter);
2470 memset(r_ptr, 0, sizeof(*r_ptr));
2476 int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr)
2478 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(prop);
2480 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2482 if(cprop->lookupstring) {
2483 /* we have a callback defined, use it */
2484 return cprop->lookupstring(ptr, key, r_ptr);
2487 /* no callback defined, compare with name properties if they exist */
2488 CollectionPropertyIterator iter;
2489 PropertyRNA *nameprop;
2490 char name[256], *nameptr;
2493 RNA_property_collection_begin(ptr, prop, &iter);
2494 for(; iter.valid; RNA_property_collection_next(&iter)) {
2495 if(iter.ptr.data && iter.ptr.type->nameproperty) {
2496 nameprop= iter.ptr.type->nameproperty;
2498 nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
2500 if(strcmp(nameptr, key) == 0) {
2505 if((char *)&name != nameptr)
2512 RNA_property_collection_end(&iter);
2515 memset(r_ptr, 0, sizeof(*r_ptr));
2521 int RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
2523 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2526 return ((r_ptr->type = prop->srna) ? 1:0);
2529 int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array)
2531 CollectionPropertyIterator iter;
2532 ArrayIterator *internal;
2535 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2537 if(!(prop->flag & PROP_RAW_ARRAY) || !(itemprop->flag & PROP_RAW_ACCESS))
2540 RNA_property_collection_begin(ptr, prop, &iter);
2543 /* get data from array iterator and item property */
2544 internal= iter.internal;
2545 arrayp= (iter.valid)? iter.ptr.data: NULL;
2547 if(internal->skip || !RNA_property_editable(&iter.ptr, itemprop)) {
2548 /* we might skip some items, so it's not a proper array */
2549 RNA_property_collection_end(&iter);
2553 array->array= arrayp + itemprop->rawoffset;
2554 array->stride= internal->itemsize;
2555 array->len= ((char*)internal->endptr - arrayp)/internal->itemsize;
2556 array->type= itemprop->rawtype;
2559 memset(array, 0, sizeof(RawArray));
2561 RNA_property_collection_end(&iter);
2566 #define RAW_GET(dtype, var, raw, a) \
2568 switch(raw.type) { \
2569 case PROP_RAW_CHAR: var = (dtype)((char*)raw.array)[a]; break; \
2570 case PROP_RAW_SHORT: var = (dtype)((short*)raw.array)[a]; break; \
2571 case PROP_RAW_INT: var = (dtype)((int*)raw.array)[a]; break; \
2572 case PROP_RAW_FLOAT: var = (dtype)((float*)raw.array)[a]; break; \
2573 case PROP_RAW_DOUBLE: var = (dtype)((double*)raw.array)[a]; break; \
2574 default: var = (dtype)0; \
2578 #define RAW_SET(dtype, raw, a, var) \
2580 switch(raw.type) { \
2581 case PROP_RAW_CHAR: ((char*)raw.array)[a] = (char)var; break; \
2582 case PROP_RAW_SHORT: ((short*)raw.array)[a] = (short)var; break; \
2583 case PROP_RAW_INT: ((int*)raw.array)[a] = (int)var; break; \
2584 case PROP_RAW_FLOAT: ((float*)raw.array)[a] = (float)var; break; \
2585 case PROP_RAW_DOUBLE: ((double*)raw.array)[a] = (double)var; break; \
2590 int RNA_raw_type_sizeof(RawPropertyType type)
2593 case PROP_RAW_CHAR: return sizeof(char);
2594 case PROP_RAW_SHORT: return sizeof(short);
2595 case PROP_RAW_INT: return sizeof(int);
2596 case PROP_RAW_FLOAT: return sizeof(float);
2597 case PROP_RAW_DOUBLE: return sizeof(double);
2602 static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname, void *inarray, RawPropertyType intype, int inlen, int set)
2606 PropertyRNA *itemprop, *iprop;
2607 PropertyType itemtype=0;
2611 /* initialize in array, stride assumed 0 in following code */
2617 ptype= RNA_property_pointer_type(ptr, prop);
2619 /* try to get item property pointer */
2620 RNA_pointer_create(NULL, ptype, NULL, &itemptr);
2621 itemprop= RNA_struct_find_property(&itemptr, propname);
2624 /* we have item property pointer */
2628 itemtype= RNA_property_type(itemprop);
2630 if(!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
2631 BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported.");
2635 /* check item array */
2636 itemlen= RNA_property_array_length(&itemptr, itemprop);
2638 /* try to access as raw array */
2639 if(RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
2640 int arraylen = (itemlen == 0) ? 1 : itemlen;
2641 if(in.len != arraylen*out.len) {
2642 BKE_reportf(reports, RPT_ERROR, "Array length mismatch (expected %d, got %d).", out.len*arraylen, in.len);
2646 /* matching raw types */
2647 if(out.type == in.type) {
2648 void *inp= in.array;
2649 void *outp= out.array;
2652 size= RNA_raw_type_sizeof(out.type) * arraylen;
2654 for(a=0; a<out.len; a++) {
2655 if(set) memcpy(outp, inp, size);
2656 else memcpy(inp, outp, size);
2658 inp= (char*)inp + size;
2659 outp= (char*)outp + out.stride;
2665 /* could also be faster with non-matching types,
2666 * for now we just do slower loop .. */
2671 void *tmparray= NULL;
2673 int err= 0, j, a= 0;
2676 if (((itemtype == PROP_BOOLEAN || itemtype == PROP_INT) && in.type == PROP_RAW_INT) ||
2677 (itemtype == PROP_FLOAT && in.type == PROP_RAW_FLOAT))
2678 /* avoid creating temporary buffer if the data type match */
2681 /* no item property pointer, can still be id property, or
2682 * property of a type derived from the collection pointer type */
2683 RNA_PROP_BEGIN(ptr, itemptr, prop) {
2686 /* we got the property already */
2690 /* not yet, look it up and verify if it is valid */
2691 iprop= RNA_struct_find_property(&itemptr, propname);
2694 itemlen= RNA_property_array_length(&itemptr, iprop);
2695 itemtype= RNA_property_type(iprop);
2698 BKE_reportf(reports, RPT_ERROR, "Property named %s not found.", propname);
2703 if(!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
2704 BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported.");
2710 /* editable check */
2711 if(RNA_property_editable(&itemptr, iprop)) {
2712 if(a+itemlen > in.len) {
2713 BKE_reportf(reports, RPT_ERROR, "Array length mismatch (got %d, expected more).", in.len);
2719 /* handle conversions */
2722 case PROP_BOOLEAN: {
2724 RAW_GET(int, b, in, a);
2725 RNA_property_boolean_set(&itemptr, iprop, b);
2730 RAW_GET(int, i, in, a);
2731 RNA_property_int_set(&itemptr, iprop, i);
2736 RAW_GET(float, f, in, a);
2737 RNA_property_float_set(&itemptr, iprop, f);
2746 case PROP_BOOLEAN: {
2747 int b= RNA_property_boolean_get(&itemptr, iprop);
2748 RAW_SET(int, in, a, b);
2752 int i= RNA_property_int_get(&itemptr, iprop);
2753 RAW_SET(int, in, a, i);
2757 float f= RNA_property_float_get(&itemptr, iprop);
2758 RAW_SET(float, in, a, f);
2767 else if (needconv == 1) {
2768 /* allocate temporary array if needed */
2769 if(tmparray && tmplen != itemlen) {
2770 MEM_freeN(tmparray);
2774 tmparray= MEM_callocN(sizeof(float)*itemlen, "RNA tmparray\n");
2778 /* handle conversions */
2781 case PROP_BOOLEAN: {
2782 for(j=0; j<itemlen; j++, a++)
2783 RAW_GET(int, ((int*)tmparray)[j], in, a);
2784 RNA_property_boolean_set_array(&itemptr, iprop, tmparray);
2788 for(j=0; j<itemlen; j++, a++)
2789 RAW_GET(int, ((int*)tmparray)[j], in, a);
2790 RNA_property_int_set_array(&itemptr, iprop, tmparray);
2794 for(j=0; j<itemlen; j++, a++)
2795 RAW_GET(float, ((float*)tmparray)[j], in, a);
2796 RNA_property_float_set_array(&itemptr, iprop, tmparray);
2805 case PROP_BOOLEAN: {
2806 RNA_property_boolean_get_array(&itemptr, iprop, tmparray);
2807 for(j=0; j<itemlen; j++, a++)
2808 RAW_SET(int, in, a, ((int*)tmparray)[j]);
2812 RNA_property_int_get_array(&itemptr, iprop, tmparray);
2813 for(j=0; j<itemlen; j++, a++)
2814 RAW_SET(int, in, a, ((int*)tmparray)[j]);
2818 RNA_property_float_get_array(&itemptr, iprop, tmparray);
2819 for(j=0; j<itemlen; j++, a++)
2820 RAW_SET(float, in, a, ((float*)tmparray)[j]);
2831 case PROP_BOOLEAN: {
2832 RNA_property_boolean_set_array(&itemptr, iprop, &((int*)in.array)[a]);
2837 RNA_property_int_set_array(&itemptr, iprop, &((int*)in.array)[a]);
2842 RNA_property_float_set_array(&itemptr, iprop, &((float*)in.array)[a]);
2852 case PROP_BOOLEAN: {
2853 RNA_property_boolean_get_array(&itemptr, iprop, &((int*)in.array)[a]);
2858 RNA_property_int_get_array(&itemptr, iprop, &((int*)in.array)[a]);
2863 RNA_property_float_get_array(&itemptr, iprop, &((float*)in.array)[a]);
2878 MEM_freeN(tmparray);
2884 RawPropertyType RNA_property_raw_type(PropertyRNA *prop)
2886 if (prop->rawtype == PROP_RAW_UNSET) {
2887 /* this property has no raw access, yet we try to provide a raw type to help building the array */
2888 switch (prop->type) {
2890 return PROP_RAW_INT;
2892 return PROP_RAW_INT;
2894 return PROP_RAW_FLOAT;
2896 return PROP_RAW_INT;
2901 return prop->rawtype;
2904 int RNA_property_collection_raw_get(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname, void *array, RawPropertyType type, int len)
2906 return rna_raw_access(reports, ptr, prop, propname, array, type, len, 0);
2909 int RNA_property_collection_raw_set(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname, void *array, RawPropertyType type, int len)
2911 return rna_raw_access(reports, ptr, prop, propname, array, type, len, 1);
2914 /* Standard iterator functions */
2916 void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip)
2918 ListBaseIterator *internal;
2920 internal= MEM_callocN(sizeof(ListBaseIterator), "ListBaseIterator");
2921 internal->link= (lb)? lb->first: NULL;
2922 internal->skip= skip;
2924 iter->internal= internal;
2925 iter->valid= (internal->link != NULL);
2927 if(skip && iter->valid && skip(iter, internal->link))
2928 rna_iterator_listbase_next(iter);
2931 void rna_iterator_listbase_next(CollectionPropertyIterator *iter)
2933 ListBaseIterator *internal= iter->internal;
2935 if(internal->skip) {
2937 internal->link= internal->link->next;
2938 iter->valid= (internal->link != NULL);
2939 } while(iter->valid && internal->skip(iter, internal->link));
2942 internal->link= internal->link->next;
2943 iter->valid= (internal->link != NULL);
2947 void *rna_iterator_listbase_get(CollectionPropertyIterator *iter)
2949 ListBaseIterator *internal= iter->internal;
2951 return internal->link;
2954 void rna_iterator_listbase_end(CollectionPropertyIterator *iter)
2956 MEM_freeN(iter->internal);
2957 iter->internal= NULL;
2960 PointerRNA rna_listbase_lookup_int(PointerRNA *ptr, StructRNA *type, struct ListBase *lb, int index)
2962 void *data= BLI_findlink(lb, index);
2963 return rna_pointer_inherit_refine(ptr, type, data);
2966 void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int itemsize, int length, int free_ptr, IteratorSkipFunc skip)
2968 ArrayIterator *internal;
2972 else if (length == 0) {
2977 internal= MEM_callocN(sizeof(ArrayIterator), "ArrayIterator");
2979 internal->free_ptr= free_ptr ? ptr:NULL;
2980 internal->endptr= ((char*)ptr)+length*itemsize;
2981 internal->itemsize= itemsize;
2982 internal->skip= skip;
2983 internal->length= length;
2985 iter->internal= internal;
2986 iter->valid= (internal->ptr != internal->endptr);
2988 if(skip && iter->valid && skip(iter, internal->ptr))
2989 rna_iterator_array_next(iter);
2992 void rna_iterator_array_next(CollectionPropertyIterator *iter)
2994 ArrayIterator *internal= iter->internal;
2996 if(internal->skip) {
2998 internal->ptr += internal->itemsize;
2999 iter->valid= (internal->ptr != internal->endptr);
3000 } while(iter->valid && internal->skip(iter, internal->ptr));
3003 internal->ptr += internal->itemsize;
3004 iter->valid= (internal->ptr != internal->endptr);
3008 void *rna_iterator_array_get(CollectionPropertyIterator *iter)
3010 ArrayIterator *internal= iter->internal;
3012 return internal->ptr;
3015 void *rna_iterator_array_dereference_get(CollectionPropertyIterator *iter)
3017 ArrayIterator *internal= iter->internal;
3020 return *(void**)(internal->ptr);
3023 void rna_iterator_array_end(CollectionPropertyIterator *iter)
3025 ArrayIterator *internal= iter->internal;
3027 if(internal->free_ptr) {
3028 MEM_freeN(internal->free_ptr);
3029 internal->free_ptr= NULL;
3031 MEM_freeN(iter->internal);
3032 iter->internal= NULL;
3035 PointerRNA rna_array_lookup_int(PointerRNA *ptr, StructRNA *type, void *data, int itemsize, int length, int index)
3037 if(index < 0 || index >= length)
3038 return PointerRNA_NULL;
3040 return rna_pointer_inherit_refine(ptr, type, ((char*)data) + index*itemsize);
3043 /* RNA Path - Experiment */
3045 static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int bracket)
3050 int i, j, len, escape;
3055 /* get data between [], check escaping ] with \] */
3056 if(**path == '[') (*path)++;
3061 /* 2 kinds of lookups now, quoted or unquoted */
3068 while(*p && (*p != ']')) {
3075 /* skip the first quote */
3078 while(*p && (*p != quote || escape)) {
3079 escape= (*p == '\\');
3084 /* skip the last quoted char to get the ']' */
3089 if(*p != ']') return NULL;
3092 /* get data until . or [ */
3095 while(*p && *p != '.' && *p != '[') {
3105 /* try to use fixed buffer if possible */
3106 if(len+1 < fixedlen)
3109 buf= MEM_callocN(sizeof(char)*(len+1), "rna_path_token");
3111 /* copy string, taking into account escaped ] */
3113 for(p=*path, i=0, j=0; i<len; i++, p++) {
3114 if(*p == '\\' && *(p+1) == quote);
3121 memcpy(buf, *path, sizeof(char)*len);
3125 /* set path to start of next token */
3133 static int rna_token_strip_quotes(char *token)
3136 int len = strlen(token);
3137 if (len >= 2 && token[len-1]=='"') {
3146 /* Resolve the given RNA path to find the pointer+property indicated at the end of the path */
3147 int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
3149 return RNA_path_resolve_full(ptr, path, r_ptr, r_prop, NULL);
3152 int RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *index)
3155 PointerRNA curptr, nextptr;
3156 char fixedbuf[256], *token;
3162 if(path==NULL || *path=='\0')
3166 int use_id_prop = (*path=='[') ? 1:0;
3167 /* custom property lookup ?
3168 * C.object["someprop"]
3171 /* look up property name in current struct */
3172 token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), use_id_prop);
3177 if(use_id_prop) { /* look up property name in current struct */
3178 IDProperty *group= RNA_struct_idprops(&curptr, 0);
3179 if(group && rna_token_strip_quotes(token))
3180 prop= (PropertyRNA *)IDP_GetPropertyFromGroup(group, token+1);
3183 prop= RNA_struct_find_property(&curptr, token);
3186 if(token != fixedbuf)
3192 type= RNA_property_type(prop);
3194 /* now look up the value of this property if it is a pointer or
3195 * collection, otherwise return the property rna so that the
3196 * caller can read the value of the property itself */
3199 nextptr= RNA_property_pointer_get(&curptr, prop);
3203 prop= NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
3204 if(index) *index= -1;
3210 case PROP_COLLECTION:
3213 /* resolve the lookup with [] brackets */
3214 token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1);
3219 /* check for "" to see if it is a string */
3220 if(rna_token_strip_quotes(token)) {
3221 RNA_property_collection_lookup_string(&curptr, prop, token+1, &nextptr);
3224 /* otherwise do int lookup */
3225 intkey= atoi(token);
3226 if(intkey==0 && (token[0] != '0' || token[1] != '\0')) {
3227 return 0; /* we can be sure the fixedbuf was used in this case */
3229 RNA_property_collection_lookup_int(&curptr, prop, intkey, &nextptr);
3232 if(token != fixedbuf) {