Merge branch 'master' into blender2.8
[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         IntPropertyRNA *nprop = (IntPropertyRNA *)prop;
755         rna_idproperty_check(&prop, ptr);
756
757         if (nprop->defaultarray) {
758                 memcpy(values, nprop->defaultarray, prop->totarraylength * sizeof(int));
759         }
760         else {
761                 int i;
762                 for (i = 0; i < prop->totarraylength; i++)
763                         values[i] = nprop->defaultvalue;
764         }
765 }
766 static void rna_BoolProperty_default_array_get(PointerRNA *ptr, bool *values)
767 {
768         PropertyRNA *prop = (PropertyRNA *)ptr->data;
769         BoolPropertyRNA *nprop = (BoolPropertyRNA *)prop;
770         rna_idproperty_check(&prop, ptr);
771
772         if (nprop->defaultarray) {
773                 memcpy(values, nprop->defaultarray, prop->totarraylength * sizeof(bool));
774         }
775         else {
776                 int i;
777                 for (i = 0; i < prop->totarraylength; i++)
778                         values[i] = nprop->defaultvalue;
779         }
780 }
781 static void rna_FloatProperty_default_array_get(PointerRNA *ptr, float *values)
782 {
783         PropertyRNA *prop = (PropertyRNA *)ptr->data;
784         FloatPropertyRNA *nprop = (FloatPropertyRNA *)prop;
785         rna_idproperty_check(&prop, ptr);
786
787         if (nprop->defaultarray) {
788                 memcpy(values, nprop->defaultarray, prop->totarraylength * sizeof(float));
789         }
790         else {
791                 int i;
792                 for (i = 0; i < prop->totarraylength; i++)
793                         values[i] = nprop->defaultvalue;
794         }
795 }
796
797 static int rna_IntProperty_hard_min_get(PointerRNA *ptr)
798 {
799         PropertyRNA *prop = (PropertyRNA *)ptr->data;
800         rna_idproperty_check(&prop, ptr);
801         return ((IntPropertyRNA *)prop)->hardmin;
802 }
803
804 static int rna_IntProperty_hard_max_get(PointerRNA *ptr)
805 {
806         PropertyRNA *prop = (PropertyRNA *)ptr->data;
807         rna_idproperty_check(&prop, ptr);
808         return ((IntPropertyRNA *)prop)->hardmax;
809 }
810
811 static int rna_IntProperty_soft_min_get(PointerRNA *ptr)
812 {
813         PropertyRNA *prop = (PropertyRNA *)ptr->data;
814         rna_idproperty_check(&prop, ptr);
815         return ((IntPropertyRNA *)prop)->softmin;
816 }
817
818 static int rna_IntProperty_soft_max_get(PointerRNA *ptr)
819 {
820         PropertyRNA *prop = (PropertyRNA *)ptr->data;
821         rna_idproperty_check(&prop, ptr);
822         return ((IntPropertyRNA *)prop)->softmax;
823 }
824
825 static int rna_IntProperty_step_get(PointerRNA *ptr)
826 {
827         PropertyRNA *prop = (PropertyRNA *)ptr->data;
828         rna_idproperty_check(&prop, ptr);
829         return ((IntPropertyRNA *)prop)->step;
830 }
831
832 static float rna_FloatProperty_default_get(PointerRNA *ptr)
833 {
834         PropertyRNA *prop = (PropertyRNA *)ptr->data;
835         rna_idproperty_check(&prop, ptr);
836         return ((FloatPropertyRNA *)prop)->defaultvalue;
837 }
838 static float rna_FloatProperty_hard_min_get(PointerRNA *ptr)
839 {
840         PropertyRNA *prop = (PropertyRNA *)ptr->data;
841         rna_idproperty_check(&prop, ptr);
842         return ((FloatPropertyRNA *)prop)->hardmin;
843 }
844
845 static float rna_FloatProperty_hard_max_get(PointerRNA *ptr)
846 {
847         PropertyRNA *prop = (PropertyRNA *)ptr->data;
848         rna_idproperty_check(&prop, ptr);
849         return ((FloatPropertyRNA *)prop)->hardmax;
850 }
851
852 static float rna_FloatProperty_soft_min_get(PointerRNA *ptr)
853 {
854         PropertyRNA *prop = (PropertyRNA *)ptr->data;
855         rna_idproperty_check(&prop, ptr);
856         return ((FloatPropertyRNA *)prop)->softmin;
857 }
858
859 static float rna_FloatProperty_soft_max_get(PointerRNA *ptr)
860 {
861         PropertyRNA *prop = (PropertyRNA *)ptr->data;
862         rna_idproperty_check(&prop, ptr);
863         return ((FloatPropertyRNA *)prop)->softmax;
864 }
865
866 static float rna_FloatProperty_step_get(PointerRNA *ptr)
867 {
868         PropertyRNA *prop = (PropertyRNA *)ptr->data;
869         rna_idproperty_check(&prop, ptr);
870         return ((FloatPropertyRNA *)prop)->step;
871 }
872
873 static int rna_FloatProperty_precision_get(PointerRNA *ptr)
874 {
875         PropertyRNA *prop = (PropertyRNA *)ptr->data;
876         rna_idproperty_check(&prop, ptr);
877         return ((FloatPropertyRNA *)prop)->precision;
878 }
879
880 static void rna_StringProperty_default_get(PointerRNA *ptr, char *value)
881 {
882         PropertyRNA *prop = (PropertyRNA *)ptr->data;
883         rna_idproperty_check(&prop, ptr);
884         strcpy(value, ((StringPropertyRNA *)prop)->defaultvalue);
885 }
886 static int rna_StringProperty_default_length(PointerRNA *ptr)
887 {
888         PropertyRNA *prop = (PropertyRNA *)ptr->data;
889         rna_idproperty_check(&prop, ptr);
890         return strlen(((StringPropertyRNA *)prop)->defaultvalue);
891 }
892
893 static int rna_StringProperty_max_length_get(PointerRNA *ptr)
894 {
895         PropertyRNA *prop = (PropertyRNA *)ptr->data;
896         rna_idproperty_check(&prop, ptr);
897         return ((StringPropertyRNA *)prop)->maxlength;
898 }
899
900 static const EnumPropertyItem *rna_EnumProperty_default_itemf(bContext *C, PointerRNA *ptr,
901                                                         PropertyRNA *prop_parent, bool *r_free)
902 {
903         PropertyRNA *prop = (PropertyRNA *)ptr->data;
904         EnumPropertyRNA *eprop;
905
906         rna_idproperty_check(&prop, ptr);
907         eprop = (EnumPropertyRNA *)prop;
908
909         /* incompatible default attributes */
910         if ((prop_parent->flag & PROP_ENUM_FLAG) != (prop->flag & PROP_ENUM_FLAG)) {
911                 return DummyRNA_NULL_items;
912         }
913
914         if ((eprop->itemf == NULL) ||
915             (eprop->itemf == rna_EnumProperty_default_itemf) ||
916             (ptr->type == &RNA_EnumProperty) ||
917             (C == NULL))
918         {
919                 if (eprop->item) {
920                         return eprop->item;
921                 }
922         }
923
924         return eprop->itemf(C, ptr, prop, r_free);
925 }
926
927 /* XXX - not sure this is needed? */
928 static int rna_EnumProperty_default_get(PointerRNA *ptr)
929 {
930         PropertyRNA *prop = (PropertyRNA *)ptr->data;
931         rna_idproperty_check(&prop, ptr);
932         return ((EnumPropertyRNA *)prop)->defaultvalue;
933 }
934
935 static int rna_enum_check_separator(CollectionPropertyIterator *UNUSED(iter), void *data)
936 {
937         EnumPropertyItem *item = (EnumPropertyItem *)data;
938
939         return (item->identifier[0] == 0);
940 }
941
942 static void rna_EnumProperty_items_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
943 {
944         PropertyRNA *prop = (PropertyRNA *)ptr->data;
945         /* EnumPropertyRNA *eprop;  *//* UNUSED */
946         const EnumPropertyItem *item = NULL;
947         int totitem;
948         bool free;
949
950         rna_idproperty_check(&prop, ptr);
951         /* eprop = (EnumPropertyRNA *)prop; */
952
953         RNA_property_enum_items_ex(
954                     NULL, ptr, prop, STREQ(iter->prop->identifier, "enum_items_static"), &item, &totitem, &free);
955         rna_iterator_array_begin(iter, (void *)item, sizeof(EnumPropertyItem), totitem, free, rna_enum_check_separator);
956 }
957
958 static void rna_EnumPropertyItem_identifier_get(PointerRNA *ptr, char *value)
959 {
960         strcpy(value, ((EnumPropertyItem *)ptr->data)->identifier);
961 }
962
963 static int rna_EnumPropertyItem_identifier_length(PointerRNA *ptr)
964 {
965         return strlen(((EnumPropertyItem *)ptr->data)->identifier);
966 }
967
968 static void rna_EnumPropertyItem_name_get(PointerRNA *ptr, char *value)
969 {
970         strcpy(value, ((EnumPropertyItem *)ptr->data)->name);
971 }
972
973 static int rna_EnumPropertyItem_name_length(PointerRNA *ptr)
974 {
975         return strlen(((EnumPropertyItem *)ptr->data)->name);
976 }
977
978 static void rna_EnumPropertyItem_description_get(PointerRNA *ptr, char *value)
979 {
980         EnumPropertyItem *eprop = (EnumPropertyItem *)ptr->data;
981
982         if (eprop->description)
983                 strcpy(value, eprop->description);
984         else
985                 value[0] = '\0';
986 }
987
988 static int rna_EnumPropertyItem_description_length(PointerRNA *ptr)
989 {
990         EnumPropertyItem *eprop = (EnumPropertyItem *)ptr->data;
991
992         if (eprop->description)
993                 return strlen(eprop->description);
994         else
995                 return 0;
996 }
997
998 static int rna_EnumPropertyItem_value_get(PointerRNA *ptr)
999 {
1000         return ((EnumPropertyItem *)ptr->data)->value;
1001 }
1002
1003 static int rna_EnumPropertyItem_icon_get(PointerRNA *ptr)
1004 {
1005         return ((EnumPropertyItem *)ptr->data)->icon;
1006 }
1007
1008 static PointerRNA rna_PointerProperty_fixed_type_get(PointerRNA *ptr)
1009 {
1010         PropertyRNA *prop = (PropertyRNA *)ptr->data;
1011         rna_idproperty_check(&prop, ptr);
1012         return rna_pointer_inherit_refine(ptr, &RNA_Struct, ((PointerPropertyRNA *)prop)->type);
1013 }
1014
1015 static PointerRNA rna_CollectionProperty_fixed_type_get(PointerRNA *ptr)
1016 {
1017         PropertyRNA *prop = (PropertyRNA *)ptr->data;
1018         rna_idproperty_check(&prop, ptr);
1019         return rna_pointer_inherit_refine(ptr, &RNA_Struct, ((CollectionPropertyRNA *)prop)->item_type);
1020 }
1021
1022 /* Function */
1023
1024 static void rna_Function_identifier_get(PointerRNA *ptr, char *value)
1025 {
1026         strcpy(value, ((FunctionRNA *)ptr->data)->identifier);
1027 }
1028
1029 static int rna_Function_identifier_length(PointerRNA *ptr)
1030 {
1031         return strlen(((FunctionRNA *)ptr->data)->identifier);
1032 }
1033
1034 static void rna_Function_description_get(PointerRNA *ptr, char *value)
1035 {
1036         strcpy(value, ((FunctionRNA *)ptr->data)->description);
1037 }
1038
1039 static int rna_Function_description_length(PointerRNA *ptr)
1040 {
1041         return strlen(((FunctionRNA *)ptr->data)->description);
1042 }
1043
1044 static void rna_Function_parameters_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1045 {
1046         rna_iterator_listbase_begin(iter, &((FunctionRNA *)ptr->data)->cont.properties, rna_property_builtin);
1047 }
1048
1049 static bool rna_Function_registered_get(PointerRNA *ptr)
1050 {
1051         FunctionRNA *func = (FunctionRNA *)ptr->data;
1052         return 0 != (func->flag & FUNC_REGISTER);
1053 }
1054
1055 static bool rna_Function_registered_optional_get(PointerRNA *ptr)
1056 {
1057         FunctionRNA *func = (FunctionRNA *)ptr->data;
1058         return 0 != (func->flag & (FUNC_REGISTER_OPTIONAL & ~FUNC_REGISTER));
1059 }
1060
1061 static bool rna_Function_no_self_get(PointerRNA *ptr)
1062 {
1063         FunctionRNA *func = (FunctionRNA *)ptr->data;
1064         return !(func->flag & FUNC_NO_SELF);
1065 }
1066
1067 static int rna_Function_use_self_type_get(PointerRNA *ptr)
1068 {
1069         FunctionRNA *func = (FunctionRNA *)ptr->data;
1070         return 0 != (func->flag & FUNC_USE_SELF_TYPE);
1071 }
1072
1073 /* Blender RNA */
1074
1075 static int rna_struct_is_publc(CollectionPropertyIterator *UNUSED(iter), void *data)
1076 {
1077         StructRNA *srna = data;
1078
1079         return !(srna->flag & STRUCT_PUBLIC_NAMESPACE);
1080 }
1081
1082
1083 static void rna_BlenderRNA_structs_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
1084 {
1085         BlenderRNA *brna = ptr->data;
1086         rna_iterator_listbase_begin(iter, &brna->structs, rna_struct_is_publc);
1087 }
1088
1089 /* optional, for faster lookups */
1090 static int rna_BlenderRNA_structs_length(PointerRNA *ptr)
1091 {
1092         BlenderRNA *brna = ptr->data;
1093         BLI_assert(brna->structs_len == BLI_listbase_count(&brna->structs));
1094         return brna->structs_len;
1095 }
1096 static int rna_BlenderRNA_structs_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
1097 {
1098         BlenderRNA *brna = ptr->data;
1099         StructRNA *srna = index < brna->structs_len ? BLI_findlink(&brna->structs, index) : NULL;
1100         if (srna != NULL) {
1101                 RNA_pointer_create(NULL, &RNA_Struct, srna, r_ptr);
1102                 return true;
1103         }
1104         else {
1105                 return false;
1106         }
1107 }
1108 static int rna_BlenderRNA_structs_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
1109 {
1110         BlenderRNA *brna = ptr->data;
1111         StructRNA *srna = BLI_ghash_lookup(brna->structs_map, (void *)key);
1112         if (srna != NULL) {
1113                 RNA_pointer_create(NULL, &RNA_Struct, srna, r_ptr);
1114                 return true;
1115         }
1116
1117         return false;
1118 }
1119
1120 /* Default override (and compare) callbacks. */
1121
1122 /* Ensures it makes sense to go inside the pointers to compare their content
1123  * (if they are IDs, or have different names or RNA type, then this would be meaningless). */
1124 static bool rna_property_override_diff_propptr_validate_diffing(
1125         PointerRNA *propptr_a, PointerRNA *propptr_b, const bool no_prop_name,
1126         bool *r_is_id, bool *r_is_null, bool *r_is_type_diff,
1127         char **r_propname_a, char *propname_a_buff, size_t propname_a_buff_size,
1128         char **r_propname_b, char *propname_b_buff, size_t propname_b_buff_size)
1129 {
1130         BLI_assert(propptr_a != NULL);
1131
1132         bool is_valid_for_diffing = true;
1133         const bool do_force_name = !no_prop_name && r_propname_a != NULL;
1134
1135         if (do_force_name) {
1136                 BLI_assert(r_propname_a != NULL);
1137                 BLI_assert(r_propname_b != NULL);
1138         }
1139
1140         *r_is_id = *r_is_null = *r_is_type_diff = false;
1141
1142         /* Beware, PointerRNA_NULL has no type and is considered a 'blank page'! */
1143         if (propptr_a->type == NULL) {
1144                 if (propptr_b == NULL || propptr_b->type == NULL) {
1145                         *r_is_null = true;
1146                 }
1147                 else {
1148                         *r_is_id = RNA_struct_is_ID(propptr_b->type);
1149                         *r_is_null = true;
1150                         *r_is_type_diff = true;
1151                 }
1152                 is_valid_for_diffing = false;
1153         }
1154         else {
1155                 *r_is_id = RNA_struct_is_ID(propptr_a->type);
1156                 *r_is_null = *r_is_type_diff = (ELEM(NULL, propptr_b, propptr_b->type));
1157                 is_valid_for_diffing = !(*r_is_id || *r_is_null);
1158         }
1159
1160         if (propptr_b == NULL || propptr_a->type != propptr_b->type) {
1161                 *r_is_type_diff = true;
1162                 is_valid_for_diffing = false;
1163 //              printf("%s: different pointer RNA types\n", rna_path ? rna_path : "<UNKNOWN>");
1164         }
1165
1166         /* We do a generic quick first comparison checking for "name" and/or "type" properties.
1167          * We assume that is any of those are false, then we are not handling the same data.
1168          * This helps a lot in static override case, especially to detect inserted items in collections. */
1169         if (!no_prop_name && (is_valid_for_diffing || do_force_name)) {
1170                 PropertyRNA *nameprop_a = RNA_struct_name_property(propptr_a->type);
1171                 PropertyRNA *nameprop_b = (propptr_b != NULL) ? RNA_struct_name_property(propptr_b->type) : NULL;
1172
1173                 int propname_a_len = 0, propname_b_len = 0;
1174                 char *propname_a = NULL;
1175                 char *propname_b = NULL;
1176                 char buff_a[4096];
1177                 char buff_b[4096];
1178                 if (nameprop_a != NULL) {
1179                         if (r_propname_a == NULL && propname_a_buff == NULL) {
1180                                 propname_a_buff = buff_a;
1181                                 propname_a_buff_size = sizeof(buff_a);
1182                         }
1183
1184                         propname_a = RNA_property_string_get_alloc(
1185                                          propptr_a, nameprop_a, propname_a_buff, propname_a_buff_size, &propname_a_len);
1186 //                      printf("propname_a = %s\n", propname_a ? propname_a : "<NONE>");
1187
1188                         if (r_propname_a != NULL) {
1189                                 *r_propname_a = propname_a;
1190                         }
1191                 }
1192 //              else printf("item of type %s a has no name property!\n", propptr_a->type->name);
1193                 if (nameprop_b != NULL) {
1194                         if (r_propname_b == NULL && propname_b_buff == NULL) {
1195                                 propname_b_buff = buff_b;
1196                                 propname_b_buff_size = sizeof(buff_b);
1197                         }
1198
1199                         propname_b = RNA_property_string_get_alloc(
1200                                          propptr_b, nameprop_b, propname_b_buff, propname_b_buff_size, &propname_b_len);
1201
1202                         if (r_propname_b != NULL) {
1203                                 *r_propname_b = propname_b;
1204                         }
1205                 }
1206                 if (propname_a != NULL && propname_b != NULL) {
1207                         if (propname_a_len != propname_b_len ||
1208                             propname_a[0] != propname_b[0] ||
1209                             !STREQ(propname_a, propname_b))
1210                         {
1211                                 is_valid_for_diffing = false;
1212 //                              printf("%s: different names\n", rna_path ? rna_path : "<UNKNOWN>");
1213                         }
1214                 }
1215         }
1216
1217         if (*r_is_id) {
1218                 BLI_assert(propptr_a->data == propptr_a->id.data && propptr_b->data == propptr_b->id.data);
1219         }
1220
1221         return is_valid_for_diffing;
1222 }
1223
1224 /* Used for both Pointer and Collection properties. */
1225 static int rna_property_override_diff_propptr(
1226         Main *bmain,
1227         PointerRNA *propptr_a, PointerRNA *propptr_b,
1228         eRNACompareMode mode, const bool no_ownership, const bool no_prop_name,
1229         IDOverrideStatic *override, const char *rna_path, const int flags, bool *r_override_changed)
1230 {
1231         const bool do_create = override != NULL && (flags & RNA_OVERRIDE_COMPARE_CREATE) != 0 && rna_path != NULL;
1232
1233         bool is_id = false;
1234         bool is_null = false;
1235         bool is_type_diff = false;
1236         /* If false, it means that the whole data itself is different, so no point in going inside of it at all! */
1237         bool is_valid_for_diffing = rna_property_override_diff_propptr_validate_diffing(
1238                                         propptr_a, propptr_b, no_prop_name, &is_id, &is_null, &is_type_diff,
1239                                         NULL, NULL, 0, NULL, NULL, 0);
1240
1241         if (is_id) {
1242                 BLI_assert(no_ownership);  /* For now, once we deal with nodetrees we'll want to get rid of that one. */
1243         }
1244
1245         if (override) {
1246                 if (no_ownership /* || is_id */ || is_null || is_type_diff || !is_valid_for_diffing) {
1247                         /* In case this pointer prop does not own its data (or one is NULL), do not compare structs!
1248                          * This is a quite safe path to infinite loop, among other nasty issues.
1249                          * Instead, just compare pointers themselves. */
1250                         const int comp = (propptr_a->data != propptr_b->data);
1251
1252                         if (do_create && comp != 0) {
1253                                 bool created = false;
1254                                 IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1255
1256                                 if (op != NULL && created) {  /* If not yet overridden... */
1257                                         BKE_override_static_property_operation_get(
1258                                                     op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
1259                                         if (r_override_changed) {
1260                                                 *r_override_changed = created;
1261                                         }
1262                                 }
1263                         }
1264
1265                         return comp;
1266                 }
1267                 else {
1268                         eRNAOverrideMatchResult report_flags = 0;
1269                         const bool match = RNA_struct_override_matches(
1270                                                bmain, propptr_a, propptr_b, rna_path, override, flags, &report_flags);
1271                         if (r_override_changed && (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) != 0) {
1272                                 *r_override_changed = true;
1273                         }
1274                         return !match;
1275                 }
1276         }
1277         else {
1278                 /* We could also use is_diff_pointer, but then we potentially lose the gt/lt info -
1279                  * and don't think performances are critical here for now anyway... */
1280                 return !RNA_struct_equals(bmain, propptr_a, propptr_b, mode);
1281         }
1282 }
1283
1284
1285
1286 #define RNA_PROPERTY_GET_SINGLE(_typename, _ptr, _prop, _index) \
1287         (is_array ? RNA_property_##_typename##_get_index((_ptr), (_prop), (_index)) : \
1288                     RNA_property_##_typename##_get((_ptr), (_prop)))
1289 #define RNA_PROPERTY_SET_SINGLE(_typename, _ptr, _prop, _index, _value) \
1290         (is_array ? RNA_property_##_typename##_set_index((_ptr), (_prop), (_index), (_value)) : \
1291                     RNA_property_##_typename##_set((_ptr), (_prop), (_value)))
1292
1293 int rna_property_override_diff_default(
1294         Main *bmain,
1295         PointerRNA *ptr_a, PointerRNA *ptr_b,
1296         PropertyRNA *prop_a, PropertyRNA *prop_b,
1297         const int len_a, const int len_b,
1298         const int mode,
1299         IDOverrideStatic *override, const char *rna_path,
1300         const int flags, bool *r_override_changed)
1301 {
1302         BLI_assert(len_a == len_b);
1303
1304         /* Note: at this point, we are sure that when len_a is zero, we are not handling an (empty) array. */
1305
1306         const bool do_create = override != NULL && (flags & RNA_OVERRIDE_COMPARE_CREATE) != 0 && rna_path != NULL;
1307
1308         switch (RNA_property_type(prop_a)) {
1309                 case PROP_BOOLEAN:
1310                 {
1311                         if (len_a) {
1312                                 bool array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
1313                                 bool *array_a, *array_b;
1314
1315                                 array_a = (len_a > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(bool) * len_a, "RNA equals") : array_stack_a;
1316                                 array_b = (len_b > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(bool) * len_b, "RNA equals") : array_stack_b;
1317
1318                                 RNA_property_boolean_get_array(ptr_a, prop_a, array_a);
1319                                 RNA_property_boolean_get_array(ptr_b, prop_b, array_b);
1320
1321                                 const int comp = memcmp(array_a, array_b, sizeof(bool) * len_a);
1322
1323                                 if (do_create && comp != 0) {
1324                                         /* XXX TODO this will have to be refined to handle array items */
1325                                         bool created = false;
1326                                         IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1327
1328                                         if (op != NULL && created) {
1329                                                 BKE_override_static_property_operation_get(
1330                                                             op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
1331                                                 if (r_override_changed) {
1332                                                         *r_override_changed = created;
1333                                                 }
1334                                         }
1335                                         else {
1336                                                 /* Already overridden prop, we'll have to check arrays items etc. */
1337                                         }
1338                                 }
1339
1340                                 if (array_a != array_stack_a) MEM_freeN(array_a);
1341                                 if (array_b != array_stack_b) MEM_freeN(array_b);
1342
1343                                 return comp;
1344                         }
1345                         else {
1346                                 const bool value_a = RNA_property_boolean_get(ptr_a, prop_a);
1347                                 const bool value_b = RNA_property_boolean_get(ptr_b, prop_b);
1348                                 const int comp = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0;
1349
1350                                 if (do_create && comp != 0) {
1351                                         bool created = false;
1352                                         IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1353
1354                                         if (op != NULL && created) {  /* If not yet overridden... */
1355                                                 BKE_override_static_property_operation_get(
1356                                                             op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
1357                                                 if (r_override_changed) {
1358                                                         *r_override_changed = created;
1359                                                 }
1360                                         }
1361                                 }
1362
1363                                 return comp;
1364                         }
1365                 }
1366
1367                 case PROP_INT:
1368                 {
1369                         if (len_a) {
1370                                 int array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
1371                                 int *array_a, *array_b;
1372
1373                                 array_a = (len_a > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(int) * len_a, "RNA equals") : array_stack_a;
1374                                 array_b = (len_b > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(int) * len_b, "RNA equals") : array_stack_b;
1375
1376                                 RNA_property_int_get_array(ptr_a, prop_a, array_a);
1377                                 RNA_property_int_get_array(ptr_b, prop_b, array_b);
1378
1379                                 const int comp = memcmp(array_a, array_b, sizeof(int) * len_a);
1380
1381                                 if (do_create && comp != 0) {
1382                                         /* XXX TODO this will have to be refined to handle array items */
1383                                         bool created = false;
1384                                         IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1385
1386                                         if (op != NULL && created) {
1387                                                 BKE_override_static_property_operation_get(
1388                                                             op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
1389                                                 if (r_override_changed) {
1390                                                         *r_override_changed = created;
1391                                                 }
1392                                         }
1393                                         else {
1394                                                 /* Already overridden prop, we'll have to check arrays items etc. */
1395                                         }
1396                                 }
1397
1398                                 if (array_a != array_stack_a) MEM_freeN(array_a);
1399                                 if (array_b != array_stack_b) MEM_freeN(array_b);
1400
1401                                 return comp;
1402                         }
1403                         else {
1404                                 const int value_a = RNA_property_int_get(ptr_a, prop_a);
1405                                 const int value_b = RNA_property_int_get(ptr_b, prop_b);
1406                                 const int comp = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0;
1407
1408                                 if (do_create && comp != 0) {
1409                                         bool created = false;
1410                                         IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1411
1412                                         if (op != NULL && created) {  /* If not yet overridden... */
1413                                                 BKE_override_static_property_operation_get(
1414                                                             op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
1415                                                 if (r_override_changed) {
1416                                                         *r_override_changed = created;
1417                                                 }
1418                                         }
1419                                 }
1420
1421                                 return comp;
1422                         }
1423                 }
1424
1425                 case PROP_FLOAT:
1426                 {
1427                         if (len_a) {
1428                                 float array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
1429                                 float *array_a, *array_b;
1430
1431                                 array_a = (len_a > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(float) * len_a, "RNA equals") : array_stack_a;
1432                                 array_b = (len_b > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(float) * len_b, "RNA equals") : array_stack_b;
1433
1434                                 RNA_property_float_get_array(ptr_a, prop_a, array_a);
1435                                 RNA_property_float_get_array(ptr_b, prop_b, array_b);
1436
1437                                 const int comp = memcmp(array_a, array_b, sizeof(float) * len_a);
1438
1439                                 if (do_create && comp != 0) {
1440                                         /* XXX TODO this will have to be refined to handle array items */
1441                                         bool created = false;
1442                                         IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1443
1444                                         if (op != NULL && created) {
1445                                                 BKE_override_static_property_operation_get(
1446                                                             op, IDOVERRIDESTATIC_OP_REPLACE,
1447                                                             NULL, NULL, -1, -1, true, NULL, NULL);
1448                                                 if (r_override_changed) {
1449                                                         *r_override_changed = created;
1450                                                 }
1451                                         }
1452                                         else {
1453                                                 /* Already overridden prop, we'll have to check arrays items etc. */
1454                                         }
1455                                 }
1456
1457                                 if (array_a != array_stack_a) MEM_freeN(array_a);
1458                                 if (array_b != array_stack_b) MEM_freeN(array_b);
1459
1460                                 return comp;
1461                         }
1462                         else {
1463                                 const float value_a = RNA_property_float_get(ptr_a, prop_a);
1464                                 const float value_b = RNA_property_float_get(ptr_b, prop_b);
1465                                 const int comp = (value_a < value_b) ? -1 : (value_a > value_b) ? 1 : 0;
1466
1467                                 if (do_create && comp != 0) {
1468                                         bool created = false;
1469                                         IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1470
1471                                         if (op != NULL && created) {  /* If not yet overridden... */
1472                                                 BKE_override_static_property_operation_get(
1473                                                             op, IDOVERRIDESTATIC_OP_REPLACE,
1474                                                             NULL, NULL, -1, -1, true, NULL, NULL);
1475                                                 if (r_override_changed) {
1476                                                         *r_override_changed = created;
1477                                                 }
1478                                         }
1479                                 }
1480
1481                                 return comp ;
1482                         }
1483                 }
1484
1485                 case PROP_ENUM:
1486                 {
1487                         const int value_a = RNA_property_enum_get(ptr_a, prop_a);
1488                         const int value_b = RNA_property_enum_get(ptr_b, prop_b);
1489                         const int comp = value_a != value_b;
1490
1491                         if (do_create && comp != 0) {
1492                                 bool created = false;
1493                                 IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1494
1495                                 if (op != NULL && created) {  /* If not yet overridden... */
1496                                         BKE_override_static_property_operation_get(
1497                                                     op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
1498                                         if (r_override_changed) {
1499                                                 *r_override_changed = created;
1500                                         }
1501                                 }
1502                         }
1503
1504                         return comp;
1505                 }
1506
1507                 case PROP_STRING:
1508                 {
1509                         char fixed_a[4096], fixed_b[4096];
1510                         int len_str_a, len_str_b;
1511                         char *value_a = RNA_property_string_get_alloc(ptr_a, prop_a, fixed_a, sizeof(fixed_a), &len_str_a);
1512                         char *value_b = RNA_property_string_get_alloc(ptr_b, prop_b, fixed_b, sizeof(fixed_b), &len_str_b);
1513                         /* TODO we could do a check on length too, but then we would not have a 'real' string comparison...
1514                          * Maybe behind a eRNAOverrideMatch flag? */
1515 //                      const int comp = len_str_a < len_str_b ? -1 : len_str_a > len_str_b ? 1 : strcmp(value_a, value_b);
1516                         const int comp = strcmp(value_a, value_b);
1517
1518                         if (do_create && comp != 0) {
1519                                 bool created = false;
1520                                 IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1521
1522                                 if (op != NULL && created) {  /* If not yet overridden... */
1523                                         BKE_override_static_property_operation_get(
1524                                                     op, IDOVERRIDESTATIC_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL);
1525                                         if (r_override_changed) {
1526                                                 *r_override_changed = created;
1527                                         }
1528                                 }
1529                         }
1530
1531                         if (value_a != fixed_a) MEM_freeN(value_a);
1532                         if (value_b != fixed_b) MEM_freeN(value_b);
1533
1534                         return comp;
1535                 }
1536
1537                 case PROP_POINTER:
1538                 {
1539                         if (STREQ(RNA_property_identifier(prop_a), "rna_type")) {
1540                                 /* Dummy 'pass' answer, this is a meta-data and must be ignored... */
1541                                 return 0;
1542                         }
1543                         else {
1544                                 PointerRNA propptr_a = RNA_property_pointer_get(ptr_a, prop_a);
1545                                 PointerRNA propptr_b = RNA_property_pointer_get(ptr_b, prop_b);
1546                                 const bool no_ownership = (RNA_property_flag(prop_a) & PROP_PTR_NO_OWNERSHIP) != 0;
1547                                 const bool no_prop_name = (RNA_property_override_flag(prop_a) & PROPOVERRIDE_NO_PROP_NAME) != 0;
1548                                 return rna_property_override_diff_propptr(
1549                                             bmain,
1550                                             &propptr_a, &propptr_b, mode, no_ownership, no_prop_name,
1551                                             override, rna_path, flags, r_override_changed);
1552                         }
1553                         break;
1554                 }
1555
1556                 case PROP_COLLECTION:
1557                 {
1558                         /* Note: we assume we only insert in ptr_a (i.e. we can only get new items in ptr_a),
1559                          * and that we never remove anything. */
1560                         const bool use_insertion = (RNA_property_override_flag(prop_a) & PROPOVERRIDE_STATIC_INSERTION) && do_create;
1561                         const bool no_prop_name = (RNA_property_override_flag(prop_a) & PROPOVERRIDE_NO_PROP_NAME) != 0;
1562                         bool equals = true;
1563                         bool abort = false;
1564                         bool is_first_insert = true;
1565                         int idx_a = 0;
1566                         int idx_b = 0;
1567
1568 #define RNA_PATH_BUFFSIZE 8192
1569
1570                         char extended_rna_path_buffer[RNA_PATH_BUFFSIZE];
1571                         char *extended_rna_path = extended_rna_path_buffer;
1572
1573 #define RNA_PATH_PRINTF(_str, ...) \
1574                         if (BLI_snprintf(extended_rna_path_buffer, RNA_PATH_BUFFSIZE, \
1575                                          (_str), __VA_ARGS__) >= RNA_PATH_BUFFSIZE - 1) \
1576                         { extended_rna_path = BLI_sprintfN((_str), __VA_ARGS__); }(void)0
1577 #define RNA_PATH_FREE() \
1578                         if (extended_rna_path != extended_rna_path_buffer) MEM_freeN(extended_rna_path)
1579
1580                         CollectionPropertyIterator iter_a, iter_b;
1581                         RNA_property_collection_begin(ptr_a, prop_a, &iter_a);
1582                         RNA_property_collection_begin(ptr_b, prop_b, &iter_b);
1583
1584                         char buff_a[4096];
1585                         char buff_prev_a[4096] = {0};
1586                         char buff_b[4096];
1587                         char *propname_a = NULL;
1588                         char *prev_propname_a = buff_prev_a;
1589                         char *propname_b = NULL;
1590
1591                         for (; iter_a.valid && !abort; ) {
1592                                 bool is_valid_for_diffing;
1593                                 bool is_valid_for_insertion;
1594                                 do {
1595                                         bool is_id = false, is_null = false, is_type_diff = false;
1596
1597                                         is_valid_for_insertion = use_insertion;
1598
1599                                         /* If false, it means that the whole data itself is different, so no point in going inside of it at all! */
1600                                         if (iter_b.valid) {
1601                                                 is_valid_for_diffing = rna_property_override_diff_propptr_validate_diffing(
1602                                                                            &iter_a.ptr, &iter_b.ptr, no_prop_name,
1603                                                                            &is_id, &is_null, &is_type_diff,
1604                                                                            &propname_a, buff_a, sizeof(buff_a),
1605                                                                            &propname_b, buff_b, sizeof(buff_b));
1606                                         }
1607                                         else {
1608                                                 is_valid_for_diffing = false;
1609                                                 if (is_valid_for_insertion) {
1610                                                         /* We still need propname from 'a' item... */
1611                                                         rna_property_override_diff_propptr_validate_diffing(
1612                                                                     &iter_a.ptr, NULL, no_prop_name,
1613                                                                     &is_id, &is_null, &is_type_diff,
1614                                                                     &propname_a, buff_a, sizeof(buff_a),
1615                                                                     &propname_b, buff_b, sizeof(buff_b));
1616                                                 }
1617                                         }
1618
1619                                         /* We do not support insertion of IDs for now, neither handle NULL pointers. */
1620                                         if (is_id || is_valid_for_diffing) {
1621                                                 is_valid_for_insertion = false;
1622                                         }
1623
1624 #if 0
1625                                         if (rna_path) {
1626                                                 printf("Checking %s, %s [%d] vs %s [%d]; is_id: %d, diffing: %d; "
1627                                                        "insert: %d (could be used: %d, do_create: %d)\n",
1628                                                        rna_path, propname_a ? propname_a : "", idx_a, propname_b ? propname_b : "", idx_b,
1629                                                        is_id, is_valid_for_diffing, is_valid_for_insertion,
1630                                                        (RNA_property_override_flag(prop_a) & PROPOVERRIDE_STATIC_INSERTION) != 0, do_create);
1631                                         }
1632 #endif
1633
1634                                         if (!(is_id || is_valid_for_diffing || is_valid_for_insertion)) {
1635                                                 /* Differences we cannot handle, we can break here
1636                                                  * (we do not support replacing ID pointers in collections e.g.). */
1637                                                 equals = false;
1638                                                 abort = true;
1639                                                 break;
1640                                         }
1641
1642                                         /* There may be a propname defined in some cases, while no actual name set
1643                                          * (e.g. happens with point cache), in that case too we want to fall back to index.
1644                                          * Note that we do not need the RNA path for insertion operations. */
1645                                         if (is_id || is_valid_for_diffing) {
1646                                                 if ((propname_a != NULL && propname_a[0] != '\0') &&
1647                                                     (propname_b != NULL && propname_b[0] != '\0'))
1648                                                 {
1649                                                         if (rna_path) {
1650                                                                 /* In case of name, either it is valid for diffing, and _a and _b are identical,
1651                                                                  * or it is valid for insertion, and we need to use _a. */
1652                                                                 char esc_item_name[RNA_PATH_BUFFSIZE];
1653                                                                 BLI_strescape(esc_item_name, propname_a, RNA_PATH_BUFFSIZE);
1654                                                                 RNA_PATH_PRINTF("%s[\"%s\"]", rna_path, esc_item_name);
1655                                                         }
1656                                                 }
1657                                                 else {  /* Based on index... */
1658                                                         if (rna_path) {
1659                                                                 /* In case of indices, we need _a one for insertion, but _b ones for in-depth diffing.
1660                                                                  * Insertion always happen once all 'replace' operations have been done,
1661                                                                  * otherwise local and reference paths for those would have to be different! */
1662                                                                 RNA_PATH_PRINTF("%s[%d]", rna_path, is_valid_for_insertion ? idx_a : idx_b);
1663                                                         }
1664                                                 }
1665                                         }
1666
1667                                         /* Collections do not support replacement of their data (since they do not support removing),
1668                                          * only in *some* cases, insertion.
1669                                          * We also assume then that _a data is the one where things are inserted. */
1670                                         if (is_valid_for_insertion && use_insertion) {
1671                                                 bool created;
1672                                                 IDOverrideStaticProperty *op = BKE_override_static_property_get(override, rna_path, &created);
1673
1674                                                 if (is_first_insert) {
1675                                                         /* We need to clean up all possible existing insertion operations, otherwise we'd end up
1676                                                          * with a mess of ops everytime something changes. */
1677                                                         for (IDOverrideStaticPropertyOperation *opop = op->operations.first;
1678                                                              opop != NULL;)
1679                                                         {
1680                                                                 IDOverrideStaticPropertyOperation *opop_next = opop->next;
1681                                                                 if (ELEM(opop->operation,
1682                                                                          IDOVERRIDESTATIC_OP_INSERT_AFTER, IDOVERRIDESTATIC_OP_INSERT_BEFORE))
1683                                                                 {
1684                                                                         BKE_override_static_property_operation_delete(op, opop);
1685                                                                 }
1686                                                                 opop = opop_next;
1687                                                         }
1688                                                         is_first_insert = false;
1689                                                 }
1690
1691                                                 BKE_override_static_property_operation_get(
1692                                                             op, IDOVERRIDESTATIC_OP_INSERT_AFTER,
1693                                                             NULL, prev_propname_a, -1, idx_a - 1, true, NULL, NULL);
1694 //                                              printf("%s: Adding insertion op override after '%s'/%d\n", rna_path, prev_propname_a, idx_a - 1);
1695                                         }
1696                                         else if (is_id || is_valid_for_diffing) {
1697                                                 if (equals || do_create) {
1698                                                         const bool no_ownership = (RNA_property_flag(prop_a) & PROP_PTR_NO_OWNERSHIP) != 0;
1699                                                         const int eq = rna_property_override_diff_propptr(
1700                                                                            bmain,
1701                                                                            &iter_a.ptr, &iter_b.ptr, mode, no_ownership, no_prop_name,
1702                                                                            override, extended_rna_path, flags, r_override_changed);
1703                                                         equals = equals && eq;
1704                                                 }
1705                                         }
1706
1707                                         if (prev_propname_a != buff_prev_a) {
1708                                                 MEM_freeN(prev_propname_a);
1709                                                 prev_propname_a = buff_prev_a;
1710                                         }
1711                                         prev_propname_a[0] = '\0';
1712                                         if (propname_a != NULL &&
1713                                             BLI_strncpy_rlen(prev_propname_a, propname_a, sizeof(buff_prev_a)) >= sizeof(buff_prev_a) - 1)
1714                                         {
1715                                                 prev_propname_a = BLI_strdup(propname_a);
1716                                         }
1717                                         if (propname_a != buff_a) {
1718                                                 MEM_SAFE_FREE(propname_a);
1719                                                 propname_a = buff_a;
1720                                         }
1721                                         propname_a[0] = '\0';
1722                                         if (propname_b != buff_b) {
1723                                                 MEM_SAFE_FREE(propname_b);
1724                                                 propname_b = buff_b;
1725                                         }
1726                                         propname_b[0] = '\0';
1727                                         RNA_PATH_FREE();
1728
1729                                         if (!do_create && !equals) {
1730                                                 abort = true;  /* Early out in case we do not want to loop over whole collection. */
1731                                                 break;
1732                                         }
1733
1734                                         if (!(use_insertion && !(is_id || is_valid_for_diffing))) {
1735                                                 break;
1736                                         }
1737
1738                                         if (iter_a.valid) {
1739                                                 RNA_property_collection_next(&iter_a);
1740                                                 idx_a++;
1741                                         }
1742                                 } while (iter_a.valid);
1743
1744                                 if (iter_a.valid) {
1745                                         RNA_property_collection_next(&iter_a);
1746                                         idx_a++;
1747                                 }
1748                                 if (iter_b.valid) {
1749                                         RNA_property_collection_next(&iter_b);
1750                                         idx_b++;
1751                                 }
1752
1753 #undef RNA_PATH_BUFFSIZE
1754 #undef RNA_PATH_PRINTF
1755 #undef RNA_PATH_FREE
1756                         }
1757
1758                         equals = equals && !(iter_a.valid || iter_b.valid) && !abort;  /* Not same number of items in both collections... */
1759                         RNA_property_collection_end(&iter_a);
1760                         RNA_property_collection_end(&iter_b);
1761
1762                         return (equals == false);
1763                 }
1764
1765                 default:
1766                         break;
1767         }
1768
1769         return 0;
1770 }
1771
1772 bool rna_property_override_store_default(
1773         Main *UNUSED(bmain),
1774         PointerRNA *ptr_local, PointerRNA *ptr_reference, PointerRNA *ptr_storage,
1775         PropertyRNA *prop_local, PropertyRNA *prop_reference, PropertyRNA *prop_storage,
1776         const int len_local, const int len_reference, const int len_storage,
1777         IDOverrideStaticPropertyOperation *opop)
1778 {
1779         BLI_assert(len_local == len_reference && (!ptr_storage || len_local == len_storage));
1780         UNUSED_VARS_NDEBUG(len_reference, len_storage);
1781
1782         bool changed = false;
1783         const bool is_array = len_local > 0;
1784         const int index = is_array ? opop->subitem_reference_index : 0;
1785
1786         if (!ELEM(opop->operation, IDOVERRIDESTATIC_OP_ADD, IDOVERRIDESTATIC_OP_SUBTRACT, IDOVERRIDESTATIC_OP_MULTIPLY)) {
1787                 return changed;
1788         }
1789
1790         /* XXX TODO About range limits.
1791          * Ideally, it would be great to get rid of RNA range in that specific case.
1792          * However, this won't be that easy and will add yet another layer of complexity in generated code,
1793          * not to mention that we could most likely *not* bypass custom setters anyway.
1794          * So for now, if needed second operand value is not in valid range, we simply fall back
1795          * to a mere REPLACE operation.
1796          * Time will say whether this is acceptable limitation or not. */
1797         switch (RNA_property_type(prop_local)) {
1798                 case PROP_BOOLEAN:
1799                         /* TODO support boolean ops? Really doubt this would ever be useful though... */
1800                         BLI_assert(0 && "Boolean properties support no override diff operation");
1801                         break;
1802                 case PROP_INT:
1803                 {
1804                         int prop_min, prop_max;
1805                         RNA_property_int_range(ptr_local, prop_local, &prop_min, &prop_max);
1806
1807                         if (is_array && index == -1) {
1808                                 int array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
1809                                 int *array_a, *array_b;
1810
1811                                 array_a = (len_local > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_local, __func__) : array_stack_a;
1812                                 RNA_property_int_get_array(ptr_reference, prop_reference, array_a);
1813
1814                                 switch (opop->operation) {
1815                                         case IDOVERRIDESTATIC_OP_ADD:
1816                                         case IDOVERRIDESTATIC_OP_SUBTRACT:
1817                                         {
1818                                                 const int fac = opop->operation == IDOVERRIDESTATIC_OP_ADD ? 1 : -1;
1819                                                 const int other_op = opop->operation == IDOVERRIDESTATIC_OP_ADD ? IDOVERRIDESTATIC_OP_SUBTRACT : IDOVERRIDESTATIC_OP_ADD;
1820                                                 bool do_set = true;
1821                                                 array_b = (len_local > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_local, __func__) : array_stack_b;
1822                                                 RNA_property_int_get_array(ptr_local, prop_local, array_b);
1823                                                 for (int i = len_local; i--;) {
1824                                                         array_b[i] = fac * (array_b[i] - array_a[i]);
1825                                                         if (array_b[i] < prop_min || array_b[i] > prop_max) {
1826                                                                 opop->operation = other_op;
1827                                                                 for (int j = len_local; j--;) {
1828                                                                         array_b[j] = j >= i ? -array_b[j] : fac * (array_a[j] - array_b[j]);
1829                                                                         if (array_b[j] < prop_min || array_b[j] > prop_max) {
1830                                                                                 /* We failed to  find a suitable diff op,
1831                                                                                  * fall back to plain REPLACE one. */
1832                                                                                 opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
1833                                                                                 do_set = false;
1834                                                                                 break;
1835                                                                         }
1836                                                                 }
1837                                                                 break;
1838                                                         }
1839                                                 }
1840                                                 if (do_set) {
1841                                                         changed = true;
1842                                                         RNA_property_int_set_array(ptr_storage, prop_storage, array_b);
1843                                                 }
1844                                                 if (array_b != array_stack_b) MEM_freeN(array_b);
1845                                                 break;
1846                                         }
1847                                         default:
1848                                                 BLI_assert(0 && "Unsupported RNA override diff operation on integer");
1849                                                 break;
1850                                 }
1851
1852                                 if (array_a != array_stack_a) MEM_freeN(array_a);
1853                         }
1854                         else {
1855                                 const int value = RNA_PROPERTY_GET_SINGLE(int, ptr_reference, prop_reference, index);
1856
1857                                 switch (opop->operation) {
1858                                         case IDOVERRIDESTATIC_OP_ADD:
1859                                         case IDOVERRIDESTATIC_OP_SUBTRACT:
1860                                         {
1861                                                 const int fac = opop->operation == IDOVERRIDESTATIC_OP_ADD ? 1 : -1;
1862                                                 const int other_op = opop->operation == IDOVERRIDESTATIC_OP_ADD ? IDOVERRIDESTATIC_OP_SUBTRACT : IDOVERRIDESTATIC_OP_ADD;
1863                                                 int b = fac * (RNA_PROPERTY_GET_SINGLE(int, ptr_local, prop_local, index) - value);
1864                                                 if (b < prop_min || b > prop_max) {
1865                                                         opop->operation = other_op;
1866                                                         b = -b;
1867                                                         if (b < prop_min || b > prop_max) {
1868                                                                 opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
1869                                                                 break;
1870                                                         }
1871                                                 }
1872                                                 changed = true;
1873                                                 RNA_PROPERTY_SET_SINGLE(int, ptr_storage, prop_storage, index, b);
1874                                                 break;
1875                                         }
1876                                         default:
1877                                                 BLI_assert(0 && "Unsupported RNA override diff operation on integer");
1878                                                 break;
1879                                 }
1880                         }
1881                         break;
1882                 }
1883                 case PROP_FLOAT:
1884                 {
1885                         float prop_min, prop_max;
1886                         RNA_property_float_range(ptr_local, prop_local, &prop_min, &prop_max);
1887
1888                         if (is_array && index == -1) {
1889                                 float array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
1890                                 float *array_a, *array_b;
1891
1892                                 array_a = (len_local > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_local, __func__) : array_stack_a;
1893
1894                                 RNA_property_float_get_array(ptr_reference, prop_reference, array_a);
1895                                 switch (opop->operation) {
1896                                         case IDOVERRIDESTATIC_OP_ADD:
1897                                         case IDOVERRIDESTATIC_OP_SUBTRACT:
1898                                         {
1899                                                 const float fac = opop->operation == IDOVERRIDESTATIC_OP_ADD ? 1.0 : -1.0;
1900                                                 const int other_op = opop->operation == IDOVERRIDESTATIC_OP_ADD ? IDOVERRIDESTATIC_OP_SUBTRACT : IDOVERRIDESTATIC_OP_ADD;
1901                                                 bool do_set = true;
1902                                                 array_b = (len_local > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_local, __func__) : array_stack_b;
1903                                                 RNA_property_float_get_array(ptr_local, prop_local, array_b);
1904                                                 for (int i = len_local; i--;) {
1905                                                         array_b[i] = fac * (array_b[i] - array_a[i]);
1906                                                         if (array_b[i] < prop_min || array_b[i] > prop_max) {
1907                                                                 opop->operation = other_op;
1908                                                                 for (int j = len_local; j--;) {
1909                                                                         array_b[j] = j >= i ? -array_b[j] : fac * (array_a[j] - array_b[j]);
1910                                                                         if (array_b[j] < prop_min || array_b[j] > prop_max) {
1911                                                                                 /* We failed to  find a suitable diff op,
1912                                                                                  * fall back to plain REPLACE one. */
1913                                                                                 opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
1914                                                                                 do_set = false;
1915                                                                                 break;
1916                                                                         }
1917                                                                 }
1918                                                                 break;
1919                                                         }
1920                                                 }
1921                                                 if (do_set) {
1922                                                         changed = true;
1923                                                         RNA_property_float_set_array(ptr_storage, prop_storage, array_b);
1924                                                 }
1925                                                 if (array_b != array_stack_b) MEM_freeN(array_b);
1926                                                 break;
1927                                         }
1928                                         case IDOVERRIDESTATIC_OP_MULTIPLY:
1929                                         {
1930                                                 bool do_set = true;
1931                                                 array_b = (len_local > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_local, __func__) : array_stack_b;
1932                                                 RNA_property_float_get_array(ptr_local, prop_local, array_b);
1933                                                 for (int i = len_local; i--;) {
1934                                                         array_b[i] = array_a[i] == 0.0f ? array_b[i] : array_b[i] / array_a[i];
1935                                                         if (array_b[i] < prop_min || array_b[i] > prop_max) {
1936                                                                 opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
1937                                                                 do_set = false;
1938                                                                 break;
1939                                                         }
1940                                                 }
1941                                                 if (do_set) {
1942                                                         changed = true;
1943                                                         RNA_property_float_set_array(ptr_storage, prop_storage, array_b);
1944                                                 }
1945                                                 if (array_b != array_stack_b) MEM_freeN(array_b);
1946                                                 break;
1947                                         }
1948                                         default:
1949                                                 BLI_assert(0 && "Unsupported RNA override diff operation on float");
1950                                                 break;
1951                                 }
1952
1953                                 if (array_a != array_stack_a) MEM_freeN(array_a);
1954                         }
1955                         else {
1956                                 const float value = RNA_PROPERTY_GET_SINGLE(float, ptr_reference, prop_reference, index);
1957
1958                                 switch (opop->operation) {
1959                                         case IDOVERRIDESTATIC_OP_ADD:
1960                                         case IDOVERRIDESTATIC_OP_SUBTRACT:
1961                                         {
1962                                                 const float fac = opop->operation == IDOVERRIDESTATIC_OP_ADD ? 1.0f : -1.0f;
1963                                                 const int other_op = opop->operation == IDOVERRIDESTATIC_OP_ADD ? IDOVERRIDESTATIC_OP_SUBTRACT : IDOVERRIDESTATIC_OP_ADD;
1964                                                 float b = fac * (RNA_PROPERTY_GET_SINGLE(float, ptr_local, prop_local, index) - value);
1965                                                 if (b < prop_min || b > prop_max) {
1966                                                         opop->operation = other_op;
1967                                                         b = -b;
1968                                                         if (b < prop_min || b > prop_max) {
1969                                                                 opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
1970                                                                 break;
1971                                                         }
1972                                                 }
1973                                                 changed = true;
1974                                                 RNA_PROPERTY_SET_SINGLE(float, ptr_storage, prop_storage, index, b);
1975                                                 break;
1976                                         }
1977                                         case IDOVERRIDESTATIC_OP_MULTIPLY:
1978                                         {
1979                                                 const float b = RNA_property_float_get_index(ptr_local, prop_local, index) / (value == 0.0f ?  1.0f : value);
1980                                                 if (b < prop_min || b > prop_max) {
1981                                                         opop->operation = IDOVERRIDESTATIC_OP_REPLACE;
1982                                                         break;
1983                                                 }
1984                                                 changed = true;
1985                                                 RNA_property_float_set_index(ptr_storage, prop_storage, index, b);
1986                                                 break;
1987                                         }
1988                                         default:
1989                                                 BLI_assert(0 && "Unsupported RNA override diff operation on float");
1990                                                 break;
1991                                 }
1992                         }
1993                         return true;
1994                 }
1995                 case PROP_ENUM:
1996                         /* TODO support add/sub, for bitflags? */
1997                         BLI_assert(0 && "Enum properties support no override diff operation");
1998                         break;
1999                 case PROP_POINTER:
2000                         BLI_assert(0 && "Pointer properties support no override diff operation");
2001                         break;
2002                 case PROP_STRING:
2003                         BLI_assert(0 && "String properties support no override diff operation");
2004                         break;
2005                 case PROP_COLLECTION:
2006                         /* XXX TODO support this of course... */
2007                         BLI_assert(0 && "Collection properties support no override diff operation");
2008                         break;
2009                 default:
2010                         break;
2011         }
2012
2013         return changed;
2014 }
2015
2016 bool rna_property_override_apply_default(
2017         Main *UNUSED(bmain),
2018         PointerRNA *ptr_dst, PointerRNA *ptr_src, PointerRNA *ptr_storage,
2019         PropertyRNA *prop_dst, PropertyRNA *prop_src, PropertyRNA *prop_storage,
2020         const int len_dst, const int len_src, const int len_storage,
2021         PointerRNA *UNUSED(ptr_item_dst), PointerRNA *UNUSED(ptr_item_src), PointerRNA *UNUSED(ptr_item_storage),
2022         IDOverrideStaticPropertyOperation *opop)
2023 {
2024         BLI_assert(len_dst == len_src && (!ptr_storage || len_dst == len_storage));
2025         UNUSED_VARS_NDEBUG(len_src, len_storage);
2026
2027         const bool is_array = len_dst > 0;
2028         const int index = is_array ? opop->subitem_reference_index : 0;
2029         const short override_op = opop->operation;
2030
2031         switch (RNA_property_type(prop_dst)) {
2032                 case PROP_BOOLEAN:
2033                         if (is_array && index == -1) {
2034                                 bool array_stack_a[RNA_STACK_ARRAY];
2035                                 bool *array_a;
2036
2037                                 array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) : array_stack_a;
2038
2039                                 RNA_property_boolean_get_array(ptr_src, prop_src, array_a);
2040
2041                                 switch (override_op) {
2042                                         case IDOVERRIDESTATIC_OP_REPLACE:
2043                                                 RNA_property_boolean_set_array(ptr_dst, prop_dst, array_a);
2044                                                 break;
2045                                         default:
2046                                                 BLI_assert(0 && "Unsupported RNA override operation on boolean");
2047                                                 return false;
2048                                 }
2049
2050                                 if (array_a != array_stack_a) MEM_freeN(array_a);
2051                         }
2052                         else {
2053                                 const bool value = RNA_PROPERTY_GET_SINGLE(boolean, ptr_src, prop_src, index);
2054
2055                                 switch (override_op) {
2056                                         case IDOVERRIDESTATIC_OP_REPLACE:
2057                                                 RNA_PROPERTY_SET_SINGLE(boolean, ptr_dst, prop_dst, index, value);
2058                                                 break;
2059                                         default:
2060                                                 BLI_assert(0 && "Unsupported RNA override operation on boolean");
2061                                                 return false;
2062                                 }
2063                         }
2064                         return true;
2065                 case PROP_INT:
2066                         if (is_array && index == -1) {
2067                                 int array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
2068                                 int *array_a, *array_b;
2069
2070                                 array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) : array_stack_a;
2071
2072                                 switch (override_op) {
2073                                         case IDOVERRIDESTATIC_OP_REPLACE:
2074                                                 RNA_property_int_get_array(ptr_src, prop_src, array_a);
2075                                                 RNA_property_int_set_array(ptr_dst, prop_dst, array_a);
2076                                                 break;
2077                                         case IDOVERRIDESTATIC_OP_ADD:
2078                                         case IDOVERRIDESTATIC_OP_SUBTRACT:
2079                                                 RNA_property_int_get_array(ptr_dst, prop_dst, array_a);
2080                                                 array_b = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_dst, __func__) : array_stack_b;
2081                                                 RNA_property_int_get_array(ptr_storage, prop_storage, array_b);
2082                                                 if (override_op == IDOVERRIDESTATIC_OP_ADD) {
2083                                                         for (int i = len_dst; i--;) array_a[i] += array_b[i];
2084                                                 }
2085                                                 else {
2086                                                         for (int i = len_dst; i--;) array_a[i] -= array_b[i];
2087                                                 }
2088                                                 RNA_property_int_set_array(ptr_dst, prop_dst, array_a);
2089                                                 if (array_b != array_stack_b) MEM_freeN(array_b);
2090                                                 break;
2091                                         default:
2092                                                 BLI_assert(0 && "Unsupported RNA override operation on integer");
2093                                                 return false;
2094                                 }
2095
2096                                 if (array_a != array_stack_a) MEM_freeN(array_a);
2097                         }
2098                         else {
2099                                 const int storage_value = ptr_storage ? RNA_PROPERTY_GET_SINGLE(int, ptr_storage, prop_storage, index) : 0;
2100
2101                                 switch (override_op) {
2102                                         case IDOVERRIDESTATIC_OP_REPLACE:
2103                                                 RNA_PROPERTY_SET_SINGLE(int, ptr_dst, prop_dst, index,
2104                                                                         RNA_PROPERTY_GET_SINGLE(int, ptr_src, prop_src, index));
2105                                                 break;
2106                                         case IDOVERRIDESTATIC_OP_ADD:
2107                                                 RNA_PROPERTY_SET_SINGLE(int, ptr_dst, prop_dst, index,
2108                                                                         RNA_PROPERTY_GET_SINGLE(int, ptr_dst, prop_dst, index) - storage_value);
2109                                                 break;
2110                                         case IDOVERRIDESTATIC_OP_SUBTRACT:
2111                                                 RNA_PROPERTY_SET_SINGLE(int, ptr_dst, prop_dst, index,
2112                                                                         RNA_PROPERTY_GET_SINGLE(int, ptr_dst, prop_dst, index) - storage_value);
2113                                                 break;
2114                                         default:
2115                                                 BLI_assert(0 && "Unsupported RNA override operation on integer");
2116                                                 return false;
2117                                 }
2118                         }
2119                         return true;
2120                 case PROP_FLOAT:
2121                         if (is_array && index == -1) {
2122                                 float array_stack_a[RNA_STACK_ARRAY], array_stack_b[RNA_STACK_ARRAY];
2123                                 float *array_a, *array_b;
2124
2125                                 array_a = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_a) * len_dst, __func__) : array_stack_a;
2126
2127                                 switch (override_op) {
2128                                         case IDOVERRIDESTATIC_OP_REPLACE:
2129                                                 RNA_property_float_get_array(ptr_src, prop_src, array_a);
2130                                                 RNA_property_float_set_array(ptr_dst, prop_dst, array_a);
2131                                                 break;
2132                                         case IDOVERRIDESTATIC_OP_ADD:
2133                                         case IDOVERRIDESTATIC_OP_SUBTRACT:
2134                                         case IDOVERRIDESTATIC_OP_MULTIPLY:
2135                                                 RNA_property_float_get_array(ptr_dst, prop_dst, array_a);
2136                                                 array_b = (len_dst > RNA_STACK_ARRAY) ? MEM_mallocN(sizeof(*array_b) * len_dst, __func__) : array_stack_b;
2137                                                 RNA_property_float_get_array(ptr_storage, prop_storage, array_b);
2138                                                 if (override_op == IDOVERRIDESTATIC_OP_ADD) {
2139                                                         for (int i = len_dst; i--;) array_a[i] += array_b[i];
2140                                                 }
2141                                                 else if (override_op == IDOVERRIDESTATIC_OP_SUBTRACT) {
2142                                                         for (int i = len_dst; i--;) array_a[i] -= array_b[i];
2143                                                 }
2144                                                 else {
2145                                                         for (int i = len_dst; i--;) array_a[i] *= array_b[i];
2146                                                 }
2147                                                 RNA_property_float_set_array(ptr_dst, prop_dst, array_a);
2148                                                 if (array_b != array_stack_b) MEM_freeN(array_b);
2149                                                 break;
2150                                         default:
2151                                                 BLI_assert(0 && "Unsupported RNA override operation on float");
2152                                                 return false;
2153                                 }
2154
2155                                 if (array_a != array_stack_a) MEM_freeN(array_a);
2156                         }
2157                         else {
2158                                 const float storage_value = ptr_storage ? RNA_PROPERTY_GET_SINGLE(float, ptr_storage, prop_storage, index) : 0.0f;
2159
2160                                 switch (override_op) {
2161                                         case IDOVERRIDESTATIC_OP_REPLACE:
2162                                                 RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index,
2163                                                                         RNA_PROPERTY_GET_SINGLE(float, ptr_src, prop_src, index));
2164                                                 break;
2165                                         case IDOVERRIDESTATIC_OP_ADD:
2166                                                 RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index,
2167                                                                         RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) + storage_value);
2168                                                 break;
2169                                         case IDOVERRIDESTATIC_OP_SUBTRACT:
2170                                                 RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index,
2171                                                                         RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) - storage_value);
2172                                                 break;
2173                                         case IDOVERRIDESTATIC_OP_MULTIPLY:
2174                                                 RNA_PROPERTY_SET_SINGLE(float, ptr_dst, prop_dst, index,
2175                                                                         RNA_PROPERTY_GET_SINGLE(float, ptr_dst, prop_dst, index) * storage_value);
2176                                                 break;
2177                                         default:
2178                                                 BLI_assert(0 && "Unsupported RNA override operation on float");
2179                                                 return false;
2180                                 }
2181                         }
2182                         return true;
2183                 case PROP_ENUM:
2184                 {
2185                         const int value = RNA_property_enum_get(ptr_src, prop_src);
2186
2187                         switch (override_op) {
2188                                 case IDOVERRIDESTATIC_OP_REPLACE:
2189                                         RNA_property_enum_set(ptr_dst, prop_dst, value);
2190                                         break;
2191                                 /* TODO support add/sub, for bitflags? */
2192                                 default:
2193                                         BLI_assert(0 && "Unsupported RNA override operation on enum");
2194                                         return false;
2195                         }
2196                         return true;
2197                 }
2198                 case PROP_POINTER:
2199                 {
2200                         PointerRNA value = RNA_property_pointer_get(ptr_src, prop_src);
2201
2202                         switch (override_op) {
2203                                 case IDOVERRIDESTATIC_OP_REPLACE:
2204                                         RNA_property_pointer_set(ptr_dst, prop_dst, value);
2205                                         break;
2206                                 default:
2207                                         BLI_assert(0 && "Unsupported RNA override operation on pointer");
2208                                         return false;
2209                         }
2210                         return true;
2211                 }
2212                 case PROP_STRING:
2213                 {
2214                         char buff[256];
2215                         char *value = RNA_property_string_get_alloc(ptr_src, prop_src, buff, sizeof(buff), NULL);
2216
2217                         switch (override_op) {
2218                                 case IDOVERRIDESTATIC_OP_REPLACE:
2219                                         RNA_property_string_set(ptr_dst, prop_dst, value);
2220                                         break;
2221                                 default:
2222                                         BLI_assert(0 && "Unsupported RNA override operation on string");
2223                                         return false;
2224                         }
2225
2226                         if (value != buff) MEM_freeN(value);
2227                         return true;
2228                 }
2229                 case PROP_COLLECTION:
2230                 {
2231                         BLI_assert(!"You need to define a specific override apply callback for enums.");
2232                         return false;
2233                 }
2234                 default:
2235                         BLI_assert(0);
2236                         return false;
2237         }
2238
2239         return false;
2240 }
2241
2242 #undef RNA_PROPERTY_GET_SINGLE
2243 #undef RNA_PROPERTY_SET_SINGLE
2244
2245
2246 #else
2247
2248 static void rna_def_struct(BlenderRNA *brna)
2249 {
2250         StructRNA *srna;
2251         PropertyRNA *prop;
2252
2253         srna = RNA_def_struct(brna, "Struct", NULL);
2254         RNA_def_struct_ui_text(srna, "Struct Definition", "RNA structure definition");
2255         RNA_def_struct_ui_icon(srna, ICON_RNA);
2256
2257         prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
2258         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2259         RNA_def_property_string_funcs(prop, "rna_Struct_name_get", "rna_Struct_name_length", NULL);
2260         RNA_def_property_ui_text(prop, "Name", "Human readable name");
2261
2262         prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
2263         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2264         RNA_def_property_string_funcs(prop, "rna_Struct_identifier_get", "rna_Struct_identifier_length", NULL);
2265         RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting");
2266         RNA_def_struct_name_property(srna, prop);
2267
2268         prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
2269         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2270         RNA_def_property_string_funcs(prop, "rna_Struct_description_get", "rna_Struct_description_length", NULL);
2271         RNA_def_property_ui_text(prop, "Description", "Description of the Struct's purpose");
2272
2273         prop = RNA_def_property(srna, "translation_context", PROP_STRING, PROP_NONE);
2274         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2275         RNA_def_property_string_funcs(prop, "rna_Struct_translation_context_get",
2276                                       "rna_Struct_translation_context_length", NULL);
2277         RNA_def_property_ui_text(prop, "Translation Context", "Translation context of the struct's name");
2278
2279         prop = RNA_def_property(srna, "base", PROP_POINTER, PROP_NONE);
2280         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2281         RNA_def_property_struct_type(prop, "Struct");
2282         RNA_def_property_pointer_funcs(prop, "rna_Struct_base_get", NULL, NULL, NULL);
2283         RNA_def_property_ui_text(prop, "Base", "Struct definition this is derived from");
2284
2285         prop = RNA_def_property(srna, "nested", PROP_POINTER, PROP_NONE);
2286         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2287         RNA_def_property_struct_type(prop, "Struct");
2288         RNA_def_property_pointer_funcs(prop, "rna_Struct_nested_get", NULL, NULL, NULL);
2289         RNA_def_property_ui_text(prop, "Nested",
2290                                  "Struct in which this struct is always nested, and to which it logically belongs");
2291
2292         prop = RNA_def_property(srna, "name_property", PROP_POINTER, PROP_NONE);
2293         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2294         RNA_def_property_struct_type(prop, "StringProperty");
2295         RNA_def_property_pointer_funcs(prop, "rna_Struct_name_property_get", NULL, NULL, NULL);
2296         RNA_def_property_ui_text(prop, "Name Property", "Property that gives the name of the struct");
2297
2298         prop = RNA_def_property(srna, "properties", PROP_COLLECTION, PROP_NONE);
2299         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2300         RNA_def_property_struct_type(prop, "Property");
2301         RNA_def_property_collection_funcs(prop, "rna_Struct_properties_begin", "rna_Struct_properties_next",
2302                                           "rna_iterator_listbase_end", "rna_Struct_properties_get",
2303                                           NULL, NULL, NULL, NULL);
2304         RNA_def_property_ui_text(prop, "Properties", "Properties in the struct");
2305
2306         prop = RNA_def_property(srna, "functions", PROP_COLLECTION, PROP_NONE);
2307         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2308         RNA_def_property_struct_type(prop, "Function");
2309         RNA_def_property_collection_funcs(prop, "rna_Struct_functions_begin", "rna_Struct_functions_next",
2310                                           "rna_iterator_listbase_end", "rna_Struct_functions_get",
2311                                           NULL, NULL, NULL, NULL);
2312         RNA_def_property_ui_text(prop, "Functions", "");
2313
2314         prop = RNA_def_property(srna, "property_tags", PROP_COLLECTION, PROP_NONE);
2315         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2316         RNA_def_property_struct_type(prop, "EnumPropertyItem");
2317         RNA_def_property_collection_funcs(prop, "rna_Struct_property_tags_begin", "rna_iterator_array_next",
2318                                           "rna_iterator_array_end", "rna_iterator_array_get",
2319                                           NULL, NULL, NULL, NULL);
2320         RNA_def_property_ui_text(prop, "Property Tags", "Tags that properties can use to influence behavior");
2321 }
2322
2323 static void rna_def_property(BlenderRNA *brna)
2324 {
2325         StructRNA *srna;
2326         PropertyRNA *prop;
2327         static const EnumPropertyItem subtype_items[] = {
2328                 {PROP_NONE, "NONE", 0, "None", ""},
2329                 {PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""},
2330                 {PROP_DIRPATH, "DIR_PATH", 0, "Directory Path", ""},
2331                 {PROP_PIXEL, "PIXEL", 0, "Pixel", ""},
2332                 {PROP_UNSIGNED, "UNSIGNED", 0, "Unsigned Number", ""},
2333                 {PROP_PERCENTAGE, "PERCENTAGE", 0, "Percentage", ""},
2334                 {PROP_FACTOR, "FACTOR", 0, "Factor", ""},
2335                 {PROP_ANGLE, "ANGLE", 0, "Angle", ""},
2336                 {PROP_TIME, "TIME", 0, "Time", ""},
2337                 {PROP_DISTANCE, "DISTANCE", 0, "Distance", ""},
2338                 {PROP_COLOR, "COLOR", 0, "Color", ""},
2339                 {PROP_TRANSLATION, "TRANSLATION", 0, "Translation", ""},
2340                 {PROP_DIRECTION, "DIRECTION", 0, "Direction", ""},
2341                 {PROP_MATRIX, "MATRIX", 0, "Matrix", ""},
2342                 {PROP_EULER, "EULER", 0, "Euler", ""},
2343                 {PROP_QUATERNION, "QUATERNION", 0, "Quaternion", ""},
2344                 {PROP_XYZ, "XYZ", 0, "XYZ", ""},
2345                 {PROP_COLOR_GAMMA, "COLOR_GAMMA", 0, "Gamma Corrected Color", ""},
2346                 {PROP_COORDS, "COORDINATES", 0, "Vector Coordinates", ""},
2347                 {PROP_LAYER, "LAYER", 0, "Layer", ""},
2348                 {PROP_LAYER_MEMBER, "LAYER_MEMBERSHIP", 0, "Layer Membership", ""},
2349                 {0, NULL, 0, NULL, NULL}
2350         };
2351         EnumPropertyItem dummy_prop_tags[] = {
2352                 {0, NULL, 0, NULL, NULL}
2353         };
2354
2355         srna = RNA_def_struct(brna, "Property", NULL);
2356         RNA_def_struct_ui_text(srna, "Property Definition", "RNA property definition");
2357         RNA_def_struct_refine_func(srna, "rna_Property_refine");
2358         RNA_def_struct_ui_icon(srna, ICON_RNA);
2359
2360         prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
2361         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2362         RNA_def_property_string_funcs(prop, "rna_Property_name_get", "rna_Property_name_length", NULL);
2363         RNA_def_property_ui_text(prop, "Name", "Human readable name");
2364
2365         prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
2366         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2367         RNA_def_property_string_funcs(prop, "rna_Property_identifier_get", "rna_Property_identifier_length", NULL);
2368         RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting");
2369         RNA_def_struct_name_property(srna, prop);
2370
2371         prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
2372         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2373         RNA_def_property_string_funcs(prop, "rna_Property_description_get", "rna_Property_description_length", NULL);
2374         RNA_def_property_ui_text(prop, "Description", "Description of the property for tooltips");
2375
2376         prop = RNA_def_property(srna, "translation_context", PROP_STRING, PROP_NONE);
2377         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2378         RNA_def_property_string_funcs(prop, "rna_Property_translation_context_get",
2379                                       "rna_Property_translation_context_length", NULL);
2380         RNA_def_property_ui_text(prop, "Translation Context", "Translation context of the property's name");
2381
2382         prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
2383         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2384         RNA_def_property_enum_items(prop, rna_enum_property_type_items);
2385         RNA_def_property_enum_funcs(prop, "rna_Property_type_get", NULL, NULL);
2386         RNA_def_property_ui_text(prop, "Type", "Data type of the property");
2387
2388         prop = RNA_def_property(srna, "subtype", PROP_ENUM, PROP_NONE);
2389         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2390         RNA_def_property_enum_items(prop, subtype_items);
2391         RNA_def_property_enum_funcs(prop, "rna_Property_subtype_get", NULL, NULL);
2392         RNA_def_property_ui_text(prop, "Subtype", "Semantic interpretation of the property");
2393
2394         prop = RNA_def_property(srna, "srna", PROP_POINTER, PROP_NONE);
2395         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2396         RNA_def_property_struct_type(prop, "Struct");
2397         RNA_def_property_pointer_funcs(prop, "rna_Property_srna_get", NULL, NULL, NULL);
2398         RNA_def_property_ui_text(prop, "Base", "Struct definition used for properties assigned to this item");
2399
2400         prop = RNA_def_property(srna, "unit", PROP_ENUM, PROP_NONE);
2401         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2402         RNA_def_property_enum_items(prop, rna_enum_property_unit_items);
2403         RNA_def_property_enum_funcs(prop, "rna_Property_unit_get", NULL, NULL);
2404         RNA_def_property_ui_text(prop, "Unit", "Type of units for this property");
2405
2406         prop = RNA_def_property(srna, "icon", PROP_ENUM, PROP_NONE);
2407         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2408         RNA_def_property_enum_items(prop, rna_enum_icon_items);
2409         RNA_def_property_enum_funcs(prop, "rna_Property_icon_get", NULL, NULL);
2410         RNA_def_property_ui_text(prop, "Icon", "Icon of the item");
2411
2412         prop = RNA_def_property(srna, "is_readonly", PROP_BOOLEAN, PROP_NONE);
2413         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2414         RNA_def_property_boolean_funcs(prop, "rna_Property_readonly_get", NULL);
2415         RNA_def_property_ui_text(prop, "Read Only", "Property is editable through RNA");
2416
2417         prop = RNA_def_property(srna, "is_animatable", PROP_BOOLEAN, PROP_NONE);
2418         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2419         RNA_def_property_boolean_funcs(prop, "rna_Property_animatable_get", NULL);
2420         RNA_def_property_ui_text(prop, "Animatable", "Property is animatable through RNA");
2421
2422         prop = RNA_def_property(srna, "is_overridable", PROP_BOOLEAN, PROP_NONE);
2423         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2424         RNA_def_property_boolean_funcs(prop, "rna_Property_overridable_get", NULL);
2425         RNA_def_property_ui_text(prop, "Overridable", "Property is overridable through RNA");
2426
2427         prop = RNA_def_property(srna, "is_required", PROP_BOOLEAN, PROP_NONE);
2428         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2429         RNA_def_property_boolean_funcs(prop, "rna_Property_is_required_get", NULL);
2430         RNA_def_property_ui_text(prop, "Required", "False when this property is an optional argument in an RNA function");
2431
2432         prop = RNA_def_property(srna, "is_argument_optional", PROP_BOOLEAN, PROP_NONE);
2433         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2434         RNA_def_property_boolean_funcs(prop, "rna_Property_is_argument_optional_get", NULL);
2435         RNA_def_property_ui_text(prop, "Optional Argument",
2436                                  "True when the property is optional in a Python function implementing an RNA function");
2437
2438         prop = RNA_def_property(srna, "is_never_none", PROP_BOOLEAN, PROP_NONE);
2439         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2440         RNA_def_property_boolean_funcs(prop, "rna_Property_is_never_none_get", NULL);
2441         RNA_def_property_ui_text(prop, "Never None", "True when this value can't be set to None");
2442
2443         prop = RNA_def_property(srna, "is_hidden", PROP_BOOLEAN, PROP_NONE);
2444         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2445         RNA_def_property_boolean_funcs(prop, "rna_Property_is_hidden_get", NULL);
2446         RNA_def_property_ui_text(prop, "Hidden", "True when the property is hidden");
2447
2448         prop = RNA_def_property(srna, "is_skip_save", PROP_BOOLEAN, PROP_NONE);
2449         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2450         RNA_def_property_boolean_funcs(prop, "rna_Property_is_skip_save_get", NULL);
2451         RNA_def_property_ui_text(prop, "Skip Save", "True when the property is not saved in presets");
2452
2453         prop = RNA_def_property(srna, "is_output", PROP_BOOLEAN, PROP_NONE);
2454         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2455         RNA_def_property_boolean_funcs(prop, "rna_Property_use_output_get", NULL);
2456         RNA_def_property_ui_text(prop, "Return", "True when this property is an output value from an RNA function");
2457
2458         prop = RNA_def_property(srna, "is_registered", PROP_BOOLEAN, PROP_NONE);
2459         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2460         RNA_def_property_boolean_funcs(prop, "rna_Property_is_registered_get", NULL);
2461         RNA_def_property_ui_text(prop, "Registered", "Property is registered as part of type registration");
2462
2463         prop = RNA_def_property(srna, "is_registered_optional", PROP_BOOLEAN, PROP_NONE);
2464         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2465         RNA_def_property_boolean_funcs(prop, "rna_Property_is_registered_optional_get", NULL);
2466         RNA_def_property_ui_text(prop, "Registered Optionally",
2467                                  "Property is optionally registered as part of type registration");
2468
2469         prop = RNA_def_property(srna, "is_runtime", PROP_BOOLEAN, PROP_NONE);
2470         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2471         RNA_def_property_boolean_funcs(prop, "rna_Property_is_runtime_get", NULL);
2472         RNA_def_property_ui_text(prop, "Runtime", "Property has been dynamically created at runtime");
2473
2474         prop = RNA_def_property(srna, "is_enum_flag", PROP_BOOLEAN, PROP_NONE);
2475         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2476         RNA_def_property_boolean_funcs(prop, "rna_Property_is_enum_flag_get", NULL);
2477         RNA_def_property_ui_text(prop, "Enum Flag", "True when multiple enums ");
2478
2479         prop = RNA_def_property(srna, "is_library_editable", PROP_BOOLEAN, PROP_NONE);
2480         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2481         RNA_def_property_boolean_funcs(prop, "rna_Property_is_library_editable_flag_get", NULL);
2482         RNA_def_property_ui_text(prop, "Library Editable", "Property is editable from linked instances (changes not saved)");
2483
2484         prop = RNA_def_property(srna, "tags", PROP_ENUM, PROP_NONE);
2485         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2486         RNA_def_property_enum_items(prop, dummy_prop_tags);
2487         RNA_def_property_enum_funcs(prop, "rna_Property_tags_get", NULL, "rna_Property_tags_itemf");
2488         RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG);
2489         RNA_def_property_ui_text(prop, "Tags", "Subset of tags (defined in parent struct) that are set for this property");
2490 }
2491
2492 static void rna_def_function(BlenderRNA *brna)
2493 {
2494         StructRNA *srna;
2495         PropertyRNA *prop;
2496
2497         srna = RNA_def_struct(brna, "Function", NULL);
2498         RNA_def_struct_ui_text(srna, "Function Definition", "RNA function definition");
2499         RNA_def_struct_ui_icon(srna, ICON_RNA);
2500
2501         prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
2502         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2503         RNA_def_property_string_funcs(prop, "rna_Function_identifier_get", "rna_Function_identifier_length", NULL);
2504         RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting");
2505         RNA_def_struct_name_property(srna, prop);
2506
2507         prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
2508         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2509         RNA_def_property_string_funcs(prop, "rna_Function_description_get", "rna_Function_description_length", NULL);
2510         RNA_def_property_ui_text(prop, "Description", "Description of the Function's purpose");
2511
2512         prop = RNA_def_property(srna, "parameters", PROP_COLLECTION, PROP_NONE);
2513         /*RNA_def_property_clear_flag(prop, PROP_EDITABLE);*/
2514         RNA_def_property_struct_type(prop, "Property");
2515         RNA_def_property_collection_funcs(prop, "rna_Function_parameters_begin", "rna_iterator_listbase_next",
2516                                           "rna_iterator_listbase_end", "rna_iterator_listbase_get",
2517                                           NULL, NULL, NULL, NULL);
2518         RNA_def_property_ui_text(prop, "Parameters", "Parameters for the function");
2519
2520         prop = RNA_def_property(srna, "is_registered", PROP_BOOLEAN, PROP_NONE);
2521         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2522         RNA_def_property_boolean_funcs(prop, "rna_Function_registered_get", NULL);
2523         RNA_def_property_ui_text(prop, "Registered", "Function is registered as callback as part of type registration");
2524
2525         prop = RNA_def_property(srna, "is_registered_optional", PROP_BOOLEAN, PROP_NONE);
2526         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2527         RNA_def_property_boolean_funcs(prop, "rna_Function_registered_optional_get", NULL);
2528         RNA_def_property_ui_text(prop, "Registered Optionally",
2529                                  "Function is optionally registered as callback part of type registration");
2530
2531         prop = RNA_def_property(srna, "use_self", PROP_BOOLEAN, PROP_NONE);
2532         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2533         RNA_def_property_boolean_funcs(prop, "rna_Function_no_self_get", NULL);
2534         RNA_def_property_ui_text(prop, "No Self",
2535                                  "Function does not pass its self as an argument (becomes a static method in python)");
2536
2537         prop = RNA_def_property(srna, "use_self_type", PROP_BOOLEAN, PROP_NONE);
2538         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2539         RNA_def_property_boolean_funcs(prop, "rna_Function_use_self_type_get", NULL);
2540         RNA_def_property_ui_text(prop, "Use Self Type",
2541                                  "Function passes its self type as an argument (becomes a class method in python if use_self is false)");
2542 }
2543
2544 static void rna_def_number_property(StructRNA *srna, PropertyType type)
2545 {
2546         PropertyRNA *prop;
2547
2548         prop = RNA_def_property(srna, "default", type, PROP_NONE);
2549         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2550         RNA_def_property_ui_text(prop, "Default", "Default value for this number");
2551
2552         switch (type) {
2553                 case PROP_BOOLEAN:
2554                         RNA_def_property_boolean_funcs(prop, "rna_BoolProperty_default_get", NULL);
2555                         break;
2556                 case PROP_INT:
2557                         RNA_def_property_int_funcs(prop, "rna_IntProperty_default_get", NULL, NULL);
2558                         break;
2559                 case PROP_FLOAT:
2560                         RNA_def_property_float_funcs(prop, "rna_FloatProperty_default_get", NULL, NULL);
2561                         break;
2562                 default:
2563                         break;
2564         }
2565
2566
2567         prop = RNA_def_property(srna, "default_array", type, PROP_NONE);
2568         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2569         RNA_def_property_array(prop, RNA_MAX_ARRAY_DIMENSION); /* no fixed default length, important its not 0 though */
2570         RNA_def_property_flag(prop, PROP_DYNAMIC);
2571         RNA_def_property_dynamic_array_funcs(prop, "rna_NumberProperty_default_array_get_length"); /* same for all types */
2572
2573         switch (type) {
2574                 case PROP_BOOLEAN:
2575                         RNA_def_property_boolean_funcs(prop, "rna_BoolProperty_default_array_get", NULL);
2576                         break;
2577                 case PROP_INT:
2578                         RNA_def_property_int_funcs(prop, "rna_IntProperty_default_array_get", NULL, NULL);
2579                         break;
2580                 case PROP_FLOAT:
2581                         RNA_def_property_float_funcs(prop, "rna_FloatProperty_default_array_get", NULL, NULL);
2582                         break;
2583                 default:
2584                         break;
2585         }
2586         RNA_def_property_ui_text(prop, "Default Array", "Default value for this array");
2587
2588
2589         prop = RNA_def_property(srna, "array_length", PROP_INT, PROP_UNSIGNED);
2590         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2591         RNA_def_property_int_funcs(prop, "rna_Property_array_length_get", NULL, NULL);
2592         RNA_def_property_ui_text(prop, "Array Length", "Maximum length of the array, 0 means unlimited");
2593
2594         prop = RNA_def_property(srna, "array_dimensions", PROP_INT, PROP_UNSIGNED);
2595         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2596         RNA_def_property_array(prop, RNA_MAX_ARRAY_DIMENSION);
2597         RNA_def_property_int_funcs(prop, "rna_Property_array_dimensions_get", NULL, NULL);
2598         RNA_def_property_ui_text(prop, "Array Dimensions", "Length of each dimension of the array");
2599
2600         prop = RNA_def_property(srna, "is_array", PROP_BOOLEAN, PROP_NONE);
2601         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2602         RNA_def_property_boolean_funcs(prop, "rna_NumberProperty_is_array_get", NULL);
2603         RNA_def_property_ui_text(prop, "Is Array", "");
2604
2605         if (type == PROP_BOOLEAN)
2606                 return;
2607
2608         prop = RNA_def_property(srna, "hard_min", 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_hard_min_get", NULL, NULL);
2611         else RNA_def_property_float_funcs(prop, "rna_FloatProperty_hard_min_get", NULL, NULL);
2612         RNA_def_property_ui_text(prop, "Hard Minimum", "Minimum value used by buttons");
2613
2614         prop = RNA_def_property(srna, "hard_max", type, PROP_NONE);
2615         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2616         if (type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_hard_max_get", NULL, NULL);
2617         else RNA_def_property_float_funcs(prop, "rna_FloatProperty_hard_max_get", NULL, NULL);
2618         RNA_def_property_ui_text(prop, "Hard Maximum", "Maximum value used by buttons");
2619
2620         prop = RNA_def_property(srna, "soft_min", type, PROP_NONE);
2621         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2622         if (type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_soft_min_get", NULL, NULL);
2623         else RNA_def_property_float_funcs(prop, "rna_FloatProperty_soft_min_get", NULL, NULL);
2624         RNA_def_property_ui_text(prop, "Soft Minimum", "Minimum value used by buttons");
2625
2626         prop = RNA_def_property(srna, "soft_max", type, PROP_NONE);
2627         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2628         if (type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_soft_max_get", NULL, NULL);
2629         else RNA_def_property_float_funcs(prop, "rna_FloatProperty_soft_max_get", NULL, NULL);
2630         RNA_def_property_ui_text(prop, "Soft Maximum", "Maximum value used by buttons");
2631
2632         prop = RNA_def_property(srna, "step", type, PROP_UNSIGNED);
2633         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2634         if (type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_step_get", NULL, NULL);
2635         else RNA_def_property_float_funcs(prop, "rna_FloatProperty_step_get", NULL, NULL);
2636         RNA_def_property_ui_text(prop, "Step", "Step size used by number buttons, for floats 1/100th of the step size");
2637
2638         if (type == PROP_FLOAT) {
2639                 prop = RNA_def_property(srna, "precision", PROP_INT, PROP_UNSIGNED);
2640                 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2641                 RNA_def_property_int_funcs(prop, "rna_FloatProperty_precision_get", NULL, NULL);
2642                 RNA_def_property_ui_text(prop, "Precision", "Number of digits after the dot used by buttons");
2643         }
2644 }
2645
2646 static void rna_def_string_property(StructRNA *srna)
2647 {
2648         PropertyRNA *prop;
2649
2650         prop = RNA_def_property(srna, "default", PROP_STRING, PROP_NONE);
2651         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2652         RNA_def_property_string_funcs(prop, "rna_StringProperty_default_get", "rna_StringProperty_default_length", NULL);
2653         RNA_def_property_ui_text(prop, "Default", "string default value");
2654
2655         prop = RNA_def_property(srna, "length_max", PROP_INT, PROP_UNSIGNED);
2656         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2657         RNA_def_property_int_funcs(prop, "rna_StringProperty_max_length_get", NULL, NULL);
2658         RNA_def_property_ui_text(prop, "Maximum Length", "Maximum length of the string, 0 means unlimited");
2659 }
2660
2661 static void rna_def_enum_property(BlenderRNA *brna, StructRNA *srna)
2662 {
2663         PropertyRNA *prop;
2664
2665         /* the itemf func is used instead, keep blender happy */
2666         static const EnumPropertyItem default_dummy_items[] = {
2667                 {PROP_NONE, "DUMMY", 0, "Dummy", ""},
2668                 {0, NULL, 0, NULL, NULL}
2669         };
2670
2671         prop = RNA_def_property(srna, "default", PROP_ENUM, PROP_NONE);
2672         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2673         RNA_def_property_enum_items(prop, default_dummy_items);
2674         RNA_def_property_enum_funcs(prop, "rna_EnumProperty_default_get", NULL, "rna_EnumProperty_default_itemf");
2675         RNA_def_property_ui_text(prop, "Default", "Default value for this enum");
2676
2677         /* same 'default' but uses 'PROP_ENUM_FLAG' */
2678         prop = RNA_def_property(srna, "default_flag", PROP_ENUM, PROP_NONE);
2679         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2680         RNA_def_property_flag(prop, PROP_ENUM_FLAG);
2681         RNA_def_property_enum_items(prop, default_dummy_items);
2682         RNA_def_property_enum_funcs(prop, "rna_EnumProperty_default_get", NULL, "rna_EnumProperty_default_itemf");
2683         RNA_def_property_ui_text(prop, "Default", "Default value for this enum");
2684
2685         prop = RNA_def_property(srna, "enum_items", PROP_COLLECTION, PROP_NONE);
2686         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2687         RNA_def_property_struct_type(prop, "EnumPropertyItem");
2688         RNA_def_property_collection_funcs(prop, "rna_EnumProperty_items_begin", "rna_iterator_array_next",
2689                                           "rna_iterator_array_end", "rna_iterator_array_get", NULL, NULL, NULL, NULL);
2690         RNA_def_property_ui_text(prop, "Items", "Possible values for the property");
2691
2692         prop = RNA_def_property(srna, "enum_items_static", PROP_COLLECTION, PROP_NONE);
2693         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2694         RNA_def_property_struct_type(prop, "EnumPropertyItem");
2695         RNA_def_property_collection_funcs(prop, "rna_EnumProperty_items_begin", "rna_iterator_array_next",
2696                                           "rna_iterator_array_end", "rna_iterator_array_get", NULL, NULL, NULL, NULL);
2697         RNA_def_property_ui_text(prop, "Static Items",
2698                                  "Possible values for the property (never calls optional dynamic generation of those)");
2699
2700         srna = RNA_def_struct(brna, "EnumPropertyItem", NULL);
2701         RNA_def_struct_ui_text(srna, "Enum Item Definition", "Definition of a choice in an RNA enum property");
2702         RNA_def_struct_ui_icon(srna, ICON_RNA);
2703
2704         prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
2705         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2706         RNA_def_property_string_funcs(prop, "rna_EnumPropertyItem_name_get", "rna_EnumPropertyItem_name_length", NULL);
2707         RNA_def_property_ui_text(prop, "Name", "Human readable name");
2708
2709         prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
2710         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2711         RNA_def_property_string_funcs(prop, "rna_EnumPropertyItem_description_get",
2712                                       "rna_EnumPropertyItem_description_length", NULL);
2713         RNA_def_property_ui_text(prop, "Description", "Description of the item's purpose");
2714
2715         prop = RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
2716         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2717         RNA_def_property_string_funcs(prop, "rna_EnumPropertyItem_identifier_get",
2718                                       "rna_EnumPropertyItem_identifier_length", NULL);
2719         RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting");
2720         RNA_def_struct_name_property(srna, prop);
2721
2722         prop = RNA_def_property(srna, "value", PROP_INT, PROP_UNSIGNED);
2723         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2724         RNA_def_property_int_funcs(prop, "rna_EnumPropertyItem_value_get", NULL, NULL);
2725         RNA_def_property_ui_text(prop, "Value", "Value of the item");
2726
2727         prop = RNA_def_property(srna, "icon", PROP_ENUM, PROP_NONE);
2728         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2729         RNA_def_property_enum_items(prop, rna_enum_icon_items);
2730         RNA_def_property_enum_funcs(prop, "rna_EnumPropertyItem_icon_get", NULL, NULL);
2731         RNA_def_property_ui_text(prop, "Icon", "Icon of the item");
2732 }
2733
2734 static void rna_def_pointer_property(StructRNA *srna, PropertyType type)
2735 {
2736         PropertyRNA *prop;
2737
2738         prop = RNA_def_property(srna, "fixed_type", PROP_POINTER, PROP_NONE);
2739         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2740         RNA_def_property_struct_type(prop, "Struct");
2741         if (type == PROP_POINTER)
2742                 RNA_def_property_pointer_funcs(prop, "rna_PointerProperty_fixed_type_get", NULL, NULL, NULL);
2743         else
2744                 RNA_def_property_pointer_funcs(prop, "rna_CollectionProperty_fixed_type_get", NULL, NULL, NULL);
2745         RNA_def_property_ui_text(prop, "Pointer Type", "Fixed pointer type, empty if variable type");
2746 }
2747
2748 void RNA_def_rna(BlenderRNA *brna)
2749 {
2750         StructRNA *srna;
2751         PropertyRNA *prop;
2752
2753         /* Struct*/
2754         rna_def_struct(brna);
2755
2756         /* Property */
2757         rna_def_property(brna);
2758
2759         /* BoolProperty */
2760         srna = RNA_def_struct(brna, "BoolProperty", "Property");
2761         RNA_def_struct_ui_text(srna, "Boolean Definition", "RNA boolean property definition");
2762         rna_def_number_property(srna, PROP_BOOLEAN);
2763
2764         /* IntProperty */
2765         srna = RNA_def_struct(brna, "IntProperty", "Property");
2766         RNA_def_struct_ui_text(srna, "Int Definition", "RNA integer number property definition");
2767         rna_def_number_property(srna, PROP_INT);
2768
2769         /* FloatProperty */
2770         srna = RNA_def_struct(brna, "FloatProperty", "Property");
2771         RNA_def_struct_ui_text(srna, "Float Definition", "RNA floating pointer number property definition");
2772         rna_def_number_property(srna, PROP_FLOAT);
2773
2774         /* StringProperty */
2775         srna = RNA_def_struct(brna, "StringProperty", "Property");
2776         RNA_def_struct_ui_text(srna, "String Definition", "RNA text string property definition");
2777         rna_def_string_property(srna);
2778
2779         /* EnumProperty */
2780         srna = RNA_def_struct(brna, "EnumProperty", "Property");
2781         RNA_def_struct_ui_text(srna, "Enum Definition",
2782                                "RNA enumeration property definition, to choose from a number of predefined options");
2783         rna_def_enum_property(brna, srna);
2784
2785         /* PointerProperty */
2786         srna = RNA_def_struct(brna, "PointerProperty", "Property");
2787         RNA_def_struct_ui_text(srna, "Pointer Definition", "RNA pointer property to point to another RNA struct");
2788         rna_def_pointer_property(srna, PROP_POINTER);
2789
2790         /* CollectionProperty */
2791         srna = RNA_def_struct(brna, "CollectionProperty", "Property");
2792         RNA_def_struct_ui_text(srna, "Collection Definition",
2793                                "RNA collection property to define lists, arrays and mappings");
2794         rna_def_pointer_property(srna, PROP_COLLECTION);
2795
2796         /* Function */
2797         rna_def_function(brna);
2798
2799         /* Blender RNA */
2800         srna = RNA_def_struct(brna, "BlenderRNA", NULL);
2801         RNA_def_struct_ui_text(srna, "Blender RNA", "Blender RNA structure definitions");
2802         RNA_def_struct_ui_icon(srna, ICON_RNA);
2803
2804         prop = RNA_def_property(srna, "structs", PROP_COLLECTION, PROP_NONE);
2805         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2806         RNA_def_property_struct_type(prop, "Struct");
2807         RNA_def_property_collection_funcs(prop, "rna_BlenderRNA_structs_begin", "rna_iterator_listbase_next",
2808                                           "rna_iterator_listbase_end", "rna_iterator_listbase_get",
2809                                           /* included for speed, can be removed */
2810 #if 0
2811                                           NULL, NULL, NULL, NULL);
2812 #else
2813                                           "rna_BlenderRNA_structs_length", "rna_BlenderRNA_structs_lookup_int",
2814                                           "rna_BlenderRNA_structs_lookup_string", NULL);
2815 #endif
2816
2817         RNA_def_property_ui_text(prop, "Structs", "");
2818 }
2819
2820 #endif