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_idcode.h"
50 #include "BKE_idprop.h"
52 #include "BKE_report.h"
57 #include "RNA_access.h"
58 #include "RNA_define.h"
61 #include "DNA_object_types.h"
62 #include "BKE_depsgraph.h"
65 #include "rna_internal.h"
67 const PointerRNA PointerRNA_NULL = {{NULL}};
76 for (srna = BLENDER_RNA.structs.first; srna; srna = srna->cont.next) {
77 if (!srna->cont.prophash) {
78 srna->cont.prophash = BLI_ghash_str_new("RNA_init gh");
80 for (prop = srna->cont.properties.first; prop; prop = prop->next)
81 if (!(prop->flag & PROP_BUILTIN))
82 BLI_ghash_insert(srna->cont.prophash, (void *)prop->identifier, prop);
91 RNA_property_update_cache_free();
93 for (srna = BLENDER_RNA.structs.first; srna; srna = srna->cont.next) {
94 if (srna->cont.prophash) {
95 BLI_ghash_free(srna->cont.prophash, NULL, NULL);
96 srna->cont.prophash = NULL;
100 RNA_free(&BLENDER_RNA);
105 void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr)
107 r_ptr->id.data = NULL;
108 r_ptr->type = &RNA_BlendData;
112 void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
114 StructRNA *type, *idtype = NULL;
117 PointerRNA tmp = {{NULL}};
119 idtype = rna_ID_refine(&tmp);
121 while (idtype->refine) {
122 type = idtype->refine(&tmp);
132 r_ptr->type = idtype;
136 void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
139 StructRNA *idtype = NULL;
142 PointerRNA tmp = {{0}};
144 idtype = rna_ID_refine(&tmp);
153 while (r_ptr->type && r_ptr->type->refine) {
154 StructRNA *rtype = r_ptr->type->refine(r_ptr);
156 if (rtype == r_ptr->type)
164 static void rna_pointer_inherit_id(StructRNA *type, PointerRNA *parent, PointerRNA *ptr)
166 if (type && type->flag & STRUCT_ID) {
167 ptr->id.data = ptr->data;
170 ptr->id.data = parent->id.data;
174 void RNA_blender_rna_pointer_create(PointerRNA *r_ptr)
176 r_ptr->id.data = NULL;
177 r_ptr->type = &RNA_BlenderRNA;
178 r_ptr->data = &BLENDER_RNA;
181 PointerRNA rna_pointer_inherit_refine(PointerRNA *ptr, StructRNA *type, void *data)
187 rna_pointer_inherit_id(type, ptr, &result);
189 while (result.type->refine) {
190 type = result.type->refine(&result);
192 if (type == result.type)
200 return PointerRNA_NULL;
205 void RNA_pointer_recast(PointerRNA *ptr, PointerRNA *r_ptr)
207 #if 0 /* works but this case if covered by more general code below. */
208 if (RNA_struct_is_ID(ptr->type)) {
210 RNA_id_pointer_create(ptr->id.data, r_ptr);
217 *r_ptr = *ptr; /* initialize as the same in case cant recast */
219 for (base = ptr->type->base; base; base = base->base) {
220 t_ptr = rna_pointer_inherit_refine(ptr, base, ptr->data);
221 if (t_ptr.type && t_ptr.type != ptr->type) {
230 static void rna_idproperty_touch(IDProperty *idprop)
232 /* so the property is seen as 'set' by rna */
233 idprop->flag &= ~IDP_FLAG_GHOST;
236 /* return a UI local ID prop definition for this prop */
237 static IDProperty *rna_idproperty_ui(PropertyRNA *prop)
241 for (idprop = ((IDProperty *)prop)->prev; idprop; idprop = idprop->prev) {
242 if (strcmp(RNA_IDP_UI, idprop->name) == 0)
246 if (idprop == NULL) {
247 for (idprop = ((IDProperty *)prop)->next; idprop; idprop = idprop->next) {
248 if (strcmp(RNA_IDP_UI, idprop->name) == 0)
254 return IDP_GetPropertyTypeFromGroup(idprop, ((IDProperty *)prop)->name, IDP_GROUP);
260 IDProperty *RNA_struct_idprops(PointerRNA *ptr, int create)
262 StructRNA *type = ptr->type;
264 if (type && type->idproperties)
265 return type->idproperties(ptr, create);
270 int RNA_struct_idprops_check(StructRNA *srna)
272 return (srna && srna->idproperties) ? 1 : 0;
275 static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name)
277 IDProperty *group = RNA_struct_idprops(ptr, 0);
280 return IDP_GetPropertyFromGroup(group, name);
285 static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
287 if (prop->magic == RNA_MAGIC) {
288 int arraylen[RNA_MAX_ARRAY_DIMENSION];
289 return (prop->getlength && ptr->data) ? prop->getlength(ptr, arraylen) : prop->totarraylength;
292 IDProperty *idprop = (IDProperty *)prop;
294 if (idprop->type == IDP_ARRAY)
301 static int rna_ensure_property_array_check(PropertyRNA *prop)
303 if (prop->magic == RNA_MAGIC) {
304 return (prop->getlength || prop->totarraylength) ? 1 : 0;
307 IDProperty *idprop = (IDProperty *)prop;
309 return idprop->type == IDP_ARRAY ? 1 : 0;
313 static void rna_ensure_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int length[])
315 if (prop->magic == RNA_MAGIC) {
317 prop->getlength(ptr, length);
319 memcpy(length, prop->arraylength, prop->arraydimension * sizeof(int));
322 IDProperty *idprop = (IDProperty *)prop;
324 if (idprop->type == IDP_ARRAY)
325 length[0] = idprop->len;
331 static int rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDProperty *idprop)
333 /* this verifies if the idproperty actually matches the property
334 * description and otherwise removes it. this is to ensure that
335 * rna property access is type safe, e.g. if you defined the rna
336 * to have a certain array length you can count on that staying so */
338 switch (idprop->type) {
340 if (prop->type != PROP_COLLECTION)
344 if (rna_ensure_property_array_length(ptr, prop) != idprop->len)
347 if (idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT)
349 if (idprop->subtype == IDP_INT && !ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
354 if (!ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
359 if (prop->type != PROP_FLOAT)
363 if (prop->type != PROP_STRING)
367 if (prop->type != PROP_POINTER)
377 static PropertyRNA *typemap[IDP_NUMTYPES] = {
378 (PropertyRNA *)&rna_PropertyGroupItem_string,
379 (PropertyRNA *)&rna_PropertyGroupItem_int,
380 (PropertyRNA *)&rna_PropertyGroupItem_float,
382 (PropertyRNA *)&rna_PropertyGroupItem_group, NULL,
383 (PropertyRNA *)&rna_PropertyGroupItem_double,
384 (PropertyRNA *)&rna_PropertyGroupItem_idp_array
387 static PropertyRNA *arraytypemap[IDP_NUMTYPES] = {
388 NULL, (PropertyRNA *)&rna_PropertyGroupItem_int_array,
389 (PropertyRNA *)&rna_PropertyGroupItem_float_array,
391 (PropertyRNA *)&rna_PropertyGroupItem_collection, NULL,
392 (PropertyRNA *)&rna_PropertyGroupItem_double_array
395 IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr)
397 /* This is quite a hack, but avoids some complexity in the API. we
398 * pass IDProperty structs as PropertyRNA pointers to the outside.
399 * We store some bytes in PropertyRNA structs that allows us to
400 * distinguish it from IDProperty structs. If it is an ID property,
401 * we look up an IDP PropertyRNA based on the type, and set the data
402 * pointer to the IDProperty. */
404 if ((*prop)->magic == RNA_MAGIC) {
405 if ((*prop)->flag & PROP_IDPROPERTY) {
406 IDProperty *idprop = rna_idproperty_find(ptr, (*prop)->identifier);
408 if (idprop && !rna_idproperty_verify_valid(ptr, *prop, idprop)) {
409 IDProperty *group = RNA_struct_idprops(ptr, 0);
411 IDP_RemFromGroup(group, idprop);
412 IDP_FreeProperty(idprop);
424 IDProperty *idprop = (IDProperty *)(*prop);
426 if (idprop->type == IDP_ARRAY)
427 *prop = arraytypemap[(int)(idprop->subtype)];
429 *prop = typemap[(int)(idprop->type)];
435 static PropertyRNA *rna_ensure_property(PropertyRNA *prop)
437 /* the quick version if we don't need the idproperty */
439 if (prop->magic == RNA_MAGIC)
443 IDProperty *idprop = (IDProperty *)prop;
445 if (idprop->type == IDP_ARRAY)
446 return arraytypemap[(int)(idprop->subtype)];
448 return typemap[(int)(idprop->type)];
452 static const char *rna_ensure_property_identifier(PropertyRNA *prop)
454 if (prop->magic == RNA_MAGIC)
455 return prop->identifier;
457 return ((IDProperty *)prop)->name;
460 static const char *rna_ensure_property_description(PropertyRNA *prop)
462 const char *description = NULL;
464 if (prop->magic == RNA_MAGIC)
465 description = prop->description;
467 /* attempt to get the local ID values */
468 IDProperty *idp_ui = rna_idproperty_ui(prop);
471 IDProperty *item = IDP_GetPropertyTypeFromGroup(idp_ui, "description", IDP_STRING);
473 description = IDP_String(item);
476 if (description == NULL)
477 description = ((IDProperty *)prop)->name; /* XXX - not correct */
480 return TIP_(description);
483 static const char *rna_ensure_property_name(PropertyRNA *prop)
487 if (prop->magic == RNA_MAGIC)
490 name = ((IDProperty *)prop)->name;
492 return CTX_IFACE_(prop->translation_context, name);
497 StructRNA *RNA_struct_find(const char *identifier)
501 for (type = BLENDER_RNA.structs.first; type; type = type->cont.next)
502 if (strcmp(type->identifier, identifier) == 0)
508 const char *RNA_struct_identifier(StructRNA *type)
510 return type->identifier;
513 const char *RNA_struct_ui_name(StructRNA *type)
515 return CTX_IFACE_(type->translation_context, type->name);
518 int RNA_struct_ui_icon(StructRNA *type)
526 const char *RNA_struct_ui_description(StructRNA *type)
528 return TIP_(type->description);
531 const char *RNA_struct_translation_context(StructRNA *type)
533 return type->translation_context ? type->translation_context : BLF_I18NCONTEXT_DEFAULT;
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
602 * function lists in text editors) */
603 /* id prop lookup, not so common */
604 PropertyRNA *r_prop = NULL;
605 PointerRNA r_ptr; /* only support single level props */
606 if (RNA_path_resolve(ptr, identifier, &r_ptr, &r_prop) && r_ptr.type == ptr->type && r_ptr.data == ptr->data)
610 /* most common case */
611 PropertyRNA *iterprop = RNA_struct_iterator_property(ptr->type);
614 if (RNA_property_collection_lookup_string(ptr, iterprop, identifier, &propptr))
621 /* Find the property which uses the given nested struct */
622 static PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
624 PropertyRNA *prop = NULL;
626 RNA_STRUCT_BEGIN(ptr, iprop)
628 /* This assumes that there can only be one user of this nested struct */
629 if (RNA_property_pointer_type(ptr, iprop) == srna) {
639 int RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test)
641 /* note, prop_test could be freed memory, only use for comparison */
643 /* validate the RNA is ok */
644 PropertyRNA *iterprop;
647 iterprop = RNA_struct_iterator_property(ptr->type);
649 RNA_PROP_BEGIN(ptr, itemptr, iterprop)
651 /* PropertyRNA *prop = itemptr.data; */
652 if (prop_test == (PropertyRNA *)itemptr.data) {
662 /* low level direct access to type->properties, note this ignores parent classes so should be used with care */
663 const struct ListBase *RNA_struct_type_properties(StructRNA *srna)
665 return &srna->cont.properties;
668 PropertyRNA *RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
670 return BLI_findstring_ptr(&srna->cont.properties, identifier, offsetof(PropertyRNA, identifier));
673 FunctionRNA *RNA_struct_find_function(StructRNA *srna, const char *identifier)
678 for (type = srna; type; type = type->base) {
679 func = (FunctionRNA *)BLI_findstring_ptr(&type->functions, identifier, offsetof(FunctionRNA, identifier));
686 /* funcitonal but slow */
689 PropertyRNA *iterprop;
692 RNA_pointer_create(NULL, &RNA_Struct, srna, &tptr);
693 iterprop = RNA_struct_find_property(&tptr, "functions");
697 RNA_PROP_BEGIN(&tptr, funcptr, iterprop)
699 if (strcmp(identifier, RNA_function_identifier(funcptr.data)) == 0) {
710 const ListBase *RNA_struct_type_functions(StructRNA *srna)
712 return &srna->functions;
715 StructRegisterFunc RNA_struct_register(StructRNA *type)
720 StructUnregisterFunc RNA_struct_unregister(StructRNA *type)
725 } while ((type = type->base));
730 void **RNA_struct_instance(PointerRNA *ptr)
732 StructRNA *type = ptr->type;
736 return type->instance(ptr);
737 } while ((type = type->base));
742 void *RNA_struct_py_type_get(StructRNA *srna)
744 return srna->py_type;
747 void RNA_struct_py_type_set(StructRNA *srna, void *py_type)
749 srna->py_type = py_type;
752 void *RNA_struct_blender_type_get(StructRNA *srna)
754 return srna->blender_type;
757 void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
759 srna->blender_type = blender_type;
762 char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len)
764 PropertyRNA *nameprop;
766 if (ptr->data && (nameprop = RNA_struct_name_property(ptr->type)))
767 return RNA_property_string_get_alloc(ptr, nameprop, fixedbuf, fixedlen, r_len);
772 /* Property Information */
774 const char *RNA_property_identifier(PropertyRNA *prop)
776 return rna_ensure_property_identifier(prop);
779 const char *RNA_property_description(PropertyRNA *prop)
781 return rna_ensure_property_description(prop);
784 PropertyType RNA_property_type(PropertyRNA *prop)
786 return rna_ensure_property(prop)->type;
789 PropertySubType RNA_property_subtype(PropertyRNA *prop)
791 return rna_ensure_property(prop)->subtype;
794 PropertyUnit RNA_property_unit(PropertyRNA *prop)
796 return RNA_SUBTYPE_UNIT(rna_ensure_property(prop)->subtype);
799 int RNA_property_flag(PropertyRNA *prop)
801 return rna_ensure_property(prop)->flag;
804 void *RNA_property_py_data_get(PropertyRNA *prop)
806 return prop->py_data;
809 int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
811 return rna_ensure_property_array_length(ptr, prop);
814 int RNA_property_array_check(PropertyRNA *prop)
816 return rna_ensure_property_array_check(prop);
819 /* used by BPY to make an array from the python object */
820 int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[])
822 PropertyRNA *rprop = rna_ensure_property(prop);
825 rna_ensure_property_multi_array_length(ptr, prop, length);
827 return rprop->arraydimension;
830 /* Return the size of Nth dimension. */
831 int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dim)
833 int len[RNA_MAX_ARRAY_DIMENSION];
835 rna_ensure_property_multi_array_length(ptr, prop, len);
840 char RNA_property_array_item_char(PropertyRNA *prop, int index)
842 const char *vectoritem = "XYZW";
843 const char *quatitem = "WXYZ";
844 const char *coloritem = "RGBA";
845 PropertySubType subtype = rna_ensure_property(prop)->subtype;
847 /* get string to use for array index */
848 if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
849 return quatitem[index];
851 else if ((index < 4) && ELEM8(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_XYZ_LENGTH,
852 PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION, PROP_COORDS))
854 return vectoritem[index];
856 else if ((index < 4) && ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
857 return coloritem[index];
863 int RNA_property_array_item_index(PropertyRNA *prop, char name)
865 PropertySubType subtype = rna_ensure_property(prop)->subtype;
867 /* get index based on string name/alias */
868 /* maybe a function to find char index in string would be better than all the switches */
869 if (ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
881 else if (ELEM6(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ,
882 PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION))
895 else if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
912 void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
914 IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
915 int softmin, softmax;
917 if (prop->magic != RNA_MAGIC) {
918 /* attempt to get the local ID values */
919 IDProperty *idp_ui = rna_idproperty_ui(prop);
924 item = IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_INT);
925 *hardmin = item ? IDP_Int(item) : INT_MIN;
927 item = IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_INT);
928 *hardmax = item ? IDP_Int(item) : INT_MAX;
938 iprop->range(ptr, hardmin, hardmax, &softmin, &softmax);
941 *hardmin = iprop->hardmin;
942 *hardmax = iprop->hardmax;
946 void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
948 IntPropertyRNA *iprop = (IntPropertyRNA *)rna_ensure_property(prop);
949 int hardmin, hardmax;
951 if (prop->magic != RNA_MAGIC) {
952 /* attempt to get the local ID values */
953 IDProperty *idp_ui = rna_idproperty_ui(prop);
958 item = IDP_GetPropertyTypeFromGroup(idp_ui, "soft_min", IDP_INT);
959 *softmin = item ? IDP_Int(item) : INT_MIN;
961 item = IDP_GetPropertyTypeFromGroup(idp_ui, "soft_max", IDP_INT);
962 *softmax = item ? IDP_Int(item) : INT_MAX;
964 item = IDP_GetPropertyTypeFromGroup(idp_ui, "step", IDP_INT);
965 *step = item ? IDP_Int(item) : 1;
971 *softmin = iprop->softmin;
972 *softmax = iprop->softmax;
978 iprop->range(ptr, &hardmin, &hardmax, softmin, softmax);
980 *softmin = MAX2(*softmin, hardmin);
981 *softmax = MIN2(*softmax, hardmax);
987 void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
989 FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
990 float softmin, softmax;
992 if (prop->magic != RNA_MAGIC) {
993 /* attempt to get the local ID values */
994 IDProperty *idp_ui = rna_idproperty_ui(prop);
999 item = IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_DOUBLE);
1000 *hardmin = item ? (float)IDP_Double(item) : -FLT_MAX;
1002 item = IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_DOUBLE);
1003 *hardmax = item ? (float)IDP_Double(item) : FLT_MAX;
1010 *hardmin = -FLT_MAX;
1013 fprop->range(ptr, hardmin, hardmax, &softmin, &softmax);
1016 *hardmin = fprop->hardmin;
1017 *hardmax = fprop->hardmax;
1021 void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax,
1022 float *step, float *precision)
1024 FloatPropertyRNA *fprop = (FloatPropertyRNA *)rna_ensure_property(prop);
1025 float hardmin, hardmax;
1027 if (prop->magic != RNA_MAGIC) {
1028 /* attempt to get the local ID values */
1029 IDProperty *idp_ui = rna_idproperty_ui(prop);
1034 item = IDP_GetPropertyTypeFromGroup(idp_ui, "soft_min", IDP_DOUBLE);
1035 *softmin = item ? (float)IDP_Double(item) : -FLT_MAX;
1037 item = IDP_GetPropertyTypeFromGroup(idp_ui, "soft_max", IDP_DOUBLE);
1038 *softmax = item ? (float)IDP_Double(item) : FLT_MAX;
1040 item = IDP_GetPropertyTypeFromGroup(idp_ui, "step", IDP_DOUBLE);
1041 *step = item ? (float)IDP_Double(item) : 1.0f;
1043 item = IDP_GetPropertyTypeFromGroup(idp_ui, "precision", IDP_DOUBLE);
1044 *precision = item ? (float)IDP_Double(item) : 3.0f;
1050 *softmin = fprop->softmin;
1051 *softmax = fprop->softmax;
1057 fprop->range(ptr, &hardmin, &hardmax, softmin, softmax);
1059 *softmin = MAX2(*softmin, hardmin);
1060 *softmax = MIN2(*softmax, hardmax);
1063 *step = fprop->step;
1064 *precision = (float)fprop->precision;
1067 int RNA_property_float_clamp(PointerRNA *ptr, PropertyRNA *prop, float *value)
1071 RNA_property_float_range(ptr, prop, &min, &max);
1077 else if (*value > max) {
1086 int RNA_property_int_clamp(PointerRNA *ptr, PropertyRNA *prop, int *value)
1090 RNA_property_int_range(ptr, prop, &min, &max);
1096 else if (*value > max) {
1105 /* this is the max length including \0 terminator.
1106 * '0' used when their is no maximum */
1107 int RNA_property_string_maxlength(PropertyRNA *prop)
1109 StringPropertyRNA *sprop = (StringPropertyRNA *)rna_ensure_property(prop);
1110 return sprop->maxlength;
1113 StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
1115 prop = rna_ensure_property(prop);
1117 if (prop->type == PROP_POINTER) {
1118 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1121 return pprop->typef(ptr);
1122 else if (pprop->type)
1125 else if (prop->type == PROP_COLLECTION) {
1126 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
1128 if (cprop->item_type)
1129 return cprop->item_type;
1131 /* ignore other types, RNA_struct_find_nested calls with unchecked props */
1133 return &RNA_UnknownType;
1136 int RNA_property_pointer_poll(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *value)
1138 prop = rna_ensure_property(prop);
1140 if (prop->type == PROP_POINTER) {
1141 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1143 return pprop->poll(ptr, *value);
1148 printf("%s %s: is not a pointer property.\n", __func__, prop->identifier);
1152 /* Reuse for dynamic types */
1153 EnumPropertyItem DummyRNA_NULL_items[] = {
1154 {0, NULL, 0, NULL, NULL}
1157 /* Reuse for dynamic types with default value */
1158 EnumPropertyItem DummyRNA_DEFAULT_items[] = {
1159 {0, "DEFAULT", 0, "Default", ""},
1160 {0, NULL, 0, NULL, NULL}
1163 void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item,
1164 int *totitem, int *free)
1166 EnumPropertyRNA *eprop = (EnumPropertyRNA *)rna_ensure_property(prop);
1170 if (eprop->itemf && (C != NULL || (prop->flag & PROP_ENUM_NO_CONTEXT))) {
1173 if (prop->flag & PROP_ENUM_NO_CONTEXT)
1174 *item = eprop->itemf(NULL, ptr, prop, free);
1176 *item = eprop->itemf(C, ptr, prop, free);
1180 for (; (*item)[tot].identifier; tot++) ;
1188 *item = eprop->item;
1190 *totitem = eprop->totitem;
1194 void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop,
1195 EnumPropertyItem **item, int *totitem, int *free)
1197 RNA_property_enum_items(C, ptr, prop, item, totitem, free);
1199 #ifdef WITH_INTERNATIONAL
1200 /* Note: keep directly using BLF_gettext here, has we have already done tests like BLF_translate_iface... */
1201 if (BLF_translate_iface()) {
1203 EnumPropertyItem *nitem;
1212 for (i = 0; (*item)[i].identifier; i++)
1215 nitem = MEM_callocN(sizeof(EnumPropertyItem) * (totitem + 1), "enum_items_gettexted");
1217 for (i = 0; (*item)[i].identifier; i++)
1218 nitem[i] = (*item)[i];
1223 for (i = 0; nitem[i].identifier; i++) {
1224 if (nitem[i].name) {
1225 /* note: prop->translation_context may be NULL, this just means we dont use a context */
1226 nitem[i].name = BLF_pgettext(prop->translation_context, nitem[i].name);
1228 if (nitem[i].description)
1229 nitem[i].description = BLF_pgettext(NULL, nitem[i].description);
1238 int RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value)
1240 EnumPropertyItem *item, *item_array;
1243 RNA_property_enum_items(C, ptr, prop, &item_array, NULL, &free);
1246 for (item = item_array; item->identifier; item++) {
1247 if (item->identifier[0] && strcmp(item->identifier, identifier) == 0) {
1248 *value = item->value;
1253 found = (item->identifier != NULL); /* could be alloc'd, assign before free */
1256 MEM_freeN(item_array);
1265 int RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier)
1267 for (; item->identifier; item++) {
1268 if (item->identifier[0] && item->value == value) {
1269 *identifier = item->identifier;
1276 int RNA_enum_bitflag_identifiers(EnumPropertyItem *item, const int value, const char **identifier)
1279 for (; item->identifier; item++) {
1280 if (item->identifier[0] && item->value & value) {
1281 identifier[index++] = item->identifier;
1284 identifier[index] = NULL;
1288 int RNA_enum_name(EnumPropertyItem *item, const int value, const char **name)
1290 for (; item->identifier; item++) {
1291 if (item->identifier[0] && item->value == value) {
1299 int RNA_enum_description(EnumPropertyItem *item, const int value, const char **description)
1301 for (; item->identifier; item++) {
1302 if (item->identifier[0] && item->value == value) {
1303 *description = item->description;
1310 int RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
1311 const char **identifier)
1313 EnumPropertyItem *item = NULL;
1316 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1318 result = RNA_enum_identifier(item, value, identifier);
1327 int RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
1329 EnumPropertyItem *item = NULL;
1332 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1334 result = RNA_enum_name(item, value, name);
1343 int RNA_property_enum_bitflag_identifiers(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
1344 const char **identifier)
1346 EnumPropertyItem *item = NULL;
1349 RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
1351 result = RNA_enum_bitflag_identifiers(item, value, identifier);
1360 const char *RNA_property_ui_name(PropertyRNA *prop)
1362 return rna_ensure_property_name(prop);
1365 const char *RNA_property_ui_description(PropertyRNA *prop)
1367 return rna_ensure_property_description(prop);
1370 const char *RNA_property_translation_context(PropertyRNA *_prop)
1372 PropertyRNA *prop = rna_ensure_property(_prop);
1373 return prop->translation_context ? prop->translation_context : BLF_I18NCONTEXT_DEFAULT;
1376 int RNA_property_ui_icon(PropertyRNA *prop)
1378 return rna_ensure_property(prop)->icon;
1381 int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
1383 ID *id = ptr->id.data;
1386 prop = rna_ensure_property(prop);
1387 flag = prop->editable ? prop->editable(ptr) : prop->flag;
1388 return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
1391 int RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop)
1395 prop = rna_ensure_property(prop);
1396 flag = prop->editable ? prop->editable(ptr) : prop->flag;
1397 return (flag & PROP_EDITABLE);
1400 /* same as RNA_property_editable(), except this checks individual items in an array */
1401 int RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1406 prop = rna_ensure_property(prop);
1411 flag &= prop->editable(ptr);
1413 if (prop->itemeditable)
1414 flag &= prop->itemeditable(ptr, index);
1418 return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
1421 int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
1423 /* check that base ID-block can support animation data */
1424 if (!id_type_can_have_animdata(ptr->id.data))
1427 prop = rna_ensure_property(prop);
1429 if (!(prop->flag & PROP_ANIMATABLE))
1432 return (prop->flag & PROP_EDITABLE);
1435 int RNA_property_animated(PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop))
1437 /* would need to ask animation system */
1443 /* this function is to check if its possible to create a valid path from the ID
1444 * its slow so don't call in a loop */
1445 int RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
1447 char *path = RNA_path_from_ID_to_property(ptr, prop);
1453 PropertyRNA *r_prop;
1455 RNA_id_pointer_create(ptr->id.data, &id_ptr);
1456 if (RNA_path_resolve(&id_ptr, path, &r_ptr, &r_prop) == TRUE) {
1457 ret = (prop == r_prop);
1469 static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
1471 int is_rna = (prop->magic == RNA_MAGIC);
1472 prop = rna_ensure_property(prop);
1476 /* ideally no context would be needed for update, but there's some
1477 * parts of the code that need it still, so we have this exception */
1478 if (prop->flag & PROP_CONTEXT_UPDATE) {
1480 if (prop->flag & PROP_CONTEXT_PROPERTY_UPDATE) {
1481 ((ContextPropUpdateFunc)prop->update)(C, ptr, prop);
1484 ((ContextUpdateFunc)prop->update)(C, ptr);
1489 prop->update(bmain, scene, ptr);
1492 WM_main_add_notifier(prop->noteflag, ptr->id.data);
1495 if (!is_rna || (prop->flag & PROP_IDPROPERTY)) {
1496 /* WARNING! This is so property drivers update the display!
1497 * not especially nice */
1498 DAG_id_tag_update(ptr->id.data, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
1499 WM_main_add_notifier(NC_WINDOW, NULL);
1503 /* must keep in sync with 'rna_property_update'
1504 * note, its possible this returns a false positive in the case of PROP_CONTEXT_UPDATE
1505 * but this isn't likely to be a performance problem. */
1506 int RNA_property_update_check(PropertyRNA *prop)
1508 return (prop->magic != RNA_MAGIC || prop->update || prop->noteflag);
1511 void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
1513 rna_property_update(C, CTX_data_main(C), CTX_data_scene(C), ptr, prop);
1516 void RNA_property_update_main(Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
1518 rna_property_update(NULL, bmain, scene, ptr, prop);
1522 /* RNA Updates Cache ------------------------ */
1523 /* Overview of RNA Update cache system:
1525 * RNA Update calls need to be cached in order to maintain reasonable performance
1526 * of the animation system (i.e. maintaining a somewhat interactive framerate)
1527 * while still allowing updates to be called (necessary in particular for modifier
1528 * property updates to actually work).
1530 * The cache is structured with a dual-layer structure
1531 * - L1 = PointerRNA used as key; id.data is used (it should always be defined,
1532 * and most updates end up using just that anyways)
1533 * - L2 = Update functions to be called on those PointerRNA's
1537 typedef struct tRnaUpdateCacheElem {
1538 struct tRnaUpdateCacheElem *next, *prev;
1540 PointerRNA ptr; /* L1 key - id as primary, data secondary/ignored? */
1541 ListBase L2Funcs; /* L2 functions (LinkData<RnaUpdateFuncRef>) */
1542 } tRnaUpdateCacheElem;
1544 /* cache global (tRnaUpdateCacheElem's) - only accessible using these API calls */
1545 static ListBase rna_updates_cache = {NULL, NULL};
1547 /* ........................... */
1549 void RNA_property_update_cache_add(PointerRNA *ptr, PropertyRNA *prop)
1551 tRnaUpdateCacheElem *uce = NULL;
1552 UpdateFunc fn = NULL;
1554 short is_rna = (prop->magic == RNA_MAGIC);
1557 if (ELEM(NULL, ptr, prop))
1560 prop = rna_ensure_property(prop);
1562 /* we can only handle update calls with no context args for now (makes animsys updates easier) */
1563 if ((is_rna == 0) || (prop->update == NULL) || (prop->flag & PROP_CONTEXT_UPDATE))
1567 /* find cache element for which key matches... */
1568 for (uce = rna_updates_cache.first; uce; uce = uce->next) {
1569 /* just match by id only for now, since most update calls that we'll encounter only really care about this */
1570 /* TODO: later, the cache might need to have some nesting on L1 to cope better
1571 * with these problems + some tagging to indicate we need this */
1572 if (uce->ptr.id.data == ptr->id.data)
1576 /* create new instance */
1577 uce = MEM_callocN(sizeof(tRnaUpdateCacheElem), "tRnaUpdateCacheElem");
1578 BLI_addtail(&rna_updates_cache, uce);
1581 RNA_pointer_create(ptr->id.data, ptr->type, ptr->data, &uce->ptr);
1584 /* check on the update func */
1585 for (ld = uce->L2Funcs.first; ld; ld = ld->next) {
1586 /* stop on match - function already cached */
1590 /* else... if still here, we need to add it */
1591 BLI_addtail(&uce->L2Funcs, BLI_genericNodeN(fn));
1594 void RNA_property_update_cache_flush(Main *bmain, Scene *scene)
1596 tRnaUpdateCacheElem *uce;
1598 /* TODO: should we check that bmain and scene are valid? The above stuff doesn't! */
1600 /* execute the cached updates */
1601 for (uce = rna_updates_cache.first; uce; uce = uce->next) {
1604 for (ld = uce->L2Funcs.first; ld; ld = ld->next) {
1605 UpdateFunc fn = (UpdateFunc)ld->data;
1606 fn(bmain, scene, &uce->ptr);
1611 void RNA_property_update_cache_free(void)
1613 tRnaUpdateCacheElem *uce, *ucn;
1615 for (uce = rna_updates_cache.first; uce; uce = ucn) {
1619 BLI_freelistN(&uce->L2Funcs);
1622 BLI_freelinkN(&rna_updates_cache, uce);
1626 /* ---------------------------------------------------------------------- */
1630 int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
1632 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1635 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1636 BLI_assert(RNA_property_array_check(prop) == 0);
1638 if ((idprop = rna_idproperty_check(&prop, ptr)))
1639 return IDP_Int(idprop);
1640 else if (bprop->get)
1641 return bprop->get(ptr);
1643 return bprop->defaultvalue;
1646 void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1648 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1651 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1652 BLI_assert(RNA_property_array_check(prop) == 0);
1654 /* just in case other values are passed */
1655 if (value) value = 1;
1657 if ((idprop = rna_idproperty_check(&prop, ptr))) {
1658 IDP_Int(idprop) = value;
1659 rna_idproperty_touch(idprop);
1661 else if (bprop->set) {
1662 bprop->set(ptr, value);
1664 else if (prop->flag & PROP_EDITABLE) {
1665 IDPropertyTemplate val = {0};
1670 group = RNA_struct_idprops(ptr, 1);
1672 IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
1676 void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
1678 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1681 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1682 BLI_assert(RNA_property_array_check(prop) != 0);
1684 if ((idprop = rna_idproperty_check(&prop, ptr))) {
1685 if (prop->arraydimension == 0)
1686 values[0] = RNA_property_boolean_get(ptr, prop);
1688 memcpy(values, IDP_Array(idprop), sizeof(int) * idprop->len);
1690 else if (prop->arraydimension == 0)
1691 values[0] = RNA_property_boolean_get(ptr, prop);
1692 else if (bprop->getarray)
1693 bprop->getarray(ptr, values);
1694 else if (bprop->defaultarray)
1695 memcpy(values, bprop->defaultarray, sizeof(int) * prop->totarraylength);
1697 memset(values, 0, sizeof(int) * prop->totarraylength);
1700 int RNA_property_boolean_get_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 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1706 BLI_assert(RNA_property_array_check(prop) != 0);
1708 if (len <= RNA_MAX_ARRAY_LENGTH) {
1709 RNA_property_boolean_get_array(ptr, prop, tmp);
1713 int *tmparray, value;
1715 tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_boolean_get_index");
1716 RNA_property_boolean_get_array(ptr, prop, tmparray);
1717 value = tmparray[index];
1718 MEM_freeN(tmparray);
1724 void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
1726 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1729 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1730 BLI_assert(RNA_property_array_check(prop) != 0);
1732 if ((idprop = rna_idproperty_check(&prop, ptr))) {
1733 if (prop->arraydimension == 0)
1734 IDP_Int(idprop) = values[0];
1736 memcpy(IDP_Array(idprop), values, sizeof(int) * idprop->len);
1738 rna_idproperty_touch(idprop);
1740 else if (prop->arraydimension == 0)
1741 RNA_property_boolean_set(ptr, prop, values[0]);
1742 else if (bprop->setarray)
1743 bprop->setarray(ptr, values);
1744 else if (prop->flag & PROP_EDITABLE) {
1745 IDPropertyTemplate val = {0};
1748 val.array.len = prop->totarraylength;
1749 val.array.type = IDP_INT;
1751 group = RNA_struct_idprops(ptr, 1);
1753 idprop = IDP_New(IDP_ARRAY, &val, prop->identifier);
1754 IDP_AddToGroup(group, idprop);
1755 memcpy(IDP_Array(idprop), values, sizeof(int) * idprop->len);
1760 void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
1762 int tmp[RNA_MAX_ARRAY_LENGTH];
1763 int len = rna_ensure_property_array_length(ptr, prop);
1765 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1766 BLI_assert(RNA_property_array_check(prop) != 0);
1768 if (len <= RNA_MAX_ARRAY_LENGTH) {
1769 RNA_property_boolean_get_array(ptr, prop, tmp);
1771 RNA_property_boolean_set_array(ptr, prop, tmp);
1776 tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_boolean_get_index");
1777 RNA_property_boolean_get_array(ptr, prop, tmparray);
1778 tmparray[index] = value;
1779 RNA_property_boolean_set_array(ptr, prop, tmparray);
1780 MEM_freeN(tmparray);
1784 int RNA_property_boolean_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
1786 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1788 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1789 BLI_assert(RNA_property_array_check(prop) == 0);
1791 return bprop->defaultvalue;
1794 void RNA_property_boolean_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int *values)
1796 BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1798 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1799 BLI_assert(RNA_property_array_check(prop) != 0);
1801 if (prop->arraydimension == 0)
1802 values[0] = bprop->defaultvalue;
1803 else if (bprop->defaultarray)
1804 memcpy(values, bprop->defaultarray, sizeof(int) * prop->totarraylength);
1806 memset(values, 0, sizeof(int) * prop->totarraylength);
1809 int RNA_property_boolean_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1811 int tmp[RNA_MAX_ARRAY_LENGTH];
1812 int len = rna_ensure_property_array_length(ptr, prop);
1814 BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
1815 BLI_assert(RNA_property_array_check(prop) != 0);
1817 if (len <= RNA_MAX_ARRAY_LENGTH) {
1818 RNA_property_boolean_get_default_array(ptr, prop, tmp);
1822 int *tmparray, value;
1824 tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_boolean_get_default_index");
1825 RNA_property_boolean_get_default_array(ptr, prop, tmparray);
1826 value = tmparray[index];
1827 MEM_freeN(tmparray);
1833 int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
1835 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1838 BLI_assert(RNA_property_type(prop) == PROP_INT);
1839 BLI_assert(RNA_property_array_check(prop) == 0);
1841 if ((idprop = rna_idproperty_check(&prop, ptr)))
1842 return IDP_Int(idprop);
1843 else if (iprop->get)
1844 return iprop->get(ptr);
1846 return iprop->defaultvalue;
1849 void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1851 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1854 BLI_assert(RNA_property_type(prop) == PROP_INT);
1855 BLI_assert(RNA_property_array_check(prop) == 0);
1856 /* useful to check on bad values but set function should clamp */
1857 /* BLI_assert(RNA_property_int_clamp(ptr, prop, &value) == 0); */
1859 if ((idprop = rna_idproperty_check(&prop, ptr))) {
1860 IDP_Int(idprop) = value;
1861 rna_idproperty_touch(idprop);
1863 else if (iprop->set)
1864 iprop->set(ptr, value);
1865 else if (prop->flag & PROP_EDITABLE) {
1866 IDPropertyTemplate val = {0};
1869 RNA_property_int_clamp(ptr, prop, &value);
1873 group = RNA_struct_idprops(ptr, 1);
1875 IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
1879 void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
1881 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1884 BLI_assert(RNA_property_type(prop) == PROP_INT);
1885 BLI_assert(RNA_property_array_check(prop) != 0);
1887 if ((idprop = rna_idproperty_check(&prop, ptr))) {
1888 if (prop->arraydimension == 0)
1889 values[0] = RNA_property_int_get(ptr, prop);
1891 memcpy(values, IDP_Array(idprop), sizeof(int) * idprop->len);
1893 else if (prop->arraydimension == 0)
1894 values[0] = RNA_property_int_get(ptr, prop);
1895 else if (iprop->getarray)
1896 iprop->getarray(ptr, values);
1897 else if (iprop->defaultarray)
1898 memcpy(values, iprop->defaultarray, sizeof(int) * prop->totarraylength);
1900 memset(values, 0, sizeof(int) * prop->totarraylength);
1903 void RNA_property_int_get_array_range(PointerRNA *ptr, PropertyRNA *prop, int values[2])
1905 const int array_len = RNA_property_array_length(ptr, prop);
1907 if (array_len <= 0) {
1911 else if (array_len == 1) {
1912 RNA_property_int_get_array(ptr, prop, values);
1913 values[1] = values[0];
1920 if (array_len > 32) {
1921 arr = MEM_mallocN(sizeof(int) * array_len, "RNA_property_int_get_array_range");
1927 RNA_property_int_get_array(ptr, prop, arr);
1928 values[0] = values[1] = arr[0];
1929 for (i = 1; i < array_len; i++) {
1930 values[0] = MIN2(values[0], arr[i]);
1931 values[1] = MAX2(values[1], arr[i]);
1934 if (arr != arr_stack) {
1940 int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1942 int tmp[RNA_MAX_ARRAY_LENGTH];
1943 int len = rna_ensure_property_array_length(ptr, prop);
1945 BLI_assert(RNA_property_type(prop) == PROP_INT);
1946 BLI_assert(RNA_property_array_check(prop) != 0);
1948 if (len <= RNA_MAX_ARRAY_LENGTH) {
1949 RNA_property_int_get_array(ptr, prop, tmp);
1953 int *tmparray, value;
1955 tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_int_get_index");
1956 RNA_property_int_get_array(ptr, prop, tmparray);
1957 value = tmparray[index];
1958 MEM_freeN(tmparray);
1964 void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
1966 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1969 BLI_assert(RNA_property_type(prop) == PROP_INT);
1970 BLI_assert(RNA_property_array_check(prop) != 0);
1972 if ((idprop = rna_idproperty_check(&prop, ptr))) {
1973 if (prop->arraydimension == 0)
1974 IDP_Int(idprop) = values[0];
1976 memcpy(IDP_Array(idprop), values, sizeof(int) * idprop->len);
1978 rna_idproperty_touch(idprop);
1980 else if (prop->arraydimension == 0)
1981 RNA_property_int_set(ptr, prop, values[0]);
1982 else if (iprop->setarray)
1983 iprop->setarray(ptr, values);
1984 else if (prop->flag & PROP_EDITABLE) {
1985 IDPropertyTemplate val = {0};
1988 /* TODO: RNA_property_int_clamp_array(ptr, prop, &value); */
1990 val.array.len = prop->totarraylength;
1991 val.array.type = IDP_INT;
1993 group = RNA_struct_idprops(ptr, 1);
1995 idprop = IDP_New(IDP_ARRAY, &val, prop->identifier);
1996 IDP_AddToGroup(group, idprop);
1997 memcpy(IDP_Array(idprop), values, sizeof(int) * idprop->len);
2002 void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
2004 int tmp[RNA_MAX_ARRAY_LENGTH];
2005 int len = rna_ensure_property_array_length(ptr, prop);
2007 BLI_assert(RNA_property_type(prop) == PROP_INT);
2008 BLI_assert(RNA_property_array_check(prop) != 0);
2010 if (len <= RNA_MAX_ARRAY_LENGTH) {
2011 RNA_property_int_get_array(ptr, prop, tmp);
2013 RNA_property_int_set_array(ptr, prop, tmp);
2018 tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_int_get_index");
2019 RNA_property_int_get_array(ptr, prop, tmparray);
2020 tmparray[index] = value;
2021 RNA_property_int_set_array(ptr, prop, tmparray);
2022 MEM_freeN(tmparray);
2026 int RNA_property_int_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2028 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2029 return iprop->defaultvalue;
2032 void RNA_property_int_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int *values)
2034 IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2036 BLI_assert(RNA_property_type(prop) == PROP_INT);
2037 BLI_assert(RNA_property_array_check(prop) != 0);
2039 if (prop->arraydimension == 0)
2040 values[0] = iprop->defaultvalue;
2041 else if (iprop->defaultarray)
2042 memcpy(values, iprop->defaultarray, sizeof(int) * prop->totarraylength);
2044 memset(values, 0, sizeof(int) * prop->totarraylength);
2047 int RNA_property_int_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2049 int tmp[RNA_MAX_ARRAY_LENGTH];
2050 int len = rna_ensure_property_array_length(ptr, prop);
2052 if (len <= RNA_MAX_ARRAY_LENGTH) {
2053 RNA_property_int_get_default_array(ptr, prop, tmp);
2057 int *tmparray, value;
2059 tmparray = MEM_callocN(sizeof(int) * len, "RNA_property_int_get_default_index");
2060 RNA_property_int_get_default_array(ptr, prop, tmparray);
2061 value = tmparray[index];
2062 MEM_freeN(tmparray);
2068 float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
2070 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2073 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2074 BLI_assert(RNA_property_array_check(prop) == 0);
2076 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2077 if (idprop->type == IDP_FLOAT)
2078 return IDP_Float(idprop);
2080 return (float)IDP_Double(idprop);
2082 else if (fprop->get)
2083 return fprop->get(ptr);
2085 return fprop->defaultvalue;
2088 void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
2090 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2093 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2094 BLI_assert(RNA_property_array_check(prop) == 0);
2095 /* useful to check on bad values but set function should clamp */
2096 /* BLI_assert(RNA_property_float_clamp(ptr, prop, &value) == 0); */
2098 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2099 if (idprop->type == IDP_FLOAT)
2100 IDP_Float(idprop) = value;
2102 IDP_Double(idprop) = value;
2104 rna_idproperty_touch(idprop);
2106 else if (fprop->set) {
2107 fprop->set(ptr, value);
2109 else if (prop->flag & PROP_EDITABLE) {
2110 IDPropertyTemplate val = {0};
2113 RNA_property_float_clamp(ptr, prop, &value);
2117 group = RNA_struct_idprops(ptr, 1);
2119 IDP_AddToGroup(group, IDP_New(IDP_FLOAT, &val, prop->identifier));
2123 void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
2125 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2129 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2130 BLI_assert(RNA_property_array_check(prop) != 0);
2132 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2133 if (prop->arraydimension == 0)
2134 values[0] = RNA_property_float_get(ptr, prop);
2135 else if (idprop->subtype == IDP_FLOAT) {
2136 memcpy(values, IDP_Array(idprop), sizeof(float) * idprop->len);
2139 for (i = 0; i < idprop->len; i++)
2140 values[i] = (float)(((double *)IDP_Array(idprop))[i]);
2143 else if (prop->arraydimension == 0)
2144 values[0] = RNA_property_float_get(ptr, prop);
2145 else if (fprop->getarray)
2146 fprop->getarray(ptr, values);
2147 else if (fprop->defaultarray)
2148 memcpy(values, fprop->defaultarray, sizeof(float) * prop->totarraylength);
2150 memset(values, 0, sizeof(float) * prop->totarraylength);
2153 void RNA_property_float_get_array_range(PointerRNA *ptr, PropertyRNA *prop, float values[2])
2155 const int array_len = RNA_property_array_length(ptr, prop);
2157 if (array_len <= 0) {
2161 else if (array_len == 1) {
2162 RNA_property_float_get_array(ptr, prop, values);
2163 values[1] = values[0];
2166 float arr_stack[32];
2170 if (array_len > 32) {
2171 arr = MEM_mallocN(sizeof(float) * array_len, "RNA_property_float_get_array_range");
2177 RNA_property_float_get_array(ptr, prop, arr);
2178 values[0] = values[1] = arr[0];
2179 for (i = 1; i < array_len; i++) {
2180 values[0] = MIN2(values[0], arr[i]);
2181 values[1] = MAX2(values[1], arr[i]);
2184 if (arr != arr_stack) {
2190 float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2192 float tmp[RNA_MAX_ARRAY_LENGTH];
2193 int len = rna_ensure_property_array_length(ptr, prop);
2195 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2196 BLI_assert(RNA_property_array_check(prop) != 0);
2198 if (len <= RNA_MAX_ARRAY_LENGTH) {
2199 RNA_property_float_get_array(ptr, prop, tmp);
2203 float *tmparray, value;
2205 tmparray = MEM_callocN(sizeof(float) * len, "RNA_property_float_get_index");
2206 RNA_property_float_get_array(ptr, prop, tmparray);
2207 value = tmparray[index];
2208 MEM_freeN(tmparray);
2215 void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
2217 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2221 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2222 BLI_assert(RNA_property_array_check(prop) != 0);
2224 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2225 if (prop->arraydimension == 0) {
2226 if (idprop->type == IDP_FLOAT)
2227 IDP_Float(idprop) = values[0];
2229 IDP_Double(idprop) = values[0];
2231 else if (idprop->subtype == IDP_FLOAT) {
2232 memcpy(IDP_Array(idprop), values, sizeof(float) * idprop->len);
2235 for (i = 0; i < idprop->len; i++)
2236 ((double *)IDP_Array(idprop))[i] = values[i];
2239 rna_idproperty_touch(idprop);
2241 else if (prop->arraydimension == 0)
2242 RNA_property_float_set(ptr, prop, values[0]);
2243 else if (fprop->setarray) {
2244 fprop->setarray(ptr, values);
2246 else if (prop->flag & PROP_EDITABLE) {
2247 IDPropertyTemplate val = {0};
2250 /* TODO: RNA_property_float_clamp_array(ptr, prop, &value); */
2252 val.array.len = prop->totarraylength;
2253 val.array.type = IDP_FLOAT;
2255 group = RNA_struct_idprops(ptr, 1);
2257 idprop = IDP_New(IDP_ARRAY, &val, prop->identifier);
2258 IDP_AddToGroup(group, idprop);
2259 memcpy(IDP_Array(idprop), values, sizeof(float) * idprop->len);
2264 void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
2266 float tmp[RNA_MAX_ARRAY_LENGTH];
2267 int len = rna_ensure_property_array_length(ptr, prop);
2269 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2270 BLI_assert(RNA_property_array_check(prop) != 0);
2272 if (len <= RNA_MAX_ARRAY_LENGTH) {
2273 RNA_property_float_get_array(ptr, prop, tmp);
2275 RNA_property_float_set_array(ptr, prop, tmp);
2280 tmparray = MEM_callocN(sizeof(float) * len, "RNA_property_float_get_index");
2281 RNA_property_float_get_array(ptr, prop, tmparray);
2282 tmparray[index] = value;
2283 RNA_property_float_set_array(ptr, prop, tmparray);
2284 MEM_freeN(tmparray);
2288 float RNA_property_float_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2290 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2292 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2293 BLI_assert(RNA_property_array_check(prop) == 0);
2295 return fprop->defaultvalue;
2298 void RNA_property_float_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, float *values)
2300 FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2302 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2303 BLI_assert(RNA_property_array_check(prop) != 0);
2305 if (prop->arraydimension == 0)
2306 values[0] = fprop->defaultvalue;
2307 else if (fprop->defaultarray)
2308 memcpy(values, fprop->defaultarray, sizeof(float) * prop->totarraylength);
2310 memset(values, 0, sizeof(float) * prop->totarraylength);
2313 float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
2315 float tmp[RNA_MAX_ARRAY_LENGTH];
2316 int len = rna_ensure_property_array_length(ptr, prop);
2318 BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
2319 BLI_assert(RNA_property_array_check(prop) != 0);
2321 if (len <= RNA_MAX_ARRAY_LENGTH) {
2322 RNA_property_float_get_default_array(ptr, prop, tmp);
2326 float *tmparray, value;
2328 tmparray = MEM_callocN(sizeof(float) * len, "RNA_property_float_get_default_index");
2329 RNA_property_float_get_default_array(ptr, prop, tmparray);
2330 value = tmparray[index];
2331 MEM_freeN(tmparray);
2337 void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
2339 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2342 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2344 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2345 /* editing bytes is not 100% supported
2346 * since they can contain NIL chars */
2347 if (idprop->subtype == IDP_STRING_SUB_BYTE) {
2348 memcpy(value, IDP_String(idprop), idprop->len);
2349 value[idprop->len] = '\0';
2352 memcpy(value, IDP_String(idprop), idprop->len);
2355 else if (sprop->get) {
2356 sprop->get(ptr, value);
2359 strcpy(value, sprop->defaultvalue);
2363 char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop,
2364 char *fixedbuf, int fixedlen, int *r_len)
2369 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2371 length = RNA_property_string_length(ptr, prop);
2373 if (length + 1 < fixedlen)
2376 buf = MEM_mallocN(sizeof(char) * (length + 1), "RNA_string_get_alloc");
2379 /* safety check to ensure the string is actually set */
2383 RNA_property_string_get(ptr, prop, buf);
2386 BLI_assert(buf[length] == '\0');
2396 /* this is the length without \0 terminator */
2397 int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
2399 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2402 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2404 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2405 if (idprop->subtype == IDP_STRING_SUB_BYTE) {
2410 /* these _must_ stay in sync */
2411 BLI_assert(strlen(IDP_String(idprop)) == idprop->len - 1);
2413 return idprop->len - 1;
2416 else if (sprop->length)
2417 return sprop->length(ptr);
2419 return strlen(sprop->defaultvalue);
2422 void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
2424 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2427 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2429 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2430 /* both IDP_STRING_SUB_BYTE / IDP_STRING_SUB_UTF8 */
2431 IDP_AssignString(idprop, value, RNA_property_string_maxlength(prop) - 1);
2432 rna_idproperty_touch(idprop);
2434 else if (sprop->set)
2435 sprop->set(ptr, value); /* set function needs to clamp its self */
2436 else if (prop->flag & PROP_EDITABLE) {
2439 group = RNA_struct_idprops(ptr, 1);
2441 IDP_AddToGroup(group, IDP_NewString(value, prop->identifier, RNA_property_string_maxlength(prop) - 1));
2445 void RNA_property_string_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop, char *value)
2447 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2449 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2451 strcpy(value, sprop->defaultvalue);
2454 char *RNA_property_string_get_default_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen)
2459 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2461 length = RNA_property_string_default_length(ptr, prop);
2463 if (length + 1 < fixedlen)
2466 buf = MEM_callocN(sizeof(char) * (length + 1), "RNA_string_get_alloc");
2468 RNA_property_string_get_default(ptr, prop, buf);
2473 /* this is the length without \0 terminator */
2474 int RNA_property_string_default_length(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2476 StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2478 BLI_assert(RNA_property_type(prop) == PROP_STRING);
2480 return strlen(sprop->defaultvalue);
2483 int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
2485 EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2488 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2490 if ((idprop = rna_idproperty_check(&prop, ptr)))
2491 return IDP_Int(idprop);
2492 else if (eprop->get)
2493 return eprop->get(ptr);
2495 return eprop->defaultvalue;
2498 void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
2500 EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2503 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2505 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2506 IDP_Int(idprop) = value;
2507 rna_idproperty_touch(idprop);
2509 else if (eprop->set) {
2510 eprop->set(ptr, value);
2512 else if (prop->flag & PROP_EDITABLE) {
2513 IDPropertyTemplate val = {0};
2518 group = RNA_struct_idprops(ptr, 1);
2520 IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
2524 int RNA_property_enum_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
2526 EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2528 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2530 return eprop->defaultvalue;
2533 void *RNA_property_enum_py_data_get(PropertyRNA *prop)
2535 EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2537 BLI_assert(RNA_property_type(prop) == PROP_ENUM);
2539 return eprop->py_data;
2542 PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
2544 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
2547 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2549 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2550 pprop = (PointerPropertyRNA *)prop;
2552 /* for groups, data is idprop itself */
2554 return rna_pointer_inherit_refine(ptr, pprop->typef(ptr), idprop);
2556 return rna_pointer_inherit_refine(ptr, pprop->type, idprop);
2558 else if (pprop->get) {
2559 return pprop->get(ptr);
2561 else if (prop->flag & PROP_IDPROPERTY) {
2562 /* XXX temporary hack to add it automatically, reading should
2563 * never do any write ops, to ensure thread safety etc .. */
2564 RNA_property_pointer_add(ptr, prop);
2565 return RNA_property_pointer_get(ptr, prop);
2568 return PointerRNA_NULL;
2572 void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value)
2574 /*IDProperty *idprop;*/
2576 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2578 if ((/*idprop = */ rna_idproperty_check(&prop, ptr))) {
2580 /* rna_idproperty_touch(idprop); */
2583 PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
2586 !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL) &&
2587 !((prop->flag & PROP_ID_SELF_CHECK) && ptr->id.data == ptr_value.id.data))
2589 pprop->set(ptr, ptr_value);
2594 PointerRNA RNA_property_pointer_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop))
2596 /*PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop; */
2598 /* BLI_assert(RNA_property_type(prop) == PROP_POINTER); */
2600 return PointerRNA_NULL; /* FIXME: there has to be a way... */
2603 void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop)
2605 /*IDProperty *idprop;*/
2607 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2609 if ((/*idprop=*/ rna_idproperty_check(&prop, ptr))) {
2610 /* already exists */
2612 else if (prop->flag & PROP_IDPROPERTY) {
2613 IDPropertyTemplate val = {0};
2618 group = RNA_struct_idprops(ptr, 1);
2620 IDP_AddToGroup(group, IDP_New(IDP_GROUP, &val, prop->identifier));
2623 printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);
2626 void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop)
2628 IDProperty *idprop, *group;
2630 BLI_assert(RNA_property_type(prop) == PROP_POINTER);
2632 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2633 group = RNA_struct_idprops(ptr, 0);
2636 IDP_RemFromGroup(group, idprop);
2637 IDP_FreeProperty(idprop);
2642 printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);
2645 static void rna_property_collection_get_idp(CollectionPropertyIterator *iter)
2647 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)iter->prop;
2649 iter->ptr.data = rna_iterator_array_get(iter);
2650 iter->ptr.type = cprop->item_type;
2651 rna_pointer_inherit_id(cprop->item_type, &iter->parent, &iter->ptr);
2654 void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter)
2658 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2660 memset(iter, 0, sizeof(*iter));
2662 if ((idprop = rna_idproperty_check(&prop, ptr)) || (prop->flag & PROP_IDPROPERTY)) {
2663 iter->parent = *ptr;
2667 rna_iterator_array_begin(iter, IDP_IDPArray(idprop), sizeof(IDProperty), idprop->len, 0, NULL);
2669 rna_iterator_array_begin(iter, NULL, sizeof(IDProperty), 0, 0, NULL);
2672 rna_property_collection_get_idp(iter);
2677 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
2678 cprop->begin(iter, ptr);
2682 void RNA_property_collection_next(CollectionPropertyIterator *iter)
2684 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(iter->prop);
2687 rna_iterator_array_next(iter);
2690 rna_property_collection_get_idp(iter);
2696 void RNA_property_collection_end(CollectionPropertyIterator *iter)
2698 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(iter->prop);
2701 rna_iterator_array_end(iter);
2706 int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
2708 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
2711 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2713 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2716 else if (cprop->length) {
2717 return cprop->length(ptr);
2720 CollectionPropertyIterator iter;
2723 RNA_property_collection_begin(ptr, prop, &iter);
2724 for (; iter.valid; RNA_property_collection_next(&iter))
2726 RNA_property_collection_end(&iter);
2732 void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
2735 /* CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop; */
2737 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2739 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2740 IDPropertyTemplate val = {0};
2743 item = IDP_New(IDP_GROUP, &val, "");
2744 IDP_AppendArray(idprop, item);
2745 /* IDP_FreeProperty(item); *//* IDP_AppendArray does a shallow copy (memcpy), only free memory */
2748 else if (prop->flag & PROP_IDPROPERTY) {
2749 IDProperty *group, *item;
2750 IDPropertyTemplate val = {0};
2752 group = RNA_struct_idprops(ptr, 1);
2754 idprop = IDP_NewIDPArray(prop->identifier);
2755 IDP_AddToGroup(group, idprop);
2757 item = IDP_New(IDP_GROUP, &val, "");
2758 IDP_AppendArray(idprop, item);
2759 /* IDP_FreeProperty(item); *//* IDP_AppendArray does a shallow copy (memcpy), only free memory */
2764 /* py api calls directly */
2766 else if (cprop->add) {
2767 if (!(cprop->add->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
2768 ParameterList params;
2769 RNA_parameter_list_create(¶ms, ptr, cprop->add);
2770 RNA_function_call(NULL, NULL, ptr, cprop->add, ¶ms);
2771 RNA_parameter_list_free(¶ms);
2775 printf("%s %s.%s: not implemented for this property.\n", __func__, ptr->type->identifier, prop->identifier);*/
2780 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
2782 r_ptr->data = IDP_GetIndexArray(idprop, idprop->len - 1);
2783 r_ptr->type = cprop->item_type;
2784 rna_pointer_inherit_id(NULL, ptr, r_ptr);
2787 memset(r_ptr, 0, sizeof(*r_ptr));
2791 int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
2794 /* CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop; */
2796 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2798 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2799 IDProperty tmp, *array;
2803 array = IDP_IDPArray(idprop);
2805 if (key >= 0 && key < len) {
2806 if (key + 1 < len) {
2807 /* move element to be removed to the back */
2808 memcpy(&tmp, &array[key], sizeof(IDProperty));
2809 memmove(array + key, array + key + 1, sizeof(IDProperty) * (len - (key + 1)));
2810 memcpy(&array[len - 1], &tmp, sizeof(IDProperty));
2813 IDP_ResizeIDPArray(idprop, len - 1);
2818 else if (prop->flag & PROP_IDPROPERTY)
2821 /* py api calls directly */
2823 else if (cprop->remove) {
2824 if (!(cprop->remove->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
2825 ParameterList params;
2826 RNA_parameter_list_create(¶ms, ptr, cprop->remove);
2827 RNA_function_call(NULL, NULL, ptr, cprop->remove, ¶ms);
2828 RNA_parameter_list_free(¶ms);
2834 printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);*/
2839 int RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos)
2843 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2845 if ((idprop = rna_idproperty_check(&prop, ptr))) {
2846 IDProperty tmp, *array;
2850 array = IDP_IDPArray(idprop);
2852 if (key >= 0 && key < len && pos >= 0 && pos < len && key != pos) {
2853 memcpy(&tmp, &array[key], sizeof(IDProperty));
2855 memmove(array + pos + 1, array + pos, sizeof(IDProperty) * (key - pos));
2857 memmove(array + key, array + key + 1, sizeof(IDProperty) * (pos - key));
2858 memcpy(&array[pos], &tmp, sizeof(IDProperty));
2863 else if (prop->flag & PROP_IDPROPERTY)
2869 void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
2873 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2875 if ((idprop = rna_idproperty_check(&prop, ptr)))
2876 IDP_ResizeIDPArray(idprop, 0);
2879 int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *t_ptr)
2881 CollectionPropertyIterator iter;
2884 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2886 RNA_property_collection_begin(ptr, prop, &iter);
2887 for (index = 0; iter.valid; RNA_property_collection_next(&iter), index++) {
2888 if (iter.ptr.data == t_ptr->data)
2891 RNA_property_collection_end(&iter);
2893 /* did we find it? */
2900 int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
2902 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(prop);
2904 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2906 if (cprop->lookupint) {
2907 /* we have a callback defined, use it */
2908 return cprop->lookupint(ptr, key, r_ptr);
2911 /* no callback defined, just iterate and find the nth item */
2912 CollectionPropertyIterator iter;
2915 RNA_property_collection_begin(ptr, prop, &iter);
2916 for (i = 0; iter.valid; RNA_property_collection_next(&iter), i++) {
2922 RNA_property_collection_end(&iter);
2925 memset(r_ptr, 0, sizeof(*r_ptr));
2931 int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr)
2933 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(prop);
2935 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2937 if (cprop->lookupstring) {
2938 /* we have a callback defined, use it */
2939 return cprop->lookupstring(ptr, key, r_ptr);
2942 /* no callback defined, compare with name properties if they exist */
2943 CollectionPropertyIterator iter;
2944 PropertyRNA *nameprop;
2945 char name[256], *nameptr;
2947 int keylen = strlen(key);
2950 RNA_property_collection_begin(ptr, prop, &iter);
2951 for (; iter.valid; RNA_property_collection_next(&iter)) {
2952 if (iter.ptr.data && iter.ptr.type->nameproperty) {
2953 nameprop = iter.ptr.type->nameproperty;
2955 nameptr = RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name), &namelen);
2957 if ((keylen == namelen) && (strcmp(nameptr, key) == 0)) {
2962 if ((char *)&name != nameptr)
2969 RNA_property_collection_end(&iter);
2972 memset(r_ptr, 0, sizeof(*r_ptr));
2978 /* zero return is an assignment error */
2979 int RNA_property_collection_assign_int(PointerRNA *ptr, PropertyRNA *prop, const int key, const PointerRNA *assign_ptr)
2981 CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(prop);
2983 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2985 if (cprop->assignint) {
2986 /* we have a callback defined, use it */
2987 return cprop->assignint(ptr, key, assign_ptr);
2993 int RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
2995 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
2998 return ((r_ptr->type = rna_ensure_property(prop)->srna) ? 1 : 0);
3001 int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array)
3003 CollectionPropertyIterator iter;
3004 ArrayIterator *internal;
3007 BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
3009 if (!(prop->flag & PROP_RAW_ARRAY) || !(itemprop->flag & PROP_RAW_ACCESS))
3012 RNA_property_collection_begin(ptr, prop, &iter);
3015 /* get data from array iterator and item property */
3016 internal = iter.internal;
3017 arrayp = (iter.valid) ? iter.ptr.data : NULL;
3019 if (internal->skip || !RNA_property_editable(&iter.ptr, itemprop)) {
3020 /* we might skip some items, so it's not a proper array */
3021 RNA_property_collection_end(&iter);
3025 array->array = arrayp + itemprop->rawoffset;
3026 array->stride = internal->itemsize;
3027 array->len = ((char *)internal->endptr - arrayp) / internal->itemsize;
3028 array->type = itemprop->rawtype;
3031 memset(array, 0, sizeof(RawArray));
3033 RNA_property_collection_end(&iter);
3038 #define RAW_GET(dtype, var, raw, a) \
3040 switch (raw.type) { \
3041 case PROP_RAW_CHAR: var = (dtype)((char *)raw.array)[a]; break; \
3042 case PROP_RAW_SHORT: var = (dtype)((short *)raw.array)[a]; break; \
3043 case PROP_RAW_INT: var = (dtype)((int *)raw.array)[a]; break; \
3044 case PROP_RAW_FLOAT: var = (dtype)((float *)raw.array)[a]; break; \
3045 case PROP_RAW_DOUBLE: var = (dtype)((double *)raw.array)[a]; break; \
3046 default: var = (dtype)0; \
3050 #define RAW_SET(dtype, raw, a, var) \
3052 switch (raw.type) { \
3053 case PROP_RAW_CHAR: ((char *)raw.array)[a] = (char)var; break; \
3054 case PROP_RAW_SHORT: ((short *)raw.array)[a] = (short)var; break; \
3055 case PROP_RAW_INT: ((int *)raw.array)[a] = (int)var; break; \
3056 case PROP_RAW_FLOAT: ((float *)raw.array)[a] = (float)var; break; \
3057 case PROP_RAW_DOUBLE: ((double *)raw.array)[a] = (double)var; break; \
3062 int RNA_raw_type_sizeof(RawPropertyType type)
3065 case PROP_RAW_CHAR: return sizeof(char);
3066 case PROP_RAW_SHORT: return sizeof(short);
3067 case PROP_RAW_INT: return sizeof(int);
3068 case PROP_RAW_FLOAT: return sizeof(float);
3069 case PROP_RAW_DOUBLE: return sizeof(double);
3074 static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname,
3075 void *inarray, RawPropertyType intype, int inlen, int set)
3079 PropertyRNA *itemprop, *iprop;
3080 PropertyType itemtype = 0;
3084 /* initialize in array, stride assumed 0 in following code */
3090 ptype = RNA_property_pointer_type(ptr, prop);
3092 /* try to get item property pointer */
3093 RNA_pointer_create(NULL, ptype, NULL, &itemptr);
3094 itemprop = RNA_struct_find_property(&itemptr, propname);
3097 /* we have item property pointer */
3101 itemtype = RNA_property_type(itemprop);
3103 if (!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
3104 BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported");
3108 /* check item array */
3109 itemlen = RNA_property_array_length(&itemptr, itemprop);
3111 /* try to access as raw array */
3112 if (RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
3113 int arraylen = (itemlen == 0) ? 1 : itemlen;
3114 if (in.len != arraylen * out.len) {
3115 BKE_reportf(reports, RPT_ERROR, "Array length mismatch (expected %d, got %d)",
3116 out.len * arraylen, in.len);
3120 /* matching raw types */
3121 if (out.type == in.type) {
3122 void *inp = in.array;
3123 void *outp = out.array;
3126 size = RNA_raw_type_sizeof(out.type) * arraylen;
3128 for (a = 0; a < out.len; a++) {
3129 if (set) memcpy(outp, inp, size);
3130 else memcpy(inp, outp, size);
3132 inp = (char *)inp + size;
3133 outp = (char *)outp + out.stride;
3139 /* could also be faster with non-matching types,
3140 * for now we just do slower loop .. */
3145 void *tmparray = NULL;
3147 int err = 0, j, a = 0;
3150 if (((itemtype == PROP_BOOLEAN || itemtype == PROP_INT) && in.type == PROP_RAW_INT) ||
3151 (itemtype == PROP_FLOAT && in.type == PROP_RAW_FLOAT))
3153 /* avoid creating temporary buffer if the data type match */
3156 /* no item property pointer, can still be id property, or
3157 * property of a type derived from the collection pointer type */
3158 RNA_PROP_BEGIN(ptr, itemptr, prop)
3162 /* we got the property already */
3166 /* not yet, look it up and verify if it is valid */
3167 iprop = RNA_struct_find_property(&itemptr, propname);
3170 itemlen = RNA_property_array_length(&itemptr, iprop);
3171 itemtype = RNA_property_type(iprop);
3174 BKE_reportf(reports, RPT_ERROR, "Property named '%s' not found", propname);
3179 if (!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
3180 BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported");
3186 /* editable check */
3187 if (!set || RNA_property_editable(&itemptr, iprop)) {
3188 if (a + itemlen > in.len) {
3189 BKE_reportf(reports, RPT_ERROR, "Array length mismatch (got %d, expected more)", in.len);
3195 /* handle conversions */
3201 RAW_GET(int, b, in, a);
3202 RNA_property_boolean_set(&itemptr, iprop, b);
3208 RAW_GET(int, i, in, a);
3209 RNA_property_int_set(&itemptr, iprop, i);
3215 RAW_GET(float, f, in, a);
3216 RNA_property_float_set(&itemptr, iprop, f);
3227 int b = RNA_property_boolean_get(&itemptr, iprop);
3228 RAW_SET(int, in, a, b);
3233 int i = RNA_property_int_get(&itemptr, iprop);
3234 RAW_SET(int, in, a, i);