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