Cleanup: indentation, naming
[blender.git] / source / blender / makesrna / intern / rna_rna.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
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.
8  *
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.
13  *
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.
17  *
18  * Contributor(s): Blender Foundation (2008).
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/makesrna/intern/rna_rna.c
24  *  \ingroup RNA
25  */
26
27 #include <stdlib.h>
28
29 #include "DNA_ID.h"
30
31 #include "BLI_utildefines.h"
32
33 #include "RNA_access.h"
34 #include "RNA_define.h"
35 #include "RNA_enum_types.h"
36
37 #include "rna_internal.h"
38
39 /* -------------------------------------------------------------------- */
40 /** \name Generic Enum's
41  * \{ */
42
43 /* Reuse for dynamic types  */
44 const EnumPropertyItem DummyRNA_NULL_items[] = {
45         {0, NULL, 0, NULL, NULL}
46 };
47
48 /* Reuse for dynamic types with default value */
49 const EnumPropertyItem DummyRNA_DEFAULT_items[] = {
50         {0, "DEFAULT", 0, "Default", ""},
51         {0, NULL, 0, NULL, NULL}
52 };
53
54 /** \} */
55
56 /* -------------------------------------------------------------------- */
57 /** \name RNA Enum's
58  * \{ */
59
60
61 const EnumPropertyItem rna_enum_property_type_items[] = {
62         {PROP_BOOLEAN, "BOOLEAN", 0, "Boolean", ""},
63         {PROP_INT, "INT", 0, "Integer", ""},
64         {PROP_FLOAT, "FLOAT", 0, "Float", ""},
65         {PROP_STRING, "STRING", 0, "String", ""},
66         {PROP_ENUM, "ENUM", 0, "Enumeration", ""},
67         {PROP_POINTER, "POINTER", 0, "Pointer", ""},
68         {PROP_COLLECTION, "COLLECTION", 0, "Collection", ""},
69         {0, NULL, 0, NULL, NULL}
70 };
71
72 /* XXX Keep in sync with bpy_props.c's property_subtype_xxx_items ???
73  *     Currently it is not...
74  */
75 const EnumPropertyItem rna_enum_property_subtype_items[] = {
76         {PROP_NONE, "NONE", 0, "None", ""},
77
78         /* strings */
79         {PROP_FILEPATH, "FILEPATH", 0, "File Path", ""},
80         {PROP_DIRPATH, "DIRPATH", 0, "Directory Path", ""},
81         {PROP_FILENAME, "FILENAME", 0, "File Name", ""},
82         {PROP_PASSWORD, "PASSWORD", 0, "Password", "A string that is displayed hidden ('********')"},
83
84         /* numbers */
85         {PROP_PIXEL, "PIXEL", 0, "Pixel", ""},
86         {PROP_UNSIGNED, "UNSIGNED", 0, "Unsigned", ""},
87         {PROP_PERCENTAGE, "PERCENTAGE", 0, "Percentage", ""},
88         {PROP_FACTOR, "FACTOR", 0, "Factor", ""},
89         {PROP_ANGLE, "ANGLE", 0, "Angle", ""},
90         {PROP_TIME, "TIME", 0, "Time", ""},
91         {PROP_DISTANCE, "DISTANCE", 0, "Distance", ""},
92         {PROP_DISTANCE_CAMERA, "DISTANCE_CAMERA", 0, "Camera Distance", ""},
93
94         /* number arrays */
95         {PROP_COLOR, "COLOR", 0, "Color", ""},
96         {PROP_TRANSLATION, "TRANSLATION", 0, "Translation", ""},
97         {PROP_DIRECTION, "DIRECTION", 0, "Direction", ""},
98         {PROP_VELOCITY, "VELOCITY", 0, "Velocity", ""},
99         {PROP_ACCELERATION, "ACCELERATION", 0, "Acceleration", ""},
100         {PROP_MATRIX, "MATRIX", 0, "Matrix", ""},
101         {PROP_EULER, "EULER", 0, "Euler Angles", ""},
102         {PROP_QUATERNION, "QUATERNION", 0, "Quaternion", ""},
103         {PROP_AXISANGLE, "AXISANGLE", 0, "Axis-Angle", ""},
104         {PROP_XYZ, "XYZ", 0, "XYZ", ""},
105         {PROP_XYZ_LENGTH, "XYZ_LENGTH", 0, "XYZ Length", ""},
106         {PROP_COLOR_GAMMA, "COLOR_GAMMA", 0, "Color", ""},
107         {PROP_COORDS, "COORDS", 0, "Coordinates", ""},
108
109         /* booleans */
110         {PROP_LAYER, "LAYER", 0, "Layer", ""},
111         {PROP_LAYER_MEMBER, "LAYER_MEMBER", 0, "Layer Member", ""},
112         {0, NULL, 0, NULL, NULL}
113 };
114
115 const EnumPropertyItem rna_enum_property_unit_items[] = {
116         {PROP_UNIT_NONE, "NONE", 0, "None", ""},
117         {PROP_UNIT_LENGTH, "LENGTH", 0, "Length", ""},
118         {PROP_UNIT_AREA, "AREA", 0, "Area", ""},
119         {PROP_UNIT_VOLUME, "VOLUME", 0, "Volume", ""},
120         {PROP_UNIT_ROTATION, "ROTATION", 0, "Rotation", ""},
121         {PROP_UNIT_TIME, "TIME", 0, "Time", ""},
122         {PROP_UNIT_VELOCITY, "VELOCITY", 0, "Velocity", ""},
123         {PROP_UNIT_ACCELERATION, "ACCELERATION", 0, "Acceleration", ""},
124         {PROP_UNIT_MASS, "MASS", 0, "Mass", ""},
125         {PROP_UNIT_CAMERA, "CAMERA", 0, "Camera", ""},
126         {0, NULL, 0, NULL, NULL}
127 };
128
129 /** \} */
130
131 #ifdef RNA_RUNTIME
132 #include "MEM_guardedalloc.h"
133 #include "BLI_ghash.h"
134 #include "BLI_string.h"
135
136 #include "BKE_library_override.h"
137
138 /* Struct */
139
140 static void rna_Struct_identifier_get(PointerRNA *ptr, char *value)
141 {
142         strcpy(value, ((StructRNA *)ptr->data)->identifier);
143 }
144
145 static int rna_Struct_identifier_length(PointerRNA *ptr)
146 {
147         return strlen(((StructRNA *)ptr->data)->identifier);
148 }
149
150 static void rna_Struct_description_get(PointerRNA *ptr, char *value)
151 {
152         strcpy(value, ((StructRNA *)ptr->data)->description);
153 }
154
155 static int rna_Struct_description_length(PointerRNA *ptr)
156 {
157         return strlen(((StructRNA *)ptr->data)->description);
158 }
159
160 static void rna_Struct_name_get(PointerRNA *ptr, char *value)
161 {
162         strcpy(value, ((StructRNA *)ptr->data)->name);
163 }
164
165 static int rna_Struct_name_length(PointerRNA *ptr)
166 {
167         return strlen(((StructRNA *)ptr->data)->name);
168 }
169
170 static void rna_Struct_translation_context_get(PointerRNA *ptr, char *value)
171 {
172         strcpy(value, ((StructRNA *)ptr->data)->translation_context);
173 }
174
175 static int rna_Struct_translation_context_length(PointerRNA *ptr)
176 {
177         return strlen(((StructRNA *)ptr->data)->translation_context);
178 }
179
180 static PointerRNA rna_Struct_base_get(PointerRNA *ptr)
181 {
182         return rna_pointer_inherit_refine(ptr, &RNA_Struct, ((StructRNA *)ptr->data)->base);
183 }
184
185 static PointerRNA rna_Struct_nested_get(PointerRNA *ptr)
186 {
187         return rna_pointer_inherit_refine(ptr, &RNA_Struct, ((StructRNA *)ptr->data)->nested);
188 }
189
190 static PointerRNA rna_Struct_name_property_get(PointerRNA *ptr)
191 {
192         return rna_pointer_inherit_refine(ptr, &RNA_Property, ((StructRNA *)ptr->data)->nameproperty);
193 }
194
195 /* Struct property iteration. This is quite complicated, the purpose is to
196  * iterate over properties of all inheritance levels, and for each struct to
197  * also iterator over id properties not known by RNA. */
198
199 static int rna_idproperty_known(CollectionPropertyIterator *iter, void *data)
200 {
201         IDProperty *idprop = (IDProperty *)data;
202         PropertyRNA *prop;
203         StructRNA *ptype = iter->builtin_parent.type;
204
205         /* function to skip any id properties that are already known by RNA,
206          * for the second loop where we go over unknown id properties */
207         do {
208                 for (prop = ptype->cont.properties.first; prop; prop = prop->next)
209                         if ((prop->flag_internal & PROP_INTERN_BUILTIN) == 0 && STREQ(prop->identifier, idprop->name))
210                                 return 1;
211         } while ((ptype = ptype->base));
212
213         return 0;
214 }
215
216 static int rna_property_builtin(CollectionPropertyIterator *UNUSED(iter), void *data)
217 {
218         PropertyRNA *prop = (PropertyRNA *)data;
219
220         /* function to skip builtin rna properties */
221
222         return (prop->flag_internal & PROP_INTERN_BUILTIN);
223 }
224
225 static int rna_function_builtin(CollectionPropertyIterator *UNUSED(iter), void *data)
226 {
227         FunctionRNA *func = (FunctionRNA *)data;
228
229         /* function to skip builtin rna functions */
230
231         return (func->flag & FUNC_BUILTIN);
232 }
233
234 static void rna_inheritance_next_level_restart(CollectionPropertyIterator *iter, IteratorSkipFunc skip, int funcs)
235 {
236         /* RNA struct inheritance */
237         while (!iter->valid && iter->level > 0) {
238                 StructRNA *srna;
239                 int i;
240
241                 srna = (StructRNA *)iter->parent.data;
242                 iter->level--;
243                 for (i = iter->level; i > 0; i--)
244                         srna = srna->base;
245
246                 rna_iterator_listbase_end(iter);
247
248                 if (funcs)
249                         rna_iterator_listbase_begin(iter, &srna->functions, skip);
250                 else
251                         rna_iterator_listbase_begin(iter, &srna->cont.properties, skip);
252         }
253 }
254
255 static void rna_inheritance_properties_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb,
256                                                       IteratorSkipFunc skip)
257 {
258         rna_iterator_listbase_begin(iter, lb, skip);
259         rna_inheritance_next_level_restart(iter, skip, 0);
260 }
261
262 static void rna_inheritance_properties_listbase_next(CollectionPropertyIterator *iter, IteratorSkipFunc skip)
263 {
264         rna_iterator_listbase_next(iter);
265         rna_inheritance_next_level_restart(iter, skip, 0);
266 }
267
268 static void rna_inheritance_functions_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb,
269                                                      IteratorSkipFunc skip)
270 {
271         rna_iterator_listbase_begin(iter, lb, skip);
272         rna_inheritance_next_level_restart(iter, skip, 1);
273 }
274
275 static void rna_inheritance_functions_listbase_next(CollectionPropertyIterator *iter, IteratorSkipFunc skip)
276 {
277         rna_iterator_listbase_next(iter);
278         rna_inheritance_next_level_restart(iter, skip, 1);
279 }
280
281 static void rna_Struct_properties_next(CollectionPropertyIterator *iter)
282 {
283         ListBaseIterator *internal = &iter->internal.listbase;
284         IDProperty *group;
285
286         if (internal->flag) {
287                 /* id properties */
288                 rna_iterator_listbase_next(iter);
289         }
290         else {
291                 /* regular properties */
292                 rna_inheritance_properties_listbase_next(iter, rna_property_builtin);
293
294                 /* try id properties */
295                 if (!iter->valid) {
296                         group = RNA_struct_idprops(&iter->builtin_parent, 0);
297
298                         if (group) {
299                                 rna_iterator_listbase_end(iter);
300                                 rna_iterator_listbase_begin(iter, &group->data.group, rna_idproperty_known);
301                                 internal = &iter->internal.listbase;
302                                 internal->flag = 1;
303                         }
304                 }
305         }
306 }
307
308 static void rna_Struct_properties_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
309 {
310         StructRNA *srna;
311
312         /* here ptr->data should always be the same as iter->parent.type */
313         srna = (StructRNA *)ptr->data;
314
315         while (srna->base) {
316                 iter->level++;
317                 srna = srna->base;
318         }
319
320         rna_inheritance_properties_listbase_begin(iter, &srna->cont.properties, rna_property_builtin);
321 }
322
323 static PointerRNA rna_Struct_properties_get(CollectionPropertyIterator *iter)
324 {
325         ListBaseIterator *internal = &iter->internal.listbase;
326
327         /* we return either PropertyRNA* or IDProperty*, the rna_access.c
328          * functions can handle both as PropertyRNA* with some tricks */
329         return rna_pointer_inherit_refine(&iter->parent, &RNA_Property, internal->link);
330 }
331
332 static void rna_Struct_functions_next(CollectionPropertyIterator *iter)
333 {
334         rna_inheritance_functions_listbase_next(iter, rna_function_builtin);
335 }
336
337 static void rna_Struct_functions_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
338 {
339         StructRNA *srna;
340
341         /* here ptr->data should always be the same as iter->parent.type */
342         srna = (StructRNA *)ptr->data;
343
344         while (srna->base) {
345                 iter->level++;
346                 srna = srna->base;
347         }
348
349         rna_inheritance_functions_listbase_begin(iter, &srna->functions, rna_function_builtin);
350 }
351
352 static PointerRNA rna_Struct_functions_get(CollectionPropertyIterator *iter)
353 {
354         ListBaseIterator *internal = &iter->internal.listbase;
355
356         /* we return either PropertyRNA* or IDProperty*, the rna_access.c
357          * functions can handle both as PropertyRNA* with some tricks */
358         return rna_pointer_inherit_refine(&iter->parent, &RNA_Function, internal->link);
359 }
360
361 static void rna_Struct_property_tags_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
362 {
363         /* here ptr->data should always be the same as iter->parent.type */
364         StructRNA *srna = (StructRNA *)ptr->data;
365         const EnumPropertyItem *tag_defines = RNA_struct_property_tag_defines(srna);
366         unsigned int tag_count = tag_defines ? RNA_enum_items_count(tag_defines) : 0;
367
368         rna_iterator_array_begin(iter, (void *)tag_defines, sizeof(EnumPropertyItem), tag_count, 0, NULL);
369 }
370
371 /* Builtin properties iterator re-uses the Struct properties iterator, only
372  * difference is that we need to set the ptr data to the type of the struct
373  * whose properties we want to iterate over. */
374
375 void rna_builtin_properties_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
376 {
377         PointerRNA newptr;
378
379         /* we create a new pointer with the type as the data */
380         newptr.type = &RNA_Struct;
381         newptr.data = ptr->type;
382
383         if (ptr->type->flag & STRUCT_ID)
384                 newptr.id.data = ptr->data;
385         else
386                 newptr.id.data = NULL;
387
388         iter->parent = newptr;
389         iter->builtin_parent = *ptr;
390
391         rna_Struct_properties_begin(iter, &newptr);
392 }
393
394 void rna_builtin_properties_next(CollectionPropertyIterator *iter)
395 {
396         rna_Struct_properties_next(iter);
397 }
398
399 PointerRNA rna_builtin_properties_get(CollectionPropertyIterator *iter)
400 {
401         return rna_Struct_properties_get(iter);
402 }
403
404 int rna_builtin_properties_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
405 {
406         StructRNA *srna;
407         PropertyRNA *prop;
408         PointerRNA propptr = {{NULL}};
409
410         srna = ptr->type;
411
412         do {
413                 if (srna->cont.prophash) {
414                         prop = BLI_ghash_lookup(srna->cont.prophash, (void *)key);
415
416                         if (prop) {
417                                 propptr.type = &RNA_Property;
418                                 propptr.data = prop;
419
420                                 *r_ptr = propptr;
421                                 return true;
422                         }
423                 }
424                 else {
425                         for (prop = srna->cont.properties.first; prop; prop = prop->next) {
426                                 if (!(prop->flag_internal & PROP_INTERN_BUILTIN) && STREQ(prop->identifier, key)) {
427                                         propptr.type = &RNA_Property;
428                                         propptr.data = prop;
429
430                                         *r_ptr = propptr;
431                                         return true;
432                                 }
433                         }
434                 }
435         } while ((srna = srna->base));
436
437         /* this was used pre 2.5beta0, now ID property access uses python's
438          * getitem style access
439          * - ob["foo"] rather than ob.foo */
440 #if 0
441         if (ptr->data) {
442                 IDProperty *group, *idp;
443
444                 group = RNA_struct_idprops(ptr, 0);
445
446                 if (group) {
447                         for (idp = group->data.group.first; idp; idp = idp->next) {
448                                 if (STREQ(idp->name, key)) {
449                                         propptr.type = &RNA_Property;
450                                         propptr.data = idp;
451
452                                         *r_ptr = propptr;
453                                         return true;
454                                 }
455                         }
456                 }
457         }
458 #endif
459         return false;
460 }
461
462 PointerRNA rna_builtin_type_get(PointerRNA *ptr)
463 {
464         return rna_pointer_inherit_refine(ptr, &RNA_Struct, ptr->type);
465 }
466
467 /* Property */
468
469 static StructRNA *rna_Property_refine(PointerRNA *ptr)
470 {
471         PropertyRNA *prop = (PropertyRNA *)ptr->data;
472
473         rna_idproperty_check(&prop, ptr); /* XXX ptr? */
474
475         switch (prop->type) {
476                 case PROP_BOOLEAN: return &RNA_BoolProperty;
477                 case PROP_INT: return &RNA_IntProperty;
478                 case PROP_FLOAT: return &RNA_FloatProperty;
479                 case PROP_STRING: return &RNA_StringProperty;
480                 case PROP_ENUM: return &RNA_EnumProperty;
481                 case PROP_POINTER: return &RNA_PointerProperty;
482                 case PROP_COLLECTION: return &RNA_CollectionProperty;
483                 default: return &RNA_Property;
484         }
485 }
486
487 static void rna_Property_identifier_get(PointerRNA *ptr, char *value)
488 {
489         PropertyRNA *prop = (PropertyRNA *)ptr->data;
490         rna_idproperty_check(&prop, ptr);
491         strcpy(value, ((PropertyRNA *)prop)->identifier);
492 }
493
494 static int rna_Property_identifier_length(PointerRNA *ptr)
495 {
496         PropertyRNA *prop = (PropertyRNA *)ptr->data;
497         rna_idproperty_check(&prop, ptr);
498         return strlen(prop->identifier);
499 }
500
501 static void rna_Property_name_get(PointerRNA *ptr, char *value)
502 {
503         PropertyRNA *prop = (PropertyRNA *)ptr->data;
504         rna_idproperty_check(&prop, ptr);
505         strcpy(value, prop->name ? prop->name : "");
506 }
507
508 static int rna_Property_name_length(PointerRNA *ptr)
509 {
510         PropertyRNA *prop = (PropertyRNA *)ptr->data;
511         rna_idproperty_check(&prop, ptr);
512         return prop->name ? strlen(prop->name) : 0;
513 }
514
515 static void rna_Property_description_get(PointerRNA *ptr, char *value)
516 {
517         PropertyRNA *prop = (PropertyRNA *)ptr->data;
518         rna_idproperty_check(&prop, ptr);
519         strcpy(value, prop->description ? prop->description : "");
520 }
521 static int rna_Property_description_length(PointerRNA *ptr)
522 {
523         PropertyRNA *prop = (PropertyRNA *)ptr->data;
524         rna_idproperty_check(&prop, ptr);
525         return prop->description ? strlen(prop->description) : 0;
526 }
527
528 static void rna_Property_translation_context_get(PointerRNA *ptr, char *value)
529 {
530         PropertyRNA *prop = (PropertyRNA *)ptr->data;
531         rna_idproperty_check(&prop, ptr);
532         strcpy(value, prop->translation_context);
533 }
534
535 static int rna_Property_translation_context_length(PointerRNA *ptr)
536 {
537         PropertyRNA *prop = (PropertyRNA *)ptr->data;
538         rna_idproperty_check(&prop, ptr);
539         return strlen(prop->translation_context);
540 }
541
542 static int rna_Property_type_get(PointerRNA *ptr)
543 {
544         PropertyRNA *prop = (PropertyRNA *)ptr->data;
545         rna_idproperty_check(&prop, ptr);
546         return prop->type;
547 }
548
549 static int rna_Property_subtype_get(PointerRNA *ptr)
550 {
551         PropertyRNA *prop = (PropertyRNA *)ptr->data;
552         rna_idproperty_check(&prop, ptr);
553         return prop->subtype;
554 }
555
556 static PointerRNA rna_Property_srna_get(PointerRNA *ptr)
557 {
558         PropertyRNA *prop = (PropertyRNA *)ptr->data;
559         rna_idproperty_check(&prop, ptr);
560         return rna_pointer_inherit_refine(ptr, &RNA_Struct, prop->srna);
561 }
562
563 static int rna_Property_unit_get(PointerRNA *ptr)
564 {
565         PropertyRNA *prop = (PropertyRNA *)ptr->data;
566         rna_idproperty_check(&prop, ptr);
567         return RNA_SUBTYPE_UNIT(prop->subtype);
568 }
569
570 static int rna_Property_icon_get(PointerRNA *ptr)
571 {
572         PropertyRNA *prop = (PropertyRNA *)ptr->data;
573         rna_idproperty_check(&prop, ptr);
574         return prop->icon;
575 }
576
577 static bool rna_Property_readonly_get(PointerRNA *ptr)
578 {
579         PropertyRNA *prop = (PropertyRNA *)ptr->data;
580
581         /* don't use this because it will call functions that check the internal
582          * data for introspection we only need to know if it can be edited so the
583          * flag is better for this */
584 /*      return RNA_property_editable(ptr, prop); */
585         return (prop->flag & PROP_EDITABLE) == 0;
586 }
587
588 static bool rna_Property_animatable_get(PointerRNA *ptr)
589 {
590         PropertyRNA *prop = (PropertyRNA *)ptr->data;
591
592         return (prop->flag & PROP_ANIMATABLE) != 0;
593 }
594
595 static bool rna_Property_overridable_get(PointerRNA *ptr)
596 {
597         PropertyRNA *prop = (PropertyRNA *)ptr->data;
598
599         return (prop->flag_override & PROPOVERRIDE_OVERRIDABLE_STATIC) != 0;
600 }
601
602 static bool rna_Property_use_output_get(PointerRNA *ptr)
603 {
604         PropertyRNA *prop = (PropertyRNA *)ptr->data;
605         return (prop->flag_parameter & PARM_OUTPUT) != 0;
606 }
607
608 static bool rna_Property_is_required_get(PointerRNA *ptr)
609 {
610         PropertyRNA *prop = (PropertyRNA *)ptr->data;
611         return (prop->flag_parameter & PARM_REQUIRED) != 0;
612 }
613
614 static bool rna_Property_is_argument_optional_get(PointerRNA *ptr)
615 {
616         PropertyRNA *prop = (PropertyRNA *)ptr->data;
617         return (prop->flag_parameter & PARM_PYFUNC_OPTIONAL) != 0;
618 }
619
620 static bool rna_Property_is_never_none_get(PointerRNA *ptr)
621 {
622         PropertyRNA *prop = (PropertyRNA *)ptr->data;
623         return (prop->flag & PROP_NEVER_NULL) != 0;
624 }
625
626 static bool rna_Property_is_hidden_get(PointerRNA *ptr)
627 {
628         PropertyRNA *prop = (PropertyRNA *)ptr->data;
629         return (prop->flag & PROP_HIDDEN) != 0;
630 }
631
632 static bool rna_Property_is_skip_save_get(PointerRNA *ptr)
633 {
634         PropertyRNA *prop = (PropertyRNA *)ptr->data;
635         return (prop->flag & PROP_SKIP_SAVE) != 0;
636 }
637
638
639 static bool rna_Property_is_enum_flag_get(PointerRNA *ptr)
640 {
641         PropertyRNA *prop = (PropertyRNA *)ptr->data;
642         return (prop->flag & PROP_ENUM_FLAG) != 0;
643 }
644
645 static bool rna_Property_is_library_editable_flag_get(PointerRNA *ptr)
646 {
647         PropertyRNA *prop = (PropertyRNA *)ptr->data;
648         return (prop->flag & PROP_LIB_EXCEPTION) != 0;
649 }
650
651 static int rna_Property_tags_get(PointerRNA *ptr)
652 {
653         return RNA_property_tags(ptr->data);
654 }
655
656 static const EnumPropertyItem *rna_Property_tags_itemf(
657         bContext *UNUSED(C), PointerRNA *ptr,
658         PropertyRNA *UNUSED(prop), bool *r_free)
659 {
660         PropertyRNA *this_prop = (PropertyRNA *)ptr->data;
661         const StructRNA *srna = RNA_property_pointer_type(ptr, this_prop);
662         EnumPropertyItem *prop_tags;
663         EnumPropertyItem tmp = {0, "", 0, "", ""};
664         int totitem = 0;
665
666         for (const EnumPropertyItem *struct_tags = RNA_struct_property_tag_defines(srna);
667              struct_tags != NULL && struct_tags->identifier != NULL;
668              struct_tags++)
669         {
670                 memcpy(&tmp, struct_tags, sizeof(tmp));
671                 RNA_enum_item_add(&prop_tags, &totitem, &tmp);
672         }
673         RNA_enum_item_end(&prop_tags, &totitem);
674         *r_free = true;
675
676         return prop_tags;
677 }
678
679 static int rna_Property_array_length_get(PointerRNA *ptr)
680 {
681         PropertyRNA *prop = (PropertyRNA *)ptr->data;
682         rna_idproperty_check(&prop, ptr);
683         return prop->totarraylength;
684 }
685
686 static void rna_Property_array_dimensions_get(PointerRNA *ptr, int dimensions[RNA_MAX_ARRAY_DIMENSION])
687 {
688         PropertyRNA *prop = (PropertyRNA *)ptr->data;
689         rna_idproperty_check(&prop, ptr);
690
691         if (prop->arraydimension > 1) {
692                 for (int i = RNA_MAX_ARRAY_DIMENSION; i--; ) {
693                         dimensions[i] = (i >= prop->arraydimension) ? 0 : prop->arraylength[i];
694                 }
695         }
696         else {
697                 memset(dimensions, 0, sizeof(*dimensions) * RNA_MAX_ARRAY_DIMENSION);
698                 dimensions[0] = prop->totarraylength;
699         }
700 }
701
702 static bool rna_Property_is_registered_get(PointerRNA *ptr)
703 {
704         PropertyRNA *prop = (PropertyRNA *)ptr->data;
705         return (prop->flag & PROP_REGISTER) != 0;
706 }
707
708 static bool rna_Property_is_registered_optional_get(PointerRNA *ptr)
709 {
710         PropertyRNA *prop = (PropertyRNA *)ptr->data;
711         return (prop->flag & PROP_REGISTER_OPTIONAL) != 0;
712 }
713
714 static bool rna_Property_is_runtime_get(PointerRNA *ptr)
715 {
716         PropertyRNA *prop = (PropertyRNA *)ptr->data;
717         return (prop->flag_internal & PROP_INTERN_RUNTIME) != 0;
718 }
719
720
721 static bool rna_BoolProperty_default_get(PointerRNA *ptr)
722 {
723         PropertyRNA *prop = (PropertyRNA *)ptr->data;
724         rna_idproperty_check(&prop, ptr);
725         return ((BoolPropertyRNA *)prop)->defaultvalue;
726 }
727
728 static int rna_IntProperty_default_get(PointerRNA *ptr)
729 {
730         PropertyRNA *prop = (PropertyRNA *)ptr->data;
731         rna_idproperty_check(&prop, ptr);
732         return ((IntPropertyRNA *)prop)->defaultvalue;
733 }
734 /* int/float/bool */
735 static int rna_NumberProperty_default_array_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
736 {
737         PropertyRNA *prop = (PropertyRNA *)ptr->data;
738         rna_idproperty_check(&prop, ptr);
739
740         length[0] = prop->totarraylength;
741
742         return length[0];
743 }
744 static bool rna_NumberProperty_is_array_get(PointerRNA *ptr)
745 {
746         PropertyRNA *prop = (PropertyRNA *)ptr->data;
747
748         return RNA_property_array_check(prop);
749 }
750
751 static void rna_IntProperty_default_array_get(PointerRNA *ptr, int *values)
752 {
753         PropertyRNA *prop = (PropertyRNA *)ptr->data;
754         rna_idproperty_check(&prop, ptr);
755         if (prop->totarraylength > 0) {
756                 RNA_property_int_get_default_array(ptr, prop, values);
757         }
758 }
759
760 static void rna_BoolProperty_default_array_get(PointerRNA *ptr, bool *values)
761 {
762         PropertyRNA *prop = (PropertyRNA *)ptr->data;
763         rna_idproperty_check(&prop, ptr);
764         if (prop->totarraylength > 0) {
765                 RNA_property_boolean_get_default_array(ptr, prop, values);
766         }
767 }
768
769 static void rna_FloatProperty_default_array_get(PointerRNA *ptr, float *values)
770 {
771         PropertyRNA *prop = (PropertyRNA *)ptr->data;
772         rna_idproperty_check(&prop, ptr);
773         if (prop->totarraylength > 0) {
774                 RNA_property_float_get_default_array(ptr, prop, values);
775         }
776 }
777
778 static int rna_IntProperty_hard_min_get(PointerRNA *ptr)
779 {
780         PropertyRNA *prop = (PropertyRNA *)ptr->data;
781         rna_idproperty_check(&prop, ptr);
782         return ((IntPropertyRNA *)prop)->hardmin;
783 }
784
785 static int rna_IntProperty_hard_max_get(PointerRNA *ptr)
786 {
787         PropertyRNA *prop = (PropertyRNA *)ptr->data;
788         rna_idproperty_check(&prop, ptr);
789         return ((IntPropertyRNA *)prop)->hardmax;
790 }
791
792 static int rna_IntProperty_soft_min_get(PointerRNA *ptr)
793 {
794         PropertyRNA *prop = (PropertyRNA *)ptr->data;
795         rna_idproperty_check(&prop, ptr);
796         return ((IntPropertyRNA *)prop)->softmin;
797 }
798
799 static int rna_IntProperty_soft_max_get(PointerRNA *ptr)
800 {
801         PropertyRNA *prop = (PropertyRNA *)ptr->data;
802         rna_idproperty_check(&prop, ptr);
803         return ((IntPropertyRNA *)prop)->softmax;
804 }
805
806 static int rna_IntProperty_step_get(PointerRNA *ptr)
807 {
808         PropertyRNA *prop = (PropertyRNA *)ptr->data;
809         rna_idproperty_check(&prop, ptr);
810         return ((IntPropertyRNA *)prop)->step;
811 }
812
813 static float rna_FloatProperty_default_get(PointerRNA *ptr)
814 {
815         PropertyRNA *prop = (PropertyRNA *)ptr->data;
816         rna_idproperty_check(&prop, ptr);
817         return ((FloatPropertyRNA *)prop)->defaultvalue;
818 }
819 static float rna_FloatProperty_hard_min_get(PointerRNA *ptr)
820 {
821         PropertyRNA *prop = (PropertyRNA *)ptr->data;
822         rna_idproperty_check(&prop, ptr);
823         return ((FloatPropertyRNA *)prop)->hardmin;
824 }
825
826 static float rna_FloatProperty_hard_max_get(PointerRNA *ptr)
827 {
828         PropertyRNA *prop = (PropertyRNA *)ptr->data;
829         rna_idproperty_check(&prop, ptr);
830         return ((FloatPropertyRNA *)prop)->hardmax;
831 }
832
833 static float rna_FloatProperty_soft_min_get(PointerRNA *ptr)
834 {
835         PropertyRNA *prop = (PropertyRNA *)ptr->data;
836         rna_idproperty_check(&prop, ptr);
837         return ((FloatPropertyRNA *)prop)->softmin;
838 }
839
840 static float rna_FloatProperty_soft_max_get(PointerRNA *ptr)
841 {
842         PropertyRNA *prop = (PropertyRNA *)ptr->data;
843         rna_idproperty_check(&prop, ptr);
844         return ((FloatPropertyRNA *)prop)->softmax;
845 }
846
847 static float rna_FloatProperty_step_get(PointerRNA *ptr)
848 {
849         PropertyRNA *prop = (PropertyRNA *)ptr->data;
850         rna_idproperty_check(&prop, ptr);
851         return ((FloatPropertyRNA *)prop)->step;
852 }
853
854 static int rna_FloatProperty_precision_get(PointerRNA *ptr)
855 {
856         PropertyRNA *prop = (PropertyRNA *)ptr->data;
857         rna_idproperty_check(&prop, ptr);
858         return ((FloatPropertyRNA *)prop)->precision;
859 }
860
861 static void rna_StringProperty_default_get(PointerRNA *ptr, char *value)
862 {
863         PropertyRNA *prop = (PropertyRNA *)ptr->data;
864         rna_idproperty_check(&prop, ptr);
865         strcpy(value, ((StringPropertyRNA *)prop)->defaultvalue);
866 }
867 static int rna_StringProperty_default_length(PointerRNA *ptr)
868 {
869         PropertyRNA *prop = (PropertyRNA *)ptr->data;
870         rna_idproperty_check(&prop, ptr);
871         return strlen(((StringPropertyRNA *)prop)->defaultvalue);
872 }
873
874 static int rna_StringProperty_max_length_get(PointerRNA *ptr)
875 {
876         PropertyRNA *prop = (PropertyRNA *)ptr->data;
877         rna_idproperty_check(&prop, ptr);
878         return ((StringPropertyRNA *)prop)->maxlength;
879 }
880
881 static const EnumPropertyItem *rna_EnumProperty_default_itemf(
882         bContext *C, PointerRNA *ptr,
883         PropertyRNA *prop_parent, bool *r_free)
884 {
885         PropertyRNA *prop = (PropertyRNA *)ptr->data;
886         EnumPropertyRNA *eprop;
887
888         rna_idproperty_check(&prop, ptr);
889         eprop = (EnumPropertyRNA *)prop;
890
891         /* incompatible default attributes */
892         if ((prop_parent->flag & PROP_ENUM_FLAG) != (prop->flag & PROP_ENUM_FLAG)) {
893                 return DummyRNA_NULL_items;
894         }
895
896         if ((eprop->itemf == NULL) ||
897             (eprop->itemf == rna_EnumProperty_default_itemf) ||
898             (ptr->type == &RNA_EnumProperty) ||
899             (C == NULL))
900         {
901                 if (eprop->item) {
902                         return eprop->item;
903                 }
904         }
905
906         return eprop->itemf(C, ptr, prop, r_free);
907 }
908
909 /* XXX - not sure this is needed? */
910 static int rna_EnumProperty_default_get(PointerRNA *ptr)
911 {
912         PropertyRNA *prop = (PropertyRNA *)ptr->data;
913         rna_idproperty_check(&prop, ptr);
914         return ((EnumPropertyRNA *)prop)->defaultvalue;
915 }
916
917 static int rna_enum_check_separator(CollectionPropertyIterator *UNUSED(iter), void *data)
918 {
919         EnumPropertyItem *item = (EnumPropertyItem *)data;
920
921         return (item->identifier[0] == 0);
922 }
923
924 static void rna_EnumProperty_items_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
925 {
926         PropertyRNA *prop = (PropertyRNA *)ptr->data;
927         /* EnumPropertyRNA *eprop;  *//* UNUSED */
928         const EnumPropertyItem *item = NULL;
929         int totitem;
930         bool free;
931
932         rna_idproperty_check(&prop, ptr);
933         /* eprop = (EnumPropertyRNA *)prop; */
934
935         RNA_property_enum_items_ex(
936                     NULL, ptr, prop, STREQ(iter->prop->identifier, "enum_items_static"), &item, &totitem, &free);
937         rna_iterator_array_begin(iter, (void *)item, sizeof(EnumPropertyItem), totitem, free, rna_enum_check_separator);
938 }
939
940 static void rna_EnumPropertyItem_identifier_get(PointerRNA *ptr, char *value)
941 {
942         strcpy(value, ((EnumPropertyItem *)ptr->data)->identifier);
943 }
944
945 static int rna_EnumPropertyItem_identifier_length(PointerRNA *ptr)
946 {
947         return strlen(((EnumPropertyItem *)ptr->data)->identifier);
948 }
949
950 static void rna_EnumPropertyItem_name_get(PointerRNA *ptr, char *value)
951 {
952         strcpy(value, ((EnumPropertyItem *)ptr->data)->name);
953 }
954
955 static int rna_EnumPropertyItem_name_length(PointerRNA *ptr)
956 {
957         return strlen(((EnumPropertyItem *)ptr->data)->name);
958 }
959
960 static void rna_EnumPropertyItem_description_get(PointerRNA *ptr, char *value)
961 {
962         EnumPropertyItem *eprop = (EnumPropertyItem *)ptr->data;
963
964         if (eprop->description)
965                 strcpy(value, eprop->description);
966         else
967                 value[0] = '\0';
968 }
969
970 static int rna_EnumPropertyItem_description_length(PointerRNA *ptr)
971 {
972         EnumPropertyItem *eprop = (EnumPropertyItem *)ptr->data;
973
974         if (eprop->description)
975                 return strlen(eprop->description);
976         else
977                 return 0;
978 }
979
980 static int rna_EnumPropertyItem_value_get(PointerRNA *ptr)
981 {
982         return ((EnumPropertyItem *)ptr->data)->value;
983 }
984
985 static int rna_EnumPropertyItem_icon_get(PointerRNA *ptr)
986 {
987         return ((EnumPropertyItem *)ptr->data)->icon;
988 }
989
990 static PointerRNA rna_PointerProperty_fixed_type_get(PointerRNA *ptr)
991 {
992         PropertyRNA *prop = (PropertyRNA *)ptr->data;
993         rna_idproperty_check(&prop, ptr);
994         return rna_pointer_inherit_refine(ptr, &RNA_Struct, ((PointerPropertyRNA *)prop)->type);
995 }
996
997 static PointerRNA rna_CollectionProperty_fixed_type_get(PointerRNA *ptr)
998 {
999         PropertyRNA *prop = (PropertyRNA *)ptr->data;
1000         rna_idproperty_check(&prop, ptr);
1001         return rna_pointer_inherit_refine(ptr, &RNA_Struct, ((CollectionPropertyRNA *)prop)->item_type);
1002 }
1003
1004 /* Function */
1005
1006 static void rna_Function_identifier_get(PointerRNA *ptr, char *value)
1007 {
1008         strcpy(value, ((FunctionRNA *)ptr->data)->identifier);
1009 }
1010
1011 static int rna_Function_identifier_length(PointerRNA *ptr)
1012 {
1013         return strlen(((FunctionRNA *)ptr->data)->identifier);
1014 }
1015
1016 static void rna_Function_description_get(PointerRNA *ptr, char *value)
1017 {
1018         strcpy(value, ((FunctionRNA *)ptr->data)->description);
1019 }
1020
1021 static int rna_Function_description_length(PointerRNA *ptr)
1022 {
1023         return strlen(((FunctionRNA *)ptr->data)->description);
1024 }
1025
1026 static void rna_Function_parameters_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1027 {
1028         rna_iterator_listbase_begin(iter, &((FunctionRNA *)ptr->data)->cont.properties, rna_property_builtin);
1029 }
1030
1031 static bool rna_Function_registered_get(PointerRNA *ptr)
1032 {
1033         FunctionRNA *func = (FunctionRNA *)ptr->data;
1034         return 0 != (func->flag & FUNC_REGISTER);
1035 }
1036
1037 static bool rna_Function_registered_optional_get(PointerRNA *ptr)
1038 {
1039         FunctionRNA *func = (FunctionRNA *)ptr->data;
1040         return 0 != (func->flag & (FUNC_REGISTER_OPTIONAL & ~FUNC_REGISTER));
1041 }
1042
1043 static bool rna_Function_no_self_get(PointerRNA *ptr)
1044 {
1045         FunctionRNA *func = (FunctionRNA *)ptr->data;
1046         return !(func->flag & FUNC_NO_SELF);
1047 }
1048
1049 static int rna_Function_use_self_type_get(PointerRNA *ptr)
1050 {
1051         FunctionRNA *func = (FunctionRNA *)ptr->data;
1052         return 0 != (func->flag & FUNC_USE_SELF_TYPE);
1053 }
1054
1055 /* Blender RNA */
1056
1057 static int rna_struct_is_publc(CollectionPropertyIterator *UNUSED(iter), void *data)
1058 {
1059         StructRNA *srna = data;
1060
1061         return !(srna->flag & STRUCT_PUBLIC_NAMESPACE);
1062 }
1063
1064
1065 static void rna_BlenderRNA_structs_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1066 {
1067         BlenderRNA *brna = ptr->data;
1068         rna_iterator_listbase_begin(iter, &brna->structs, rna_struct_is_publc);
1069 }
1070
1071 /* optional, for faster lookups */
1072 static int rna_BlenderRNA_structs_length(PointerRNA *ptr)
1073 {
1074         BlenderRNA *brna = ptr->data;
1075         BLI_assert(brna->structs_len == BLI_listbase_count(&brna->structs));
1076         return brna->structs_len;
1077 }
1078 static int rna_BlenderRNA_structs_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
1079 {
1080         BlenderRNA *brna = ptr->data;
1081         StructRNA *srna = index < brna->structs_len ? BLI_findlink(&brna->structs, index) : NULL;
1082         if (srna != NULL) {
1083                 RNA_pointer_create(NULL, &RNA_Struct, srna, r_ptr);
1084                 return true;
1085         }
1086         else {
1087                 return false;
1088         }
1089 }
1090 static int rna_BlenderRNA_structs_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
1091 {
1092         BlenderRNA *brna = ptr->data;
1093         StructRNA *srna = BLI_ghash_lookup(brna->structs_map, (void *)key);
1094         if (srna != NULL) {
1095                 RNA_pointer_create(NULL, &RNA_Struct, srna, r_ptr);
1096                 return true;
1097         }
1098
1099         return false;
1100 }
1101
1102 /* Default override (and compare) callbacks. */
1103
1104 /* Ensures it makes sense to go inside the pointers to compare their content
1105  * (if they are IDs, or have different names or RNA type, then this would be meaningless). */
1106 static bool rna_property_override_diff_propptr_validate_diffing(
1107         PointerRNA *propptr_a, PointerRNA *propptr_b, const bool no_prop_name,
1108         bool *r_is_id, bool *r_is_null, bool *r_is_type_diff,
1109         char **r_propname_a, char *propname_a_buff, size_t propname_a_buff_size,
1110         char **r_propname_b, char *propname_b_buff, size_t propname_b_buff_size)
1111 {
1112         BLI_assert(propptr_a != NULL);
1113
1114         bool is_valid_for_diffing = true;
1115         const bool do_force_name = !no_prop_name && r_propname_a != NULL;
1116
1117         if (do_force_name) {
1118                 BLI_assert(r_propname_a != NULL);
1119                 BLI_assert(r_propname_b != NULL);
1120         }
1121
1122         *r_is_id = *r_is_null = *r_is_type_diff = false;
1123
1124         /* Beware, PointerRNA_NULL has no type and is considered a 'blank page'! */
1125         if (propptr_a->type == NULL) {
1126                 if (propptr_b == NULL || propptr_b->type == NULL) {
1127                         *r_is_null = true;
1128                 }
1129                 else {
1130                         *r_is_id = RNA_struct_is_ID(propptr_b->type);
1131                         *r_is_null = true;
1132                         *r_is_type_diff = true;
1133                 }
1134                 is_valid_for_diffing = false;
1135         }
1136         else {
1137                 *r_is_id = RNA_struct_is_ID(propptr_a->type);
1138                 *r_is_null = *r_is_type_diff = (ELEM(NULL, propptr_b, propptr_b->type));
1139                 is_valid_for_diffing = !(*r_is_id || *r_is_null);
1140         }
1141
1142         if (propptr_b == NULL || propptr_a->type != propptr_b->type) {
1143                 *r_is_type_diff = true;
1144                 is_valid_for_diffing = false;
1145 //              printf("%s: different pointer RNA types\n", rna_path ? rna_path : "<UNKNOWN>");
1146         }
1147
1148         /* We do a generic quick first comparison checking for "name" and/or "type" properties.
1149          * We assume that is any of those are false, then we are not handling the same data.
1150          * This helps a lot in static override case, especially to detect inserted items in collections. */
1151         if (!no_prop_name && (is_valid_for_diffing || do_force_name)) {
1152                 PropertyRNA *nameprop_a = RNA_struct_name_property(propptr_a->type);
1153                 PropertyRNA *nameprop_b = (propptr_b != NULL) ? RNA_struct_name_property(propptr_b->type) : NULL;
1154
1155                 int propname_a_len = 0, propname_b_len = 0;
1156                 char *propname_a = NULL;
1157                 char *propname_b = NULL;
1158                 char buff_a[4096];
1159                 char buff_b[4096];
1160                 if (nameprop_a != NULL) {
1161                         if (r_propname_a == NULL && propname_a_buff == NULL) {
1162                                 propname_a_buff = buff_a;
1163                                 propname_a_buff_size = sizeof(buff_a);
1164                         }
1165
1166                         propname_a = RNA_property_string_get_alloc(
1167                                          propptr_a, nameprop_a, propname_a_buff, propname_a_buff_size, &propname_a_len);
1168 //                      printf("propname_a = %s\n", propname_a ? propname_a : "<NONE>");
1169
1170                         if (r_propname_a != NULL) {
1171                                 *r_propname_a = propname_a;
1172                         }
1173                 }
1174 //              else printf("item of type %s a has no name property!\n", propptr_a->type->name);
1175                 if (nameprop_b != NULL) {
1176                         if (r_propname_b == NULL && propname_b_buff == NULL) {
1177                                 propname_b_buff = buff_b;
1178                                 propname_b_buff_size = sizeof(buff_b);
1179                         }
1180
1181                         propname_b = RNA_property_string_get_alloc(
1182                                          propptr_b, nameprop_b, propname_b_buff, propname_b_buff_size, &propname_b_len);
1183
1184                         if (r_propname_b != NULL) {
1185                                 *r_propname_b = propname_b;
1186                         }
1187                 }
1188                 if (propname_a != NULL && propname_b != NULL) {
1189                         if (propname_a_len != propname_b_len ||
1190                             propname_a[0] != propname_b[0] ||
1191                             !STREQ(propname_a, propname_b))
1192                         {
1193                                 is_valid_for_diffing = false;
1194 //                              printf("%s: different names\n", rna_path ? rna_path : "<UNKNOWN>");
1195                         }
1196                 }
1197         }
1198
1199         if (*r_is_id) {
1200                 BLI_assert(propptr_a->data == propptr_a->id.data && propptr_b->data == propptr_b->id.data);
1201         }
1202
1203         return is_valid_for_diffing;
1204 }
1205
1206 /* Used for both Pointer and Collection properties. */
1207 static int rna_property_override_diff_propptr(
1208         Main *bmain,
1209         PointerRNA *propptr_a, PointerRNA *propptr_b,
1210         eRNACompareMode mode, const bool no_ownership, const bool no_prop_name,
1211         IDOverrideStatic *override, const char *rna_path, const int flags, bool *r_override_changed)
1212 {
1213         const bool do_create = override != NULL && (flags & RNA_OVERRIDE_COMPARE_CREATE) != 0 && rna_path != NULL;
1214
1215         bool is_id = false;
1216         bool is_null = false;
1217         bool is_type_diff = false;
1218         /* If false, it means that the whole data itself is different, so no point in going inside of it at all! */
1219         bool is_valid_for_diffing = rna_property_override_diff_propptr_validate_diffing(
1220                                         propptr_a, propptr_b, no_prop_name, &is_id, &is_null, &is_type_diff,
1221                                         NULL, NULL, 0, NULL, NULL, 0);
1222
1223         if (is_id) {
1224                 BLI_assert(no_ownership);  /* For now, once we deal with nodetrees we'll want to get rid of that one. */
1225         }
1226
1227         if (override) {
1228                 if (no_ownership /* || is_id */ || is_null || is_type_diff || !is_valid_for_diffing) {
1229                         /* In case this pointer prop does not own its data (or one is NULL), do not compare structs!
1230                          * This is a quite safe path to infinite loop, among other nasty issues.
1231                          * Instead, just compare pointers themselves. */
1232                         const int comp = (propptr_a->data != propptr_b->data);
1233
1234                         if (do_create && comp != 0) {
1235                                 bool created = false;
1236                                 IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1237
1238                                 if (op != NULL && created) {  /* If not yet overridden... */
1239                                         BKE_override_static_property_operation_get(
1240                                                     op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
1241                                         if (r_override_changed) {
1242                                                 *r_override_changed = created;
1243                                         }
1244                                 }
1245                         }
1246
1247                         return comp;
1248                 }
1249                 else {
1250                         eRNAOverrideMatchResult report_flags = 0;
1251                         const bool match = RNA_struct_override_matches(
1252                                                bmain, propptr_a, propptr_b, rna_path, override, flags, &report_flags);
1253                         if (r_override_changed && (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) != 0) {
1254                                 *r_override_changed = true;
1255                         }
1256                         return !match;
1257                 }
1258         }
1259         else {
1260                 /* We could also use is_diff_pointer, but then we potentially lose the gt/lt info -
1261                  * and don't think performances are critical here for now anyway... */
1262                 return !RNA_struct_equals(bmain, propptr_a, propptr_b, mode);
1263         }
1264 }
1265
1266
1267
1268 #define RNA_PROPERTY_GET_SINGLE(_typename, _ptr, _prop, _index) \
1269         (is_array ? RNA_property_##_typename##_get_index((_ptr), (_prop), (_index)) : \
1270                     RNA_property_##_typename##_get((_ptr), (_prop)))
1271 #define RNA_PROPERTY_SET_SINGLE(_typename, _ptr, _prop, _index, _value) \
1272         (is_array ? RNA_property_##_typename##_set_index((_ptr), (_prop), (_index), (_value)) : \
1273                     RNA_property_##_typename##_set((_ptr), (_prop), (_value)))
1274
1275 int rna_property_override_diff_default(
1276         Main *bmain,
1277         PointerRNA *ptr_a, PointerRNA *ptr_b,
1278         PropertyRNA *prop_a, PropertyRNA *prop_b,
1279         const int len_a, const int len_b,
1280         const int mode,
1281         IDOverrideStatic *override, const char *rna_path,
1282         const int flags, bool *r_override_changed)
1283 {
1284         BLI_assert(len_a == len_b);
1285
1286         /* Note: at this point, we are sure that when len_a is zero, we are not handling an (empty) array. */
1287
1288         const bool do_create = override != NULL && (flags & RNA_OVERRIDE_COMPARE_CREATE) != 0 && rna_path != NULL;
1289
1290         switch (RNA_property_type(prop_a)) {
1291                 case PROP_BOOLEAN:
1292                 {
1293                         if (len_a) {
1294                                 bool array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
1295                                 bool *array_a, *array_b;
1296
1297                                 array_a = (len_a > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(bool) * len_a, "RNA equals") : array_stack_a;
1298                                 array_b = (len_b > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(bool) * len_b, "RNA equals") : array_stack_b;
1299
1300                                 RNA_property_boolean_get_array(ptr_a, prop_a, array_a);
1301                                 RNA_property_boolean_get_array(ptr_b, prop_b, array_b);
1302
1303                                 const int comp = memcmp(array_a, array_b, sizeof(bool) * len_a);
1304
1305                                 if (do_create && comp != 0) {
1306                                         /* XXX TODO this will have to be refined to handle array items */
1307                                         bool created = false;
1308                                         IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1309
1310                                         if (op != NULL && created) {
1311                                                 BKE_override_static_property_operation_get(
1312                                                             op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
1313                                                 if (r_override_changed) {
1314                                                         *r_override_changed = created;
1315                                                 }
1316                                         }
1317                                         else {
1318                                                 /* Already overridden prop, we'll have to check arrays items etc. */
1319                                         }
1320                                 }
1321
1322                                 if (array_a != array_stack_a) MEM_freeN(array_a);
1323                                 if (array_b != array_stack_b) MEM_freeN(array_b);
1324
1325                                 return comp;
1326                         }
1327                         else {
1328                                 const bool value_a = RNA_property_boolean_get(ptr_a, prop_a);
1329                                 const bool value_b = RNA_property_boolean_get(ptr_b, prop_b);
1330                                 const int comp = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0;
1331
1332                                 if (do_create && comp != 0) {
1333                                         bool created = false;
1334                                         IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1335
1336                                         if (op != NULL && created) {  /* If not yet overridden... */
1337                                                 BKE_override_static_property_operation_get(
1338                                                             op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
1339                                                 if (r_override_changed) {
1340                                                         *r_override_changed = created;
1341                                                 }
1342                                         }
1343                                 }
1344
1345                                 return comp;
1346                         }
1347                 }
1348
1349                 case PROP_INT:
1350                 {
1351                         if (len_a) {
1352                                 int array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
1353                                 int *array_a, *array_b;
1354
1355                                 array_a = (len_a > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(int) * len_a, "RNA equals") : array_stack_a;
1356                                 array_b = (len_b > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(int) * len_b, "RNA equals") : array_stack_b;
1357
1358                                 RNA_property_int_get_array(ptr_a, prop_a, array_a);
1359                                 RNA_property_int_get_array(ptr_b, prop_b, array_b);
1360
1361                                 const int comp = memcmp(array_a, array_b, sizeof(int) * len_a);
1362
1363                                 if (do_create && comp != 0) {
1364                                         /* XXX TODO this will have to be refined to handle array items */
1365                                         bool created = false;
1366                                         IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1367
1368                                         if (op != NULL && created) {
1369                                                 BKE_override_static_property_operation_get(
1370                                                             op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
1371                                                 if (r_override_changed) {
1372                                                         *r_override_changed = created;
1373                                                 }
1374                                         }
1375                                         else {
1376                                                 /* Already overridden prop, we'll have to check arrays items etc. */
1377                                         }
1378                                 }
1379
1380                                 if (array_a != array_stack_a) MEM_freeN(array_a);
1381                                 if (array_b != array_stack_b) MEM_freeN(array_b);
1382
1383                                 return comp;
1384                         }
1385                         else {
1386                                 const int value_a = RNA_property_int_get(ptr_a, prop_a);
1387                                 const int value_b = RNA_property_int_get(ptr_b, prop_b);
1388                                 const int comp = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0;
1389
1390                                 if (do_create && comp != 0) {
1391                                         bool created = false;
1392                                         IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1393
1394                                         if (op != NULL && created) {  /* If not yet overridden... */
1395                                                 BKE_override_static_property_operation_get(
1396                                                             op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
1397                                                 if (r_override_changed) {
1398                                                         *r_override_changed = created;
1399                                                 }
1400                                         }
1401                                 }
1402
1403                                 return comp;
1404                         }
1405                 }
1406
1407                 case PROP_FLOAT:
1408                 {
1409                         if (len_a) {
1410                                 float array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
1411                                 float *array_a, *array_b;
1412
1413                                 array_a = (len_a > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(float) * len_a, "RNA equals") : array_stack_a;
1414                                 array_b = (len_b > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(float) * len_b, "RNA equals") : array_stack_b;
1415
1416                                 RNA_property_float_get_array(ptr_a, prop_a, array_a);
1417                                 RNA_property_float_get_array(ptr_b, prop_b, array_b);
1418
1419                                 const int comp = memcmp(array_a, array_b, sizeof(float) * len_a);
1420
1421                                 if (do_create && comp != 0) {
1422                                         /* XXX TODO this will have to be refined to handle array items */
1423                                         bool created = false;
1424                                         IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1425
1426                                         if (op != NULL && created) {
1427                                                 BKE_override_static_property_operation_get(
1428                                                             op, IDOVERRIDESTATIC_OP_REPLACE,
1429                                                             NULL, NULL, -1, -1, true, NULL, NULL);
1430                                                 if (r_override_changed) {
1431                                                         *r_override_changed = created;
1432                                                 }
1433                                         }
1434                                         else {
1435                                                 /* Already overridden prop, we'll have to check arrays items etc. */
1436                                         }
1437                                 }
1438
1439                                 if (array_a != array_stack_a) MEM_freeN(array_a);
1440                                 if (array_b != array_stack_b) MEM_freeN(array_b);
1441
1442                                 return comp;
1443                         }
1444                         else {
1445                                 const float value_a = RNA_property_float_get(ptr_a, prop_a);
1446                                 const float value_b = RNA_property_float_get(ptr_b, prop_b);
1447                                 const int comp = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0;
1448
1449                                 if (do_create && comp != 0) {
1450                                         bool created = false;
1451                                         IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1452
1453                                         if (op != NULL && created) {  /* If not yet overridden... */
1454                                                 BKE_override_static_property_operation_get(
1455                                                             op, IDOVERRIDESTATIC_OP_REPLACE,
1456                                                             NULL, NULL, -1, -1, true, NULL, NULL);
1457                                                 if (r_override_changed) {
1458                                                         *r_override_changed = created;
1459                                                 }
1460                                         }
1461                                 }
1462
1463                                 return comp ;
1464                         }
1465                 }
1466
1467                 case PROP_ENUM:
1468                 {
1469                         const int value_a = RNA_property_enum_get(ptr_a, prop_a);
1470                         const int value_b = RNA_property_enum_get(ptr_b, prop_b);
1471                         const int comp = value_a != value_b;
1472
1473                         if (do_create && comp != 0) {
1474                                 bool created = false;
1475                                 IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1476
1477                                 if (op != NULL && created) {  /* If not yet overridden... */
1478                                         BKE_override_static_property_operation_get(
1479                                                     op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
1480                                         if (r_override_changed) {
1481                                                 *r_override_changed = created;
1482                                         }
1483                                 }
1484                         }
1485
1486                         return comp;
1487                 }
1488
1489                 case PROP_STRING:
1490                 {
1491                         char fixed_a[4096], fixed_b[4096];
1492                         int len_str_a, len_str_b;
1493                         char *value_a = RNA_property_string_get_alloc(ptr_a, prop_a, fixed_a, sizeof(fixed_a), &len_str_a);
1494                         char *value_b = RNA_property_string_get_alloc(ptr_b, prop_b, fixed_b, sizeof(fixed_b), &len_str_b);
1495                         /* TODO we could do a check on length too, but then we would not have a 'real' string comparison...
1496                          * Maybe behind a eRNAOverrideMatch flag? */
1497 //                      const int comp = len_str_a < len_str_b ? -1 : len_str_a > len_str_b ? 1 : strcmp(value_a, value_b);
1498                         const int comp = strcmp(value_a, value_b);
1499
1500                         if (do_create && comp != 0) {
1501                                 bool created = false;
1502                                 IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1503
1504                                 if (op != NULL && created) {  /* If not yet overridden... */
1505                                         BKE_override_static_property_operation_get(
1506                                                     op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
1507                                         if (r_override_changed) {
1508                                                 *r_override_changed = created;
1509                                         }
1510                                 }
1511                         }
1512
1513                         if (value_a != fixed_a) MEM_freeN(value_a);
1514                         if (value_b != fixed_b) MEM_freeN(value_b);
1515
1516                         return comp;
1517                 }
1518
1519                 case PROP_POINTER:
1520                 {
1521                         if (STREQ(RNA_property_identifier(prop_a), "rna_type")) {
1522                                 /* Dummy 'pass' answer, this is a meta-data and must be ignored... */
1523                                 return 0;
1524                         }
1525                         else {
1526                                 PointerRNA propptr_a = RNA_property_pointer_get(ptr_a, prop_a);
1527                                 PointerRNA propptr_b = RNA_property_pointer_get(ptr_b, prop_b);
1528                                 const bool no_ownership = (RNA_property_flag(prop_a) & PROP_PTR_NO_OWNERSHIP) != 0;
1529                                 const bool no_prop_name = (RNA_property_override_flag(prop_a) & PROPOVERRIDE_NO_PROP_NAME) != 0;
1530                                 return rna_property_override_diff_propptr(
1531                                             bmain,
1532                                             &propptr_a, &propptr_b, mode, no_ownership, no_prop_name,
1533                                             override, rna_path, flags, r_override_changed);
1534                         }
1535                         break;
1536                 }
1537
1538                 case PROP_COLLECTION:
1539                 {
1540                         /* Note: we assume we only insert in ptr_a (i.e. we can only get new items in ptr_a),
1541                          * and that we never remove anything. */
1542                         const bool use_insertion = (RNA_property_override_flag(prop_a) & PROPOVERRIDE_STATIC_INSERTION) && do_create;
1543                         const bool no_prop_name = (RNA_property_override_flag(prop_a) & PROPOVERRIDE_NO_PROP_NAME) != 0;
1544                         bool equals = true;
1545                         bool abort = false;
1546                         bool is_first_insert = true;
1547                         int idx_a = 0;
1548                         int idx_b = 0;
1549
1550 #define RNA_PATH_BUFFSIZE 8192
1551
1552                         char extended_rna_path_buffer[RNA_PATH_BUFFSIZE];
1553                         char *extended_rna_path = extended_rna_path_buffer;
1554
1555 #define RNA_PATH_PRINTF(_str, ...) \
1556                         if (BLI_snprintf(extended_rna_path_buffer, RNA_PATH_BUFFSIZE, \
1557                                          (_str), __VA_ARGS__) >= RNA_PATH_BUFFSIZE - 1) \
1558                         { extended_rna_path = BLI_sprintfN((_str), __VA_ARGS__); }(void)0
1559 #define RNA_PATH_FREE() \
1560                         if (extended_rna_path != extended_rna_path_buffer) MEM_freeN(extended_rna_path)
1561
1562                         CollectionPropertyIterator iter_a, iter_b;
1563                         RNA_property_collection_begin(ptr_a, prop_a, &iter_a);
1564                         RNA_property_collection_begin(ptr_b, prop_b, &iter_b);
1565
1566                         char buff_a[4096];
1567                         char buff_prev_a[4096] = {0};
1568                         char buff_b[4096];
1569                         char *propname_a = NULL;
1570                         char *prev_propname_a = buff_prev_a;
1571                         char *propname_b = NULL;
1572
1573                         for (; iter_a.valid && !abort; ) {
1574                                 bool is_valid_for_diffing;
1575                                 bool is_valid_for_insertion;
1576                                 do {
1577                                         bool is_id = false, is_null = false, is_type_diff = false;
1578
1579                                         is_valid_for_insertion = use_insertion;
1580
1581                                         /* If false, it means that the whole data itself is different, so no point in going inside of it at all! */
1582                                         if (iter_b.valid) {
1583                                                 is_valid_for_diffing = rna_property_override_diff_propptr_validate_diffing(
1584                                                                            &iter_a.ptr, &iter_b.ptr, no_prop_name,
1585                                                                            &is_id, &is_null, &is_type_diff,
1586                                                                            &propname_a, buff_a, sizeof(buff_a),
1587                                                                            &propname_b, buff_b, sizeof(buff_b));
1588                                         }
1589                                         else {
1590                                                 is_valid_for_diffing = false;
1591                                                 if (is_valid_for_insertion) {
1592                                                         /* We still need propname from 'a' item... */
1593                                                         rna_property_override_diff_propptr_validate_diffing(
1594                                                                     &iter_a.ptr, NULL, no_prop_name,
1595                                                                     &is_id, &is_null, &is_type_diff,
1596                                                                     &propname_a, buff_a, sizeof(buff_a),
1597                                                                     &propname_b, buff_b, sizeof(buff_b));
1598                                                 }
1599                                         }
1600
1601                                         /* We do not support insertion of IDs for now, neither handle NULL pointers. */
1602                                         if (is_id || is_valid_for_diffing) {
1603                                                 is_valid_for_insertion = false;
1604                                         }
1605
1606 #if 0
1607                                         if (rna_path) {
1608                                                 printf("Checking %s, %s [%d] vs %s [%d]; is_id: %d, diffing: %d; "
1609                                                        "insert: %d (could be used: %d, do_create: %d)\n",
1610                                                        rna_path, propname_a ? propname_a : "", idx_a, propname_b ? propname_b : "", idx_b,
1611                                                        is_id, is_valid_for_diffing, is_valid_for_insertion,
1612                                                        (RNA_property_override_flag(prop_a) & PROPOVERRIDE_STATIC_INSERTION) != 0, do_create);
1613                                         }
1614 #endif
1615
1616                                         if (!(is_id || is_valid_for_diffing || is_valid_for_insertion)) {
1617                                                 /* Differences we cannot handle, we can break here
1618                                                  * (we do not support replacing ID pointers in collections e.g.). */
1619                                                 equals = false;
1620                                                 abort = true;
1621                                                 break;
1622                                         }
1623
1624                                         /* There may be a propname defined in some cases, while no actual name set
1625                                          * (e.g. happens with point cache), in that case too we want to fall back to index.
1626                                          * Note that we do not need the RNA path for insertion operations. */
1627                                         if (is_id || is_valid_for_diffing) {
1628                                                 if ((propname_a != NULL && propname_a[0] != '\0') &&
1629                                                     (propname_b != NULL && propname_b[0] != '\0'))
1630                                                 {
1631                                                         if (rna_path) {
1632                                                                 /* In case of name, either it is valid for diffing, and _a and _b are identical,
1633                                                                  * or it is valid for insertion, and we need to use _a. */
1634                                                                 char esc_item_name[RNA_PATH_BUFFSIZE];
1635                                                                 BLI_strescape(esc_item_name, propname_a, RNA_PATH_BUFFSIZE);
1636                                                                 RNA_PATH_PRINTF("%s[\"%s\"]", rna_path, esc_item_name);
1637                                                         }
1638                                                 }
1639                                                 else {  /* Based on index... */
1640                                                         if (rna_path) {
1641                                                                 /* In case of indices, we need _a one for insertion, but _b ones for in-depth diffing.
1642                                                                  * Insertion always happen once all 'replace' operations have been done,
1643                                                                  * otherwise local and reference paths for those would have to be different! */
1644                                                                 RNA_PATH_PRINTF("%s[%d]", rna_path, is_valid_for_insertion ? idx_a : idx_b);
1645                                                         }
1646                                                 }
1647                                         }
1648
1649                                         /* Collections do not support replacement of their data (since they do not support removing),
1650                                          * only in *some* cases, insertion.
1651                                          * We also assume then that _a data is the one where things are inserted. */
1652                                         if (is_valid_for_insertion && use_insertion) {
1653                                                 bool created;
1654                                                 IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1655
1656                                                 if (is_first_insert) {
1657                                                         /* We need to clean up all possible existing insertion operations, otherwise we'd end up
1658                                                          * with a mess of ops everytime something changes. */
1659                                                         for (IDOverrideStaticPropertyOperation *opop = op->operations.first;
1660                                                              opop != NULL;)
1661                                                         {
1662                                                                 IDOverrideStaticPropertyOperation *opop_next = opop->next;
1663                                                                 if (ELEM(opop->operation,
1664                                                                          IDOVERRIDESTATIC_OP_INSERT_AFTER, IDOVERRIDESTATIC_OP_INSERT_BEFORE))
1665                                                                 {
1666                                                                         BKE_override_static_property_operation_delete(op, opop);
1667                                                                 }
1668                                                                 opop = opop_next;
1669                                                         }
1670                                                         is_first_insert = false;
1671                                                 }
1672
1673                                                 BKE_override_static_property_operation_get(
1674                                                             op, IDOVERRIDESTATIC_OP_INSERT_AFTER,
1675                                                             NULL, prev_propname_a, -1, idx_a - 1, true, NULL, NULL);
1676 //                                              printf("%s: Adding insertion op override after '%s'/%d\n", rna_path, prev_propname_a, idx_a - 1);
1677                                         }
1678                                         else if (is_id || is_valid_for_diffing) {
1679                                                 if (equals || do_create) {
1680                                                         const bool no_ownership = (RNA_property_flag(prop_a) & PROP_PTR_NO_OWNERSHIP) != 0;
1681                                                         const int eq = rna_property_override_diff_propptr(
1682                                                                            bmain,
1683                                                                            &iter_a.ptr, &iter_b.ptr, mode, no_ownership, no_prop_name,
1684                                                                            override, extended_rna_path, flags, r_override_changed);
1685                                                         equals = equals && eq;
1686                                                 }
1687                                         }
1688
1689                                         if (prev_propname_a != buff_prev_a) {
1690                                                 MEM_freeN(prev_propname_a);
1691                                                 prev_propname_a = buff_prev_a;
1692                                         }
1693                                         prev_propname_a[0] = '\0';
1694                                         if (propname_a != NULL &&
1695                                             BLI_strncpy_rlen(prev_propname_a, propname_a, sizeof(buff_prev_a)) >= sizeof(buff_prev_a) - 1)
1696                                         {
1697                                                 prev_propname_a = BLI_strdup(propname_a);
1698                                         }
1699                                         if (propname_a != buff_a) {
1700                                                 MEM_SAFE_FREE(propname_a);
1701                                                 propname_a = buff_a;
1702                                         }
1703                                         propname_a[0] = '\0';
1704                                         if (propname_b != buff_b) {
1705                                                 MEM_SAFE_FREE(propname_b);
1706                                                 propname_b = buff_b;
1707                                         }
1708                                         propname_b[0] = '\0';
1709                                         RNA_PATH_FREE();
1710
1711                                         if (!do_create && !equals) {
1712                                                 abort = true;  /* Early out in case we do not want to loop over whole collection. */
1713                                                 break;
1714                                         }
1715
1716                                         if (!(use_insertion && !(is_id || is_valid_for_diffing))) {
1717                                                 break;
1718                                         }
1719
1720                                         if (iter_a.valid) {
1721                                                 RNA_property_collection_next(&iter_a);
1722                                                 idx_a++;
1723                                         }
1724                                 } while (iter_a.valid);
1725
1726                                 if (iter_a.valid) {
1727                                         RNA_property_collection_next(&iter_a);
1728                                         idx_a++;
1729                                 }
1730                                 if (iter_b.valid) {
1731                                         RNA_property_collection_next(&iter_b);
1732                                         idx_b++;
1733                                 }
1734
1735 #undef RNA_PATH_BUFFSIZE
1736 #undef RNA_PATH_PRINTF
1737 #undef RNA_PATH_FREE
1738                         }
1739
1740                         equals = equals && !(iter_a.valid || iter_b.valid) && !abort;  /* Not same number of items in both collections... */
1741                         RNA_property_collection_end(&iter_a);
1742                         RNA_property_collection_end(&iter_b);
1743
1744                         return (equals == false);
1745                 }
1746
1747                 default:
1748                         break;
1749         }
1750
1751         return 0;
1752 }
1753
1754 bool rna_property_override_store_default(
1755         Main *UNUSED(bmain),
1756         PointerRNA *ptr_local, PointerRNA *ptr_reference, PointerRNA *ptr_storage,
1757         PropertyRNA *prop_local, PropertyRNA *prop_reference, PropertyRNA *prop_storage,
1758         const int len_local, const int len_reference, const int len_storage,
1759         IDOverrideStaticPropertyOperation *opop)
1760 {
1761         BLI_assert(len_local == len_reference && (!ptr_storage || len_local == len_storage));
1762         UNUSED_VARS_NDEBUG(len_reference, len_storage);
1763
1764         bool changed = false;
1765         const bool is_array = len_local > 0;
1766         const int index = is_array ? opop->subitem_reference_index : 0;
1767
1768         if (!ELEM(opop->operation, IDOVERRIDESTATIC_OP_ADD, IDOVERRIDESTATIC_OP_SUBTRACT, IDOVERRIDESTATIC_OP_MULTIPLY)) {
1769                 return changed;
1770         }
1771
1772         /* XXX TODO About range limits.
1773          * Ideally, it would be great to get rid of RNA range in that specific case.
1774          * However, this won't be that easy and will add yet another layer of complexity in generated code,
1775          * not to mention that we could most likely *not* bypass custom setters anyway.
1776          * So for now, if needed second operand value is not in valid range, we simply fall back
1777          * to a mere REPLACE operation.
1778          * Time will say whether this is acceptable limitation or not. */
1779         switch (RNA_property_type(prop_local)) {
1780                 case PROP_BOOLEAN:
1781                         /* TODO support boolean ops? Really doubt this would ever be useful though... */
1782                         BLI_assert(0 && "Boolean properties support no override diff operation");
1783                         break;
1784                 case PROP_INT:
1785                 {
1786                         int prop_min, prop_max;
1787                         RNA_property_int_range(ptr_local, prop_local, &prop_min, &prop_max);
1788
1789                         if (is_array && index == -1) {
1790                                 int array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
1791                                 int *array_a, *array_b;
1792
1793                                 array_a = (len_local > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_local, __func__) : array_stack_a;
1794                                 RNA_property_int_get_array(ptr_reference, prop_reference, array_a);
1795
1796                                 switch (opop->operation) {
1797                                         case IDOVERRIDESTATIC_OP_ADD:
1798                                         case IDOVERRIDESTATIC_OP_SUBTRACT:
1799                                         {
1800                                                 const int fac = opop->operation == IDOVERRIDESTATIC_OP_ADD ? 1 : -1;
1801                                                 const int other_op = opop->operation == IDOVERRIDESTATIC_OP_ADD ? IDOVERRIDESTATIC_OP_SUBTRACT : IDOVERRIDESTATIC_OP_ADD;
1802                                                 bool do_set = true;
1803                                                 array_b = (len_local > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_local, __func__) : array_stack_b;
1804                                                 RNA_property_int_get_array(ptr_local, prop_local, array_b);
1805                                                 for (int i = len_local; i--;) {
1806                                                         array_b[i] = fac * (array_b[i] - array_a[i]);
1807                                                         if (array_b[i] < prop_min || array_b[i] > prop_max) {
1808                                                                 opop->operation = other_op;
1809                                                                 for (int j = len_local; j--;) {
1810                                                                         array_b[j] = j >= i ? -array_b[j] : fac * (array_a[j] - array_b[j]);
1811                                                                         if (array_b[j] < prop_min || array_b[j] > prop_max) {
1812                                                                                 /* We failed to  find a suitable diff op,
1813                                                                                  * fall back to plain REPLACE one. */
1814                                                                                 opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
1815                                                                                 do_set = false;
1816                                                                                 break;
1817                                                                         }
1818                                                                 }
1819                                                                 break;
1820                                                         }
1821                                                 }
1822                                                 if (do_set) {
1823                                                         changed = true;
1824                                                         RNA_property_int_set_array(ptr_storage, prop_storage, array_b);
1825                                                 }
1826                                                 if (array_b != array_stack_b) MEM_freeN(array_b);
1827                                                 break;
1828                                         }
1829                                         default:
1830                                                 BLI_assert(0 && "Unsupported RNA override diff operation on integer");
1831                                                 break;
1832                                 }
1833
1834                                 if (array_a != array_stack_a) MEM_freeN(array_a);
1835                         }
1836                         else {
1837                                 const int value = RNA_PROPERTY_GET_SINGLE(int, ptr_reference, prop_reference, index);
1838
1839                                 switch (opop->operation) {
1840                                         case IDOVERRIDESTATIC_OP_ADD:
1841                                         case IDOVERRIDESTATIC_OP_SUBTRACT:
1842                                         {
1843                                                 const int fac = opop->operation == IDOVERRIDESTATIC_OP_ADD ? 1 : -1;
1844                                                 const int other_op = opop->operation == IDOVERRIDESTATIC_OP_ADD ? IDOVERRIDESTATIC_OP_SUBTRACT : IDOVERRIDESTATIC_OP_ADD;
1845                                                 int b = fac * (RNA_PROPERTY_GET_SINGLE(int, ptr_local, prop_local, index) - value);
1846                                                 if (b < prop_min || b > prop_max) {
1847                                                         opop->operation = other_op;
1848                                                         b = -b;
1849                                                         if (b < prop_min || b > prop_max) {
1850                                                                 opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
1851                                                                 break;
1852                                                         }
1853                                                 }
1854                                                 changed = true;
1855                                                 RNA_PROPERTY_SET_SINGLE(int, ptr_storage, prop_storage, index, b);
1856                                                 break;
1857                                         }
1858                                         default:
1859                                                 BLI_assert(0 && "Unsupported RNA override diff operation on integer");
1860                                                 break;
1861                                 }
1862                         }
1863                         break;
1864                 }
1865                 case PROP_FLOAT:
1866                 {
1867                         float prop_min, prop_max;
1868                         RNA_property_float_range(ptr_local, prop_local, &prop_min, &prop_max);
1869
1870                         if (is_array && index == -1) {
1871                                 float array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
1872                                 float *array_a, *array_b;
1873
1874                                 array_a = (len_local > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_local, __func__) : array_stack_a;
1875
1876                                 RNA_property_float_get_array(ptr_reference, prop_reference, array_a);
1877                                 switch (opop->operation) {
1878                                         case IDOVERRIDESTATIC_OP_ADD:
1879                                         case IDOVERRIDESTATIC_OP_SUBTRACT:
1880                                         {
1881                                                 const float fac = opop->operation == IDOVERRIDESTATIC_OP_ADD ? 1.0 : -1.0;
1882                                                 const int other_op = opop->operation == IDOVERRIDESTATIC_OP_ADD ? IDOVERRIDESTATIC_OP_SUBTRACT : IDOVERRIDESTATIC_OP_ADD;
1883                                                 bool do_set = true;
1884                                                 array_b = (len_local > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_local, __func__) : array_stack_b;
1885                                                 RNA_property_float_get_array(ptr_local, prop_local, array_b);
1886                                                 for (int i = len_local; i--;) {
1887                                                         array_b[i] = fac * (array_b[i] - array_a[i]);
1888                                                         if (array_b[i] < prop_min || array_b[i] > prop_max) {
1889                                                                 opop->operation = other_op;
1890                                                                 for (int j = len_local; j--;) {
1891                                                                         array_b[j] = j >= i ? -array_b[j] : fac * (array_a[j] - array_b[j]);
1892                                                                         if (array_b[j] < prop_min || array_b[j] > prop_max) {
1893                                                                                 /* We failed to  find a suitable diff op,
1894                                                                                  * fall back to plain REPLACE one. */
1895                                                                                 opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
1896                                                                                 do_set = false;
1897                                                                                 break;
1898                                                                         }
1899                                                                 }
1900                                                                 break;
1901                                                         }
1902                                                 }
1903                                                 if (do_set) {
1904                                                         changed = true;
1905                                                         RNA_property_float_set_array(ptr_storage, prop_storage, array_b);
1906                                                 }
1907                                                 if (array_b != array_stack_b) MEM_freeN(array_b);
1908                                                 break;
1909                                         }
1910                                         case IDOVERRIDESTATIC_OP_MULTIPLY:
1911                                         {
1912                                                 bool do_set = true;
1913                                                 array_b = (len_local > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_local, __func__) : array_stack_b;
1914                                                 RNA_property_float_get_array(ptr_local, prop_local, array_b);
1915                                                 for (int i = len_local; i--;) {
1916                                                         array_b[i] = array_a[i] == 0.0f ? array_b[i] : array_b[i] / array_a[i];
1917                                                         if (array_b[i] < prop_min || array_b[i] > prop_max) {
1918                                                                 opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
1919                                                                 do_set = false;
1920                                                                 break;
1921                                                         }
1922                                                 }
1923                                                 if (do_set) {
1924                                                         changed = true;
1925                                                         RNA_property_float_set_array(ptr_storage, prop_storage, array_b);
1926                                                 }
1927                                                 if (array_b != array_stack_b) MEM_freeN(array_b);
1928                                                 break;
1929                                         }
1930                                         default:
1931                                                 BLI_assert(0 && "Unsupported RNA override diff operation on float");
1932                                                 break;
1933                                 }
1934
1935                                 if (array_a != array_stack_a) MEM_freeN(array_a);
1936                         }
1937                         else {
1938                                 const float value = RNA_PROPERTY_GET_SINGLE(float, ptr_reference, prop_reference, index);
1939
1940                                 switch (opop->operation) {
1941                                         case IDOVERRIDESTATIC_OP_ADD:
1942                                         case IDOVERRIDESTATIC_OP_SUBTRACT:
1943                                         {
1944                                                 const float fac = opop->operation == IDOVERRIDESTATIC_OP_ADD ? 1.0f : -1.0f;
1945                                                 const int other_op = opop->operation == IDOVERRIDESTATIC_OP_ADD ? IDOVERRIDESTATIC_OP_SUBTRACT : IDOVERRIDESTATIC_OP_ADD;
1946                                                 float b = fac * (RNA_PROPERTY_GET_SINGLE(float, ptr_local, prop_local, index) - value);
1947                                                 if (b < prop_min || b > prop_max) {
1948                                                         opop->operation = other_op;
1949                                                         b = -b;
1950                                                         if (b < prop_min || b > prop_max) {
1951                                                                 opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
1952                                                                 break;
1953                                                         }
1954                                                 }
1955                                                 changed = true;
1956                                                 RNA_PROPERTY_SET_SINGLE(float, ptr_storage, prop_storage, index, b);
1957                                                 break;
1958                                         }
1959                                         case IDOVERRIDESTATIC_OP_MULTIPLY:
1960                                         {
1961                                                 const float b = RNA_property_float_get_index(ptr_local, prop_local, index) / (value == 0.0f ?  1.0f : value);
1962                                                 if (b < prop_min || b > prop_max) {
1963                                                         opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
1964                                                         break;
1965                                                 }
1966                                                 changed = true;
1967                                                 RNA_property_float_set_index(ptr_storage, prop_storage, index, b);
1968                                                 break;
1969                                         }
1970                                         default:
1971                                                 BLI_assert(0 && "Unsupported RNA override diff operation on float");
1972                                                 break;
1973                                 }
1974                         }
1975                         return true;
1976                 }
1977                 case PROP_ENUM:
1978                         /* TODO support add/sub, for bitflags? */
1979                         BLI_assert(0 && "Enum properties support no override diff operation");
1980                         break;
1981                 case PROP_POINTER:
1982                         BLI_assert(0 && "Pointer properties support no override diff operation");
1983                         break;
1984                 case PROP_STRING:
1985                         BLI_assert(0 && "String properties support no override diff operation");
1986                         break;
1987                 case PROP_COLLECTION:
1988                         /* XXX TODO support this of course... */
1989                         BLI_assert(0 && "Collection properties support no override diff operation");
1990                         break;
1991                 default:
1992                         break;
1993         }
1994
1995         return changed;
1996 }
1997
1998 bool rna_property_override_apply_default(
1999         Main *UNUSED(bmain),
2000         PointerRNA *ptr_dst, PointerRNA *ptr_src, PointerRNA *ptr_storage,
2001         PropertyRNA *prop_dst, PropertyRNA *prop_src, PropertyRNA *prop_storage,
2002         const int len_dst, const int len_src, const int len_storage,
2003         PointerRNA *UNUSED(ptr_item_dst), PointerRNA *UNUSED(ptr_item_src), PointerRNA *UNUSED(ptr_item_storage),
2004         IDOverrideStaticPropertyOperation *opop)
2005 {
2006         BLI_assert(len_dst == len_src && (!ptr_storage || len_dst == len_storage));
2007         UNUSED_VARS_NDEBUG(len_src, len_storage);
2008
2009         const bool is_array = len_dst > 0;
2010         const int index = is_array ? opop->subitem_reference_index : 0;
2011         const short override_op = opop->operation;
2012
2013         switch (RNA_property_type(prop_dst)) {
2014                 case PROP_BOOLEAN:
2015                         if (is_array && index == -1) {
2016                                 bool array_stack_a[RNA_STACK_ARRAY];
2017                                 bool *array_a;
2018
2019                                 array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) : array_stack_a;
2020
2021                                 RNA_property_boolean_get_array(ptr_src, prop_src, array_a);
2022
2023                                 switch (override_op) {
2024                                         case IDOVERRIDESTATIC_OP_REPLACE:
2025                                                 RNA_property_boolean_set_array(ptr_dst, prop_dst, array_a);
2026                                                 break;
2027                                         default:
2028                                                 BLI_assert(0 && "Unsupported RNA override operation on boolean");
2029                                                 return false;
2030                                 }
2031
2032                                 if (array_a != array_stack_a) MEM_freeN(array_a);
2033                         }
2034                         else {
2035                                 const bool value = RNA_PROPERTY_GET_SINGLE(boolean, ptr_src, prop_src, index);
2036
2037                                 switch (override_op) {
2038                                         case IDOVERRIDESTATIC_OP_REPLACE:
2039                                                 RNA_PROPERTY_SET_SINGLE(boolean, ptr_dst, prop_dst, index, value);
2040                                                 break;
2041                                         default:
2042                                                 BLI_assert(0 && "Unsupported RNA override operation on boolean");
2043                                                 return false;
2044                                 }
2045                         }
2046                         return true;
2047                 case PROP_INT:
2048                         if (is_array && index == -1) {
2049                                 int array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
2050                                 int *array_a, *array_b;
2051
2052                                 array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) : array_stack_a;
2053
2054                                 switch (override_op) {
2055                                         case IDOVERRIDESTATIC_OP_REPLACE:
2056                                                 RNA_property_int_get_array(ptr_src, prop_src, array_a);
2057                                                 RNA_property_int_set_array(ptr_dst, prop_dst, array_a);
2058                                                 break;
2059                                         case IDOVERRIDESTATIC_OP_ADD:
2060                                         case IDOVERRIDESTATIC_OP_SUBTRACT:
2061                                                 RNA_property_int_get_array(ptr_dst, prop_dst, array_a);
2062                                                 array_b = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_dst, __func__) : array_stack_b;
2063                                                 RNA_property_int_get_array(ptr_storage, prop_storage, array_b);
2064                                                 if (override_op == IDOVERRIDESTATIC_OP_ADD) {
2065                                                         for (int i = len_dst; i--;) array_a[i] += array_b[i];
2066                                                 }
2067                                                 else {
2068                                                         for (int i = len_dst; i--;) array_a[i] -= array_b[i];
2069                                                 }
2070                                                 RNA_property_int_set_array(ptr_dst, prop_dst, array_a);
2071                                                 if (array_b != array_stack_b) MEM_freeN(array_b);
2072                                                 break;
2073                                         default:
2074                                                 BLI_assert(0 && "Unsupported RNA override operation on integer");
2075                                                 return false;
2076                                 }
2077
2078                                 if (array_a != array_stack_a) MEM_freeN(array_a);
2079                         }
2080                         else {
2081                                 const int storage_value = ptr_storage ? RNA_PROPERTY_GET_SINGLE(int, ptr_storage, prop_storage, index) : 0;
2082
2083                                 switch (override_op) {
2084                                         case IDOVERRIDESTATIC_OP_REPLACE:
2085                                                 RNA_PROPERTY_SET_SINGLE(int, ptr_dst, prop_dst, index,
2086                                                                         RNA_PROPERTY_GET_SINGLE(int, ptr_src, prop_src, index));
2087                                                 break;
2088                                         case IDOVERRIDESTATIC_OP_ADD:
2089                                                 RNA_PROPERTY_SET_SINGLE(int, ptr_dst, prop_dst, index,
2090                                                                         RNA_PROPERTY_GET_SINGLE(int, ptr_dst, prop_dst, index) - storage_value);
2091                                                 break;
2092                                         case IDOVERRIDESTATIC_OP_SUBTRACT:
2093                                                 RNA_PROPERTY_SET_SINGLE(int, ptr_dst, prop_dst, index,
2094                                                                         RNA_PROPERTY_GET_SINGLE(int, ptr_dst, prop_dst, index) - storage_value);
2095                                                 break;
2096                                         default:
2097                                                 BLI_assert(0 && "Unsupported RNA override operation on integer");
2098                                                 return false;
2099                                 }
2100                         }
2101                         return true;
2102                 case PROP_FLOAT:
2103                         if (is_array && index == -1) {
2104                                 float array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
2105                                 float *array_a, *array_b;
2106
2107                                 array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) : array_stack_a;
2108
2109                                 switch (override_op) {
2110                                         case IDOVERRIDESTATIC_OP_REPLACE:
2111                                                 RNA_property_float_get_array(ptr_src, prop_src, array_a);
2112                                                 RNA_property_float_set_array(ptr_dst, prop_dst, array_a);
2113                                                 break;
2114                                         case IDOVERRIDESTATIC_OP_ADD:
2115                                         case IDOVERRIDESTATIC_OP_SUBTRACT:
2116                                         case IDOVERRIDESTATIC_OP_MULTIPLY:
2117                                                 RNA_property_float_get_array(ptr_dst, prop_dst, array_a);
2118                                                 array_b = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_dst, __func__) : array_stack_b;
2119                                                 RNA_property_float_get_array(ptr_storage, prop_storage, array_b);
2120                                                 if (override_op == IDOVERRIDESTATIC_OP_ADD) {
2121                                                         for (int i = len_dst; i--;) array_a[i] += array_b[i];
2122                                                 }
2123                                                 else if (override_op == IDOVERRIDESTATIC_OP_SUBTRACT) {
2124                                                         for (int i = len_dst; i--;) array_a[i] -= array_b[i];
2125                                                 }
2126                                                 else {
2127                                                         for (int i = len_dst; i--;) array_a[i] *= array_b[i];
2128                                                 }
2129                                                 RNA_property_float_set_array(ptr_dst, prop_dst, array_a);
2130                                                 if (array_b != array_stack_b) MEM_freeN(array_b);
2131                                                 break;
2132                                         default:
2133                                                 BLI_assert(0 && "Unsupported RNA override operation on float");
2134                                                 return false;
2135                                 }
2136
2137                                 if (array_a != array_stack_a) MEM_freeN(array_a);
2138                         }
2139                         else {
2140                                 const float storage_value = ptr_storage ? RNA_PROPERTY_GET_SINGLE(float, ptr_storage, prop_storage, index) : 0.0f;
2141
2142                                 switch (override_op) {
2143                                         case IDOVERRIDESTATIC_OP_REPLACE:
2144                                                 RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index,
2145                                                                         RNA_PROPERTY_GET_SINGLE(float, ptr_src, prop_src, index));
2146                                                 break;
2147                                         case IDOVERRIDESTATIC_OP_ADD:
2148                                                 RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index,
2149                                                                         RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) + storage_value);
2150                                                 break;
2151                                         case IDOVERRIDESTATIC_OP_SUBTRACT:
2152                                                 RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index,
2153                                                                         RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) - storage_value);
2154                                                 break;
2155                                         case IDOVERRIDESTATIC_OP_MULTIPLY:
2156                                                 RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index,
2157                                                                         RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) * storage_value);
2158                                                 break;
2159                                         default:
2160                                                 BLI_assert(0 && "Unsupported RNA override operation on float");
2161                                                 return false;
2162                                 }
2163                         }
2164                         return true;
2165                 case PROP_ENUM:
2166                 {
2167                         const int value = RNA_property_enum_get(ptr_src, prop_src);
2168
2169                         switch (override_op) {
2170                                 case IDOVERRIDESTATIC_OP_REPLACE:
2171                                         RNA_property_enum_set(ptr_dst, prop_dst, value);
2172                                         break;
2173                                 /* TODO support add/sub, for bitflags? */
2174                                 default:
2175                                         BLI_assert(0 && "Unsupported RNA override operation on enum");
2176                                         return false;
2177                         }
2178                         return true;
2179                 }
2180                 case PROP_POINTER:
2181                 {
2182                         PointerRNA value = RNA_property_pointer_get(ptr_src, prop_src);
2183
2184                         switch (override_op) {
2185                                 case IDOVERRIDESTATIC_OP_REPLACE:
2186                                         RNA_property_pointer_set(ptr_dst, prop_dst, value);
2187                                         break;
2188                                 default:
2189                                         BLI_assert(0 && "Unsupported RNA override operation on pointer");
2190                                         return false;
2191                         }
2192                         return true;
2193                 }
2194                 case PROP_STRING:
2195                 {
2196                         char buff[256];
2197                         char *value = RNA_property_string_get_alloc(ptr_src, prop_src, buff, sizeof(buff), NULL);
2198
2199                         switch (override_op) {
2200                                 case IDOVERRIDESTATIC_OP_REPLACE:
2201                                         RNA_property_string_set(ptr_dst, prop_dst, value);
2202                                         break;
2203                                 default:
2204                                         BLI_assert(0 && "Unsupported RNA override operation on string");
2205                                         return false;
2206                         }
2207
2208                         if (value != buff) MEM_freeN(value);
2209                         return true;
2210                 }
2211                 case PROP_COLLECTION:
2212                 {
2213                         BLI_assert(!"You need to define a specific override apply callback for enums.");
2214                         return false;
2215                 }
2216                 default:
2217                         BLI_assert(0);
2218                         return false;
2219         }
2220
2221         return false;
2222 }
2223
2224 #undef RNA_PROPERTY_GET_SINGLE
2225 #undef RNA_PROPERTY_SET_SINGLE
2226
2227
2228 #else
2229
2230 static void rna_def_struct(BlenderRNA *brna)
2231 {
2232         StructRNA *srna;
2233         PropertyRNA *prop;
2234
2235         srna = RNA_def_struct(brna, "Struct", NULL);
2236         RNA_def_struct_ui_text(srna, "Struct Definition", "RNA structure definition");
2237         RNA_def_struct_ui_icon(srna, ICON_RNA);
2238
2239         prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
2240         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2241         RNA_def_property_string_funcs(prop, "rna_Struct_name_get", "rna_Struct_name_length", NULL);
2242         RNA_def_property_ui_text(prop, "Name", "Human readable name");
2243
2244         prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
2245         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2246         RNA_def_property_string_funcs(prop, "rna_Struct_identifier_get", "rna_Struct_identifier_length", NULL);
2247         RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting");
2248         RNA_def_struct_name_property(srna, prop);
2249
2250         prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
2251         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2252         RNA_def_property_string_funcs(prop, "rna_Struct_description_get", "rna_Struct_description_length", NULL);
2253         RNA_def_property_ui_text(prop, "Description", "Description of the Struct's purpose");
2254
2255         prop = RNA_def_property(srna, "translation_context", PROP_STRING, PROP_NONE);
2256         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2257         RNA_def_property_string_funcs(prop, "rna_Struct_translation_context_get",
2258                                       "rna_Struct_translation_context_length", NULL);
2259         RNA_def_property_ui_text(prop, "Translation Context", "Translation context of the struct's name");
2260
2261         prop = RNA_def_property(srna, "base", PROP_POINTER, PROP_NONE);
2262         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2263         RNA_def_property_struct_type(prop, "Struct");
2264         RNA_def_property_pointer_funcs(prop, "rna_Struct_base_get", NULL, NULL, NULL);
2265         RNA_def_property_ui_text(prop, "Base", "Struct definition this is derived from");
2266
2267         prop = RNA_def_property(srna, "nested", PROP_POINTER, PROP_NONE);
2268         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2269         RNA_def_property_struct_type(prop, "Struct");
2270         RNA_def_property_pointer_funcs(prop, "rna_Struct_nested_get", NULL, NULL, NULL);
2271         RNA_def_property_ui_text(prop, "Nested",
2272                                  "Struct in which this struct is always nested, and to which it logically belongs");
2273
2274         prop = RNA_def_property(srna, "name_property", PROP_POINTER, PROP_NONE);
2275         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2276         RNA_def_property_struct_type(prop, "StringProperty");
2277         RNA_def_property_pointer_funcs(prop, "rna_Struct_name_property_get", NULL, NULL, NULL);
2278         RNA_def_property_ui_text(prop, "Name Property", "Property that gives the name of the struct");
2279
2280         prop = RNA_def_property(srna, "properties", PROP_COLLECTION, PROP_NONE);
2281         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2282         RNA_def_property_struct_type(prop, "Property");
2283         RNA_def_property_collection_funcs(prop, "rna_Struct_properties_begin", "rna_Struct_properties_next",
2284                                           "rna_iterator_listbase_end", "rna_Struct_properties_get",
2285                                           NULL, NULL, NULL, NULL);
2286         RNA_def_property_ui_text(prop, "Properties", "Properties in the struct");
2287
2288         prop = RNA_def_property(srna, "functions", PROP_COLLECTION, PROP_NONE);
2289         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2290         RNA_def_property_struct_type(prop, "Function");
2291         RNA_def_property_collection_funcs(prop, "rna_Struct_functions_begin", "rna_Struct_functions_next",
2292                                           "rna_iterator_listbase_end", "rna_Struct_functions_get",
2293                                           NULL, NULL, NULL, NULL);
2294         RNA_def_property_ui_text(prop, "Functions", "");
2295
2296         prop = RNA_def_property(srna, "property_tags", PROP_COLLECTION, PROP_NONE);
2297         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2298         RNA_def_property_struct_type(prop, "EnumPropertyItem");
2299         RNA_def_property_collection_funcs(prop, "rna_Struct_property_tags_begin", "rna_iterator_array_next",
2300                                           "rna_iterator_array_end", "rna_iterator_array_get",
2301                                           NULL, NULL, NULL, NULL);
2302         RNA_def_property_ui_text(prop, "Property Tags", "Tags that properties can use to influence behavior");
2303 }
2304
2305 static void rna_def_property(BlenderRNA *brna)
2306 {
2307         StructRNA *srna;
2308         PropertyRNA *prop;
2309         static const EnumPropertyItem subtype_items[] = {
2310                 {PROP_NONE, "NONE", 0, "None", ""},
2311                 {PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""},
2312                 {PROP_DIRPATH, "DIR_PATH", 0, "Directory Path", ""},
2313                 {PROP_PIXEL, "PIXEL", 0, "Pixel", ""},
2314                 {PROP_UNSIGNED, "UNSIGNED", 0, "Unsigned Number", ""},
2315                 {PROP_PERCENTAGE, "PERCENTAGE", 0, "Percentage", ""},
2316                 {PROP_FACTOR, "FACTOR", 0, "Factor", ""},
2317                 {PROP_ANGLE, "ANGLE", 0, "Angle", ""},
2318                 {PROP_TIME, "TIME", 0, "Time", ""},
2319                 {PROP_DISTANCE, "DISTANCE", 0, "Distance", ""},
2320                 {PROP_COLOR, "COLOR", 0, "Color", ""},
2321                 {PROP_TRANSLATION, "TRANSLATION", 0, "Translation", ""},
2322                 {PROP_DIRECTION, "DIRECTION", 0, "Direction", ""},
2323                 {PROP_MATRIX, "MATRIX", 0, "Matrix", ""},
2324                 {PROP_EULER, "EULER", 0, "Euler", ""},
2325                 {PROP_QUATERNION, "QUATERNION", 0, "Quaternion", ""},
2326                 {PROP_XYZ, "XYZ", 0, "XYZ", ""},
2327                 {PROP_COLOR_GAMMA, "COLOR_GAMMA", 0, "Gamma Corrected Color", ""},
2328                 {PROP_COORDS, "COORDINATES", 0, "Vector Coordinates", ""},
2329                 {PROP_LAYER, "LAYER", 0, "Layer", ""},
2330                 {PROP_LAYER_MEMBER, "LAYER_MEMBERSHIP", 0, "Layer Membership", ""},
2331                 {0, NULL, 0, NULL, NULL}
2332         };
2333         EnumPropertyItem dummy_prop_tags[] = {
2334                 {0, NULL, 0, NULL, NULL}
2335         };
2336
2337         srna = RNA_def_struct(brna, "Property", NULL);
2338         RNA_def_struct_ui_text(srna, "Property Definition", "RNA property definition");
2339         RNA_def_struct_refine_func(srna, "rna_Property_refine");
2340         RNA_def_struct_ui_icon(srna, ICON_RNA);
2341
2342         prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
2343         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2344         RNA_def_property_string_funcs(prop, "rna_Property_name_get", "rna_Property_name_length", NULL);
2345         RNA_def_property_ui_text(prop, "Name", "Human readable name");
2346
2347         prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
2348         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2349         RNA_def_property_string_funcs(prop, "rna_Property_identifier_get", "rna_Property_identifier_length", NULL);
2350         RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting");
2351         RNA_def_struct_name_property(srna, prop);
2352
2353         prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
2354         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2355         RNA_def_property_string_funcs(prop, "rna_Property_description_get", "rna_Property_description_length", NULL);
2356         RNA_def_property_ui_text(prop, "Description", "Description of the property for tooltips");
2357
2358         prop = RNA_def_property(srna, "translation_context", PROP_STRING, PROP_NONE);
2359         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2360         RNA_def_property_string_funcs(prop, "rna_Property_translation_context_get",
2361                                       "rna_Property_translation_context_length", NULL);
2362         RNA_def_property_ui_text(prop, "Translation Context", "Translation context of the property's name");
2363
2364         prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
2365         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2366         RNA_def_property_enum_items(prop, rna_enum_property_type_items);
2367         RNA_def_property_enum_funcs(prop, "rna_Property_type_get", NULL, NULL);
2368         RNA_def_property_ui_text(prop, "Type", "Data type of the property");
2369
2370         prop = RNA_def_property(srna, "subtype", PROP_ENUM, PROP_NONE);
2371         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2372         RNA_def_property_enum_items(prop, subtype_items);
2373         RNA_def_property_enum_funcs(prop, "rna_Property_subtype_get", NULL, NULL);
2374         RNA_def_property_ui_text(prop, "Subtype", "Semantic interpretation of the property");
2375
2376         prop = RNA_def_property(srna, "srna", PROP_POINTER, PROP_NONE);
2377         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2378         RNA_def_property_struct_type(prop, "Struct");
2379         RNA_def_property_pointer_funcs(prop, "rna_Property_srna_get", NULL, NULL, NULL);
2380         RNA_def_property_ui_text(prop, "Base", "Struct definition used for properties assigned to this item");
2381
2382         prop = RNA_def_property(srna, "unit", PROP_ENUM, PROP_NONE);
2383         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2384         RNA_def_property_enum_items(prop, rna_enum_property_unit_items);
2385         RNA_def_property_enum_funcs(prop, "rna_Property_unit_get", NULL, NULL);
2386         RNA_def_property_ui_text(prop, "Unit", "Type of units for this property");
2387
2388         prop = RNA_def_property(srna, "icon", PROP_ENUM, PROP_NONE);
2389         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2390         RNA_def_property_enum_items(prop, rna_enum_icon_items);
2391         RNA_def_property_enum_funcs(prop, "rna_Property_icon_get", NULL, NULL);
2392         RNA_def_property_ui_text(prop, "Icon", "Icon of the item");
2393
2394         prop = RNA_def_property(srna, "is_readonly", PROP_BOOLEAN, PROP_NONE);
2395         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2396         RNA_def_property_boolean_funcs(prop, "rna_Property_readonly_get", NULL);
2397         RNA_def_property_ui_text(prop, "Read Only", "Property is editable through RNA");
2398
2399         prop = RNA_def_property(srna, "is_animatable", PROP_BOOLEAN, PROP_NONE);
2400         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2401         RNA_def_property_boolean_funcs(prop, "rna_Property_animatable_get", NULL);
2402         RNA_def_property_ui_text(prop, "Animatable", "Property is animatable through RNA");
2403
2404         prop = RNA_def_property(srna, "is_overridable", PROP_BOOLEAN, PROP_NONE);
2405         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2406         RNA_def_property_boolean_funcs(prop, "rna_Property_overridable_get", NULL);
2407         RNA_def_property_ui_text(prop, "Overridable", "Property is overridable through RNA");
2408
2409         prop = RNA_def_property(srna, "is_required", PROP_BOOLEAN, PROP_NONE);
2410         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2411         RNA_def_property_boolean_funcs(prop, "rna_Property_is_required_get", NULL);
2412         RNA_def_property_ui_text(prop, "Required", "False when this property is an optional argument in an RNA function");
2413
2414         prop = RNA_def_property(srna, "is_argument_optional", PROP_BOOLEAN, PROP_NONE);
2415         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2416         RNA_def_property_boolean_funcs(prop, "rna_Property_is_argument_optional_get", NULL);
2417         RNA_def_property_ui_text(prop, "Optional Argument",
2418                                  "True when the property is optional in a Python function implementing an RNA function");
2419
2420         prop = RNA_def_property(srna, "is_never_none", PROP_BOOLEAN, PROP_NONE);
2421         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2422         RNA_def_property_boolean_funcs(prop, "rna_Property_is_never_none_get", NULL);
2423         RNA_def_property_ui_text(prop, "Never None", "True when this value can't be set to None");
2424
2425         prop = RNA_def_property(srna, "is_hidden", PROP_BOOLEAN, PROP_NONE);
2426         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2427         RNA_def_property_boolean_funcs(prop, "rna_Property_is_hidden_get", NULL);
2428         RNA_def_property_ui_text(prop, "Hidden", "True when the property is hidden");
2429
2430         prop = RNA_def_property(srna, "is_skip_save", PROP_BOOLEAN, PROP_NONE);
2431         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2432         RNA_def_property_boolean_funcs(prop, "rna_Property_is_skip_save_get", NULL);
2433         RNA_def_property_ui_text(prop, "Skip Save", "True when the property is not saved in presets");
2434
2435         prop = RNA_def_property(srna, "is_output", PROP_BOOLEAN, PROP_NONE);
2436         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2437         RNA_def_property_boolean_funcs(prop, "rna_Property_use_output_get", NULL);
2438         RNA_def_property_ui_text(prop, "Return", "True when this property is an output value from an RNA function");
2439
2440         prop = RNA_def_property(srna, "is_registered", PROP_BOOLEAN, PROP_NONE);
2441         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2442         RNA_def_property_boolean_funcs(prop, "rna_Property_is_registered_get", NULL);
2443         RNA_def_property_ui_text(prop, "Registered", "Property is registered as part of type registration");
2444
2445         prop = RNA_def_property(srna, "is_registered_optional", PROP_BOOLEAN, PROP_NONE);
2446         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2447         RNA_def_property_boolean_funcs(prop, "rna_Property_is_registered_optional_get", NULL);
2448         RNA_def_property_ui_text(prop, "Registered Optionally",
2449                                  "Property is optionally registered as part of type registration");
2450
2451         prop = RNA_def_property(srna, "is_runtime", PROP_BOOLEAN, PROP_NONE);
2452         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2453         RNA_def_property_boolean_funcs(prop, "rna_Property_is_runtime_get", NULL);
2454         RNA_def_property_ui_text(prop, "Runtime", "Property has been dynamically created at runtime");
2455
2456         prop = RNA_def_property(srna, "is_enum_flag", PROP_BOOLEAN, PROP_NONE);
2457         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2458         RNA_def_property_boolean_funcs(prop, "rna_Property_is_enum_flag_get", NULL);
2459         RNA_def_property_ui_text(prop, "Enum Flag", "True when multiple enums ");
2460
2461         prop = RNA_def_property(srna, "is_library_editable", PROP_BOOLEAN, PROP_NONE);
2462         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2463         RNA_def_property_boolean_funcs(prop, "rna_Property_is_library_editable_flag_get", NULL);
2464         RNA_def_property_ui_text(prop, "Library Editable", "Property is editable from linked instances (changes not saved)");
2465
2466         prop = RNA_def_property(srna, "tags", PROP_ENUM, PROP_NONE);
2467         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2468         RNA_def_property_enum_items(prop, dummy_prop_tags);
2469         RNA_def_property_enum_funcs(prop, "rna_Property_tags_get", NULL, "rna_Property_tags_itemf");
2470         RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG);
2471         RNA_def_property_ui_text(prop, "Tags", "Subset of tags (defined in parent struct) that are set for this property");
2472 }
2473
2474 static void rna_def_function(BlenderRNA *brna)
2475 {
2476         StructRNA *srna;
2477         PropertyRNA *prop;
2478
2479         srna = RNA_def_struct(brna, "Function", NULL);
2480         RNA_def_struct_ui_text(srna, "Function Definition", "RNA function definition");
2481         RNA_def_struct_ui_icon(srna, ICON_RNA);
2482
2483         prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
2484         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2485         RNA_def_property_string_funcs(prop, "rna_Function_identifier_get", "rna_Function_identifier_length", NULL);
2486         RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting");
2487         RNA_def_struct_name_property(srna, prop);
2488
2489         prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
2490         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2491         RNA_def_property_string_funcs(prop, "rna_Function_description_get", "rna_Function_description_length", NULL);
2492         RNA_def_property_ui_text(prop, "Description", "Description of the Function's purpose");
2493
2494         prop = RNA_def_property(srna, "parameters", PROP_COLLECTION, PROP_NONE);
2495         /*RNA_def_property_clear_flag(prop, PROP_EDITABLE);*/
2496         RNA_def_property_struct_type(prop, "Property");
2497         RNA_def_property_collection_funcs(prop, "rna_Function_parameters_begin", "rna_iterator_listbase_next",
2498                                           "rna_iterator_listbase_end", "rna_iterator_listbase_get",
2499                                           NULL, NULL, NULL, NULL);
2500         RNA_def_property_ui_text(prop, "Parameters", "Parameters for the function");
2501
2502         prop = RNA_def_property(srna, "is_registered", PROP_BOOLEAN, PROP_NONE);
2503         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2504         RNA_def_property_boolean_funcs(prop, "rna_Function_registered_get", NULL);
2505         RNA_def_property_ui_text(prop, "Registered", "Function is registered as callback as part of type registration");
2506
2507         prop = RNA_def_property(srna, "is_registered_optional", PROP_BOOLEAN, PROP_NONE);
2508         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2509         RNA_def_property_boolean_funcs(prop, "rna_Function_registered_optional_get", NULL);
2510         RNA_def_property_ui_text(prop, "Registered Optionally",
2511                                  "Function is optionally registered as callback part of type registration");
2512
2513         prop = RNA_def_property(srna, "use_self", PROP_BOOLEAN, PROP_NONE);
2514         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2515         RNA_def_property_boolean_funcs(prop, "rna_Function_no_self_get", NULL);
2516         RNA_def_property_ui_text(prop, "No Self",
2517                                  "Function does not pass its self as an argument (becomes a static method in python)");
2518
2519         prop = RNA_def_property(srna, "use_self_type", PROP_BOOLEAN, PROP_NONE);
2520         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2521         RNA_def_property_boolean_funcs(prop, "rna_Function_use_self_type_get", NULL);
2522         RNA_def_property_ui_text(prop, "Use Self Type",
2523                                  "Function passes its self type as an argument (becomes a class method in python if use_self is false)");
2524 }
2525
2526 static void rna_def_number_property(StructRNA *srna, PropertyType type)
2527 {
2528         PropertyRNA *prop;
2529
2530         prop = RNA_def_property(srna, "default", type, PROP_NONE);
2531         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2532         RNA_def_property_ui_text(prop, "Default", "Default value for this number");
2533
2534         switch (type) {
2535                 case PROP_BOOLEAN:
2536                         RNA_def_property_boolean_funcs(prop, "rna_BoolProperty_default_get", NULL);
2537                         break;
2538                 case PROP_INT:
2539                         RNA_def_property_int_funcs(prop, "rna_IntProperty_default_get", NULL, NULL);
2540                         break;
2541                 case PROP_FLOAT:
2542                         RNA_def_property_float_funcs(prop, "rna_FloatProperty_default_get", NULL, NULL);
2543                         break;
2544                 default:
2545                         break;
2546         }
2547
2548
2549         prop = RNA_def_property(srna, "default_array", type, PROP_NONE);
2550         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2551         RNA_def_property_array(prop, RNA_MAX_ARRAY_DIMENSION); /* no fixed default length, important its not 0 though */
2552         RNA_def_property_flag(prop, PROP_DYNAMIC);
2553         RNA_def_property_dynamic_array_funcs(prop, "rna_NumberProperty_default_array_get_length"); /* same for all types */
2554
2555         switch (type) {
2556                 case PROP_BOOLEAN:
2557                         RNA_def_property_boolean_funcs(prop, "rna_BoolProperty_default_array_get", NULL);
2558                         break;
2559                 case PROP_INT:
2560                         RNA_def_property_int_funcs(prop, "rna_IntProperty_default_array_get", NULL, NULL);
2561                         break;
2562                 case PROP_FLOAT:
2563                         RNA_def_property_float_funcs(prop, "rna_FloatProperty_default_array_get", NULL, NULL);
2564                         break;
2565                 default:
2566                         break;
2567         }
2568         RNA_def_property_ui_text(prop, "Default Array", "Default value for this array");
2569
2570
2571         prop = RNA_def_property(srna, "array_length", PROP_INT, PROP_UNSIGNED);
2572         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2573         RNA_def_property_int_funcs(prop, "rna_Property_array_length_get", NULL, NULL);
2574         RNA_def_property_ui_text(prop, "Array Length", "Maximum length of the array, 0 means unlimited");
2575
2576         prop = RNA_def_property(srna, "array_dimensions", PROP_INT, PROP_UNSIGNED);
2577         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2578         RNA_def_property_array(prop, RNA_MAX_ARRAY_DIMENSION);
2579         RNA_def_property_int_funcs(prop, "rna_Property_array_dimensions_get", NULL, NULL);
2580         RNA_def_property_ui_text(prop, "Array Dimensions", "Length of each dimension of the array");
2581
2582         prop = RNA_def_property(srna, "is_array", PROP_BOOLEAN, PROP_NONE);
2583         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2584         RNA_def_property_boolean_funcs(prop, "rna_NumberProperty_is_array_get", NULL);
2585         RNA_def_property_ui_text(prop, "Is Array", "");
2586
2587         if (type == PROP_BOOLEAN)
2588                 return;
2589
2590         prop = RNA_def_property(srna, "hard_min", type, PROP_NONE);
2591         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2592         if (type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_hard_min_get", NULL, NULL);
2593         else RNA_def_property_float_funcs(prop, "rna_FloatProperty_hard_min_get", NULL, NULL);
2594         RNA_def_property_ui_text(prop, "Hard Minimum", "Minimum value used by buttons");
2595
2596         prop = RNA_def_property(srna, "hard_max", type, PROP_NONE);
2597         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2598         if (type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_hard_max_get", NULL, NULL);
2599         else RNA_def_property_float_funcs(prop, "rna_FloatProperty_hard_max_get", NULL, NULL);
2600         RNA_def_property_ui_text(prop, "Hard Maximum", "Maximum value used by buttons");
2601
2602         prop = RNA_def_property(srna, "soft_min", type, PROP_NONE);
2603         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2604         if (type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_soft_min_get", NULL, NULL);
2605         else RNA_def_property_float_funcs(prop, "rna_FloatProperty_soft_min_get", NULL, NULL);
2606         RNA_def_property_ui_text(prop, "Soft Minimum", "Minimum value used by buttons");
2607
2608         prop = RNA_def_property(srna, "soft_max", type, PROP_NONE);
2609         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2610         if (type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_soft_max_get", NULL, NULL);
2611         else RNA_def_property_float_funcs(prop, "rna_FloatProperty_soft_max_get", NULL, NULL);
2612         RNA_def_property_ui_text(prop, "Soft Maximum", "Maximum value used by buttons");
2613
2614         prop = RNA_def_property(srna, "step", type, PROP_UNSIGNED);
2615         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2616         if (type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_step_get", NULL, NULL);
2617         else RNA_def_property_float_funcs(prop, "rna_FloatProperty_step_get", NULL, NULL);
2618         RNA_def_property_ui_text(prop, "Step", "Step size used by number buttons, for floats 1/100th of the step size");
2619
2620         if (type == PROP_FLOAT) {
2621                 prop = RNA_def_property(srna, "precision", PROP_INT, PROP_UNSIGNED);
2622                 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2623                 RNA_def_property_int_funcs(prop, "rna_FloatProperty_precision_get", NULL, NULL);
2624                 RNA_def_property_ui_text(prop, "Precision", "Number of digits after the dot used by buttons");
2625         }
2626 }
2627
2628 static void rna_def_string_property(StructRNA *srna)
2629 {
2630         PropertyRNA *prop;
2631
2632         prop = RNA_def_property(srna, "default", PROP_STRING, PROP_NONE);
2633         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2634         RNA_def_property_string_funcs(prop, "rna_StringProperty_default_get", "rna_StringProperty_default_length", NULL);
2635         RNA_def_property_ui_text(prop, "Default", "string default value");
2636
2637         prop = RNA_def_property(srna, "length_max", PROP_INT, PROP_UNSIGNED);
2638         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2639         RNA_def_property_int_funcs(prop, "rna_StringProperty_max_length_get", NULL, NULL);
2640         RNA_def_property_ui_text(prop, "Maximum Length", "Maximum length of the string, 0 means unlimited");
2641 }
2642
2643 static void rna_def_enum_property(BlenderRNA *brna, StructRNA *srna)
2644 {
2645         PropertyRNA *prop;
2646
2647         /* the itemf func is used instead, keep blender happy */
2648         static const EnumPropertyItem default_dummy_items[] = {
2649                 {PROP_NONE, "DUMMY", 0, "Dummy", ""},
2650                 {0, NULL, 0, NULL, NULL}
2651         };
2652
2653         prop = RNA_def_property(srna, "default", PROP_ENUM, PROP_NONE);
2654         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2655         RNA_def_property_enum_items(prop, default_dummy_items);
2656         RNA_def_property_enum_funcs(prop, "rna_EnumProperty_default_get", NULL, "rna_EnumProperty_default_itemf");
2657         RNA_def_property_ui_text(prop, "Default", "Default value for this enum");
2658
2659         /* same 'default' but uses 'PROP_ENUM_FLAG' */
2660         prop = RNA_def_property(srna, "default_flag", PROP_ENUM, PROP_NONE);
2661         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2662         RNA_def_property_flag(prop, PROP_ENUM_FLAG);
2663         RNA_def_property_enum_items(prop, default_dummy_items);
2664         RNA_def_property_enum_funcs(prop, "rna_EnumProperty_default_get", NULL, "rna_EnumProperty_default_itemf");
2665         RNA_def_property_ui_text(prop, "Default", "Default value for this enum");
2666
2667         prop = RNA_def_property(srna, "enum_items", PROP_COLLECTION, PROP_NONE);
2668         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2669         RNA_def_property_struct_type(prop, "EnumPropertyItem");
2670         RNA_def_property_collection_funcs(prop, "rna_EnumProperty_items_begin", "rna_iterator_array_next",
2671                                           "rna_iterator_array_end", "rna_iterator_array_get", NULL, NULL, NULL, NULL);
2672         RNA_def_property_ui_text(prop, "Items", "Possible values for the property");
2673
2674         prop = RNA_def_property(srna, "enum_items_static", PROP_COLLECTION, PROP_NONE);
2675         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2676         RNA_def_property_struct_type(prop, "EnumPropertyItem");
2677         RNA_def_property_collection_funcs(prop, "rna_EnumProperty_items_begin", "rna_iterator_array_next",
2678                                           "rna_iterator_array_end", "rna_iterator_array_get", NULL, NULL, NULL, NULL);
2679         RNA_def_property_ui_text(prop, "Static Items",
2680                                  "Possible values for the property (never calls optional dynamic generation of those)");
2681
2682         srna = RNA_def_struct(brna, "EnumPropertyItem", NULL);
2683         RNA_def_struct_ui_text(srna, "Enum Item Definition", "Definition of a choice in an RNA enum property");
2684         RNA_def_struct_ui_icon(srna, ICON_RNA);
2685
2686         prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
2687         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2688         RNA_def_property_string_funcs(prop, "rna_EnumPropertyItem_name_get", "rna_EnumPropertyItem_name_length", NULL);
2689         RNA_def_property_ui_text(prop, "Name", "Human readable name");
2690
2691         prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
2692         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2693         RNA_def_property_string_funcs(prop, "rna_EnumPropertyItem_description_get",
2694                                       "rna_EnumPropertyItem_description_length", NULL);
2695         RNA_def_property_ui_text(prop, "Description", "Description of the item's purpose");
2696
2697         prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
2698         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2699         RNA_def_property_string_funcs(prop, "rna_EnumPropertyItem_identifier_get",
2700                                       "rna_EnumPropertyItem_identifier_length", NULL);
2701         RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting");
2702         RNA_def_struct_name_property(srna, prop);
2703
2704         prop = RNA_def_property(srna, "value", PROP_INT, PROP_UNSIGNED);
2705         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2706         RNA_def_property_int_funcs(prop, "rna_EnumPropertyItem_value_get", NULL, NULL);
2707         RNA_def_property_ui_text(prop, "Value", "Value of the item");
2708
2709         prop = RNA_def_property(srna, "icon", PROP_ENUM, PROP_NONE);
2710         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2711         RNA_def_property_enum_items(prop, rna_enum_icon_items);
2712         RNA_def_property_enum_funcs(prop, "rna_EnumPropertyItem_icon_get", NULL, NULL);
2713         RNA_def_property_ui_text(prop, "Icon", "Icon of the item");
2714 }
2715
2716 static void rna_def_pointer_property(StructRNA *srna, PropertyType type)
2717 {
2718         PropertyRNA *prop;
2719
2720         prop = RNA_def_property(srna, "fixed_type", PROP_POINTER, PROP_NONE);
2721         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2722         RNA_def_property_struct_type(prop, "Struct");
2723         if (type == PROP_POINTER)
2724                 RNA_def_property_pointer_funcs(prop, "rna_PointerProperty_fixed_type_get", NULL, NULL, NULL);
2725         else
2726                 RNA_def_property_pointer_funcs(prop, "rna_CollectionProperty_fixed_type_get", NULL, NULL, NULL);
2727         RNA_def_property_ui_text(prop, "Pointer Type", "Fixed pointer type, empty if variable type");
2728 }
2729
2730 void RNA_def_rna(BlenderRNA *brna)
2731 {
2732         StructRNA *srna;
2733         PropertyRNA *prop;
2734
2735         /* Struct*/
2736         rna_def_struct(brna);
2737
2738         /* Property */
2739         rna_def_property(brna);
2740
2741         /* BoolProperty */
2742         srna = RNA_def_struct(brna, "BoolProperty", "Property");
2743         RNA_def_struct_ui_text(srna, "Boolean Definition", "RNA boolean property definition");
2744         rna_def_number_property(srna, PROP_BOOLEAN);
2745
2746         /* IntProperty */
2747         srna = RNA_def_struct(brna, "IntProperty", "Property");
2748         RNA_def_struct_ui_text(srna, "Int Definition", "RNA integer number property definition");
2749         rna_def_number_property(srna, PROP_INT);
2750
2751         /* FloatProperty */
2752         srna = RNA_def_struct(brna, "FloatProperty", "Property");
2753         RNA_def_struct_ui_text(srna, "Float Definition", "RNA floating pointer number property definition");
2754         rna_def_number_property(srna, PROP_FLOAT);
2755
2756         /* StringProperty */
2757         srna = RNA_def_struct(brna, "StringProperty", "Property");
2758         RNA_def_struct_ui_text(srna, "String Definition", "RNA text string property definition");
2759         rna_def_string_property(srna);
2760
2761         /* EnumProperty */
2762         srna = RNA_def_struct(brna, "EnumProperty", "Property");
2763         RNA_def_struct_ui_text(srna, "Enum Definition",
2764                                "RNA enumeration property definition, to choose from a number of predefined options");
2765         rna_def_enum_property(brna, srna);
2766
2767         /* PointerProperty */
2768         srna = RNA_def_struct(brna, "PointerProperty", "Property");
2769         RNA_def_struct_ui_text(srna, "Pointer Definition", "RNA pointer property to point to another RNA struct");
2770         rna_def_pointer_property(srna, PROP_POINTER);
2771
2772         /* CollectionProperty */
2773         srna = RNA_def_struct(brna, "CollectionProperty", "Property");
2774         RNA_def_struct_ui_text(srna, "Collection Definition",
2775                                "RNA collection property to define lists, arrays and mappings");
2776         rna_def_pointer_property(srna, PROP_COLLECTION);
2777
2778         /* Function */
2779         rna_def_function(brna);
2780
2781         /* Blender RNA */
2782         srna = RNA_def_struct(brna, "BlenderRNA", NULL);
2783         RNA_def_struct_ui_text(srna, "Blender RNA", "Blender RNA structure definitions");
2784         RNA_def_struct_ui_icon(srna, ICON_RNA);
2785
2786         prop = RNA_def_property(srna, "structs", PROP_COLLECTION, PROP_NONE);
2787         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2788         RNA_def_property_struct_type(prop, "Struct");
2789         RNA_def_property_collection_funcs(prop, "rna_BlenderRNA_structs_begin", "rna_iterator_listbase_next",
2790                                           "rna_iterator_listbase_end", "rna_iterator_listbase_get",
2791                                           /* included for speed, can be removed */
2792 #if 0
2793                                           NULL, NULL, NULL, NULL);
2794 #else
2795                                           "rna_BlenderRNA_structs_length", "rna_BlenderRNA_structs_lookup_int",
2796                                           "rna_BlenderRNA_structs_lookup_string", NULL);
2797 #endif
2798
2799         RNA_def_property_ui_text(prop, "Structs", "");
2800 }
2801
2802 #endif