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 <ctype.h>
22 #include <float.h>
23 #include <limits.h>
24 #include <stddef.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #include "BLI_utildefines.h"
30 #include "MEM_guardedalloc.h"
31 
32 #include "DNA_defaults.h"
33 #include "DNA_genfile.h"
34 #include "DNA_sdna_types.h"
35 
36 #include "BLI_ghash.h"
37 #include "BLI_listbase.h"
38 
39 #include "BLT_translation.h"
40 
41 #include "UI_interface.h" /* For things like UI_PRECISION_FLOAT_MAX... */
42 
43 #include "RNA_define.h"
44 
45 #include "rna_internal.h"
46 
47 #include "CLG_log.h"
48 
49 static CLG_LogRef LOG = {"rna.define"};
50 
51 #ifdef DEBUG
52 #  define ASSERT_SOFT_HARD_LIMITS \
53     if (softmin < hardmin || softmax > hardmax) { \
54       CLOG_ERROR(&LOG, "error with soft/hard limits: %s.%s", CONTAINER_RNA_ID(cont), identifier); \
55       BLI_assert(!"invalid soft/hard limits"); \
56     } \
57     (void)0
58 #else
59 #  define ASSERT_SOFT_HARD_LIMITS (void)0
60 #endif
61 
62 /* Global used during defining */
63 
64 BlenderDefRNA DefRNA = {
65     .sdna = NULL,
66     .structs = {NULL, NULL},
67     .allocs = {NULL, NULL},
68     .laststruct = NULL,
69     .error = 0,
70     .silent = false,
71     .preprocess = false,
72     .verify = true,
73     .animate = true,
74     .make_overridable = false,
75 };
76 
77 #ifndef RNA_RUNTIME
78 static struct {
79   GHash *struct_map_static_from_alias;
80 } g_version_data;
81 #endif
82 
83 #ifndef RNA_RUNTIME
84 /**
85  * When set, report details about which defaults are used.
86  * Noisy but handy when investigating default extraction.
87  */
88 static bool debugSRNA_defaults = false;
89 
print_defult_info(const PropertyDefRNA * dp)90 static void print_defult_info(const PropertyDefRNA *dp)
91 {
92   fprintf(stderr,
93           "dna_type=%s, dna_offset=%d, dna_struct=%s, dna_name=%s, id=%s\n",
94           dp->dnatype,
95           dp->dnaoffset,
96           dp->dnastructname,
97           dp->dnaname,
98           dp->prop->identifier);
99 }
100 #endif /* RNA_RUNTIME */
101 
102 /* Duplicated code since we can't link in blenkernel or blenlib */
103 
104 /* pedantic check for final '.', note '...' are allowed though. */
105 #ifndef NDEBUG
106 #  define DESCR_CHECK(description, id1, id2) \
107     if (description && (description)[0]) { \
108       int i = strlen(description); \
109       if (i > 3 && (description)[i - 1] == '.' && (description)[i - 3] != '.') { \
110         CLOG_WARN(&LOG, \
111                   "'%s' description from '%s' '%s' ends with a '.' !", \
112                   description, \
113                   id1 ? id1 : "", \
114                   id2 ? id2 : ""); \
115       } \
116     } \
117     (void)0
118 
119 #else
120 #  define DESCR_CHECK(description, id1, id2)
121 #endif
122 
rna_addtail(ListBase * listbase,void * vlink)123 void rna_addtail(ListBase *listbase, void *vlink)
124 {
125   Link *link = vlink;
126 
127   link->next = NULL;
128   link->prev = listbase->last;
129 
130   if (listbase->last) {
131     ((Link *)listbase->last)->next = link;
132   }
133   if (listbase->first == NULL) {
134     listbase->first = link;
135   }
136   listbase->last = link;
137 }
138 
rna_remlink(ListBase * listbase,void * vlink)139 static void rna_remlink(ListBase *listbase, void *vlink)
140 {
141   Link *link = vlink;
142 
143   if (link->next) {
144     link->next->prev = link->prev;
145   }
146   if (link->prev) {
147     link->prev->next = link->next;
148   }
149 
150   if (listbase->last == link) {
151     listbase->last = link->prev;
152   }
153   if (listbase->first == link) {
154     listbase->first = link->next;
155   }
156 }
157 
rna_findlink(ListBase * listbase,const char * identifier)158 PropertyDefRNA *rna_findlink(ListBase *listbase, const char *identifier)
159 {
160   Link *link;
161 
162   for (link = listbase->first; link; link = link->next) {
163     PropertyRNA *prop = ((PropertyDefRNA *)link)->prop;
164     if (prop && (STREQ(prop->identifier, identifier))) {
165       return (PropertyDefRNA *)link;
166     }
167   }
168 
169   return NULL;
170 }
171 
rna_freelinkN(ListBase * listbase,void * vlink)172 void rna_freelinkN(ListBase *listbase, void *vlink)
173 {
174   rna_remlink(listbase, vlink);
175   MEM_freeN(vlink);
176 }
177 
rna_freelistN(ListBase * listbase)178 void rna_freelistN(ListBase *listbase)
179 {
180   Link *link, *next;
181 
182   for (link = listbase->first; link; link = next) {
183     next = link->next;
184     MEM_freeN(link);
185   }
186 
187   listbase->first = listbase->last = NULL;
188 }
189 
rna_brna_structs_add(BlenderRNA * brna,StructRNA * srna)190 static void rna_brna_structs_add(BlenderRNA *brna, StructRNA *srna)
191 {
192   rna_addtail(&brna->structs, srna);
193   brna->structs_len += 1;
194 
195   /* This exception is only needed for pre-processing.
196    * otherwise we don't allow empty names. */
197   if ((srna->flag & STRUCT_PUBLIC_NAMESPACE) && (srna->identifier[0] != '\0')) {
198     BLI_ghash_insert(brna->structs_map, (void *)srna->identifier, srna);
199   }
200 }
201 
202 #ifdef RNA_RUNTIME
rna_brna_structs_remove_and_free(BlenderRNA * brna,StructRNA * srna)203 static void rna_brna_structs_remove_and_free(BlenderRNA *brna, StructRNA *srna)
204 {
205   if ((srna->flag & STRUCT_PUBLIC_NAMESPACE) && brna->structs_map) {
206     if (srna->identifier[0] != '\0') {
207       BLI_ghash_remove(brna->structs_map, (void *)srna->identifier, NULL, NULL);
208     }
209   }
210 
211   RNA_def_struct_free_pointers(NULL, srna);
212 
213   if (srna->flag & STRUCT_RUNTIME) {
214     rna_freelinkN(&brna->structs, srna);
215   }
216   brna->structs_len -= 1;
217 }
218 #endif
219 
DNA_struct_find_nr_wrapper(const struct SDNA * sdna,const char * struct_name)220 static int DNA_struct_find_nr_wrapper(const struct SDNA *sdna, const char *struct_name)
221 {
222   struct_name = DNA_struct_rename_legacy_hack_static_from_alias(struct_name);
223 #ifdef RNA_RUNTIME
224   /* We may support this at some point but for now we don't. */
225   BLI_assert(0);
226 #else
227   struct_name = BLI_ghash_lookup_default(
228       g_version_data.struct_map_static_from_alias, struct_name, (void *)struct_name);
229 #endif
230   return DNA_struct_find_nr(sdna, struct_name);
231 }
232 
rna_find_struct_def(StructRNA * srna)233 StructDefRNA *rna_find_struct_def(StructRNA *srna)
234 {
235   StructDefRNA *dsrna;
236 
237   if (!DefRNA.preprocess) {
238     /* we should never get here */
239     CLOG_ERROR(&LOG, "only at preprocess time.");
240     return NULL;
241   }
242 
243   dsrna = DefRNA.structs.last;
244   for (; dsrna; dsrna = dsrna->cont.prev) {
245     if (dsrna->srna == srna) {
246       return dsrna;
247     }
248   }
249 
250   return NULL;
251 }
252 
rna_find_struct_property_def(StructRNA * srna,PropertyRNA * prop)253 PropertyDefRNA *rna_find_struct_property_def(StructRNA *srna, PropertyRNA *prop)
254 {
255   StructDefRNA *dsrna;
256   PropertyDefRNA *dprop;
257 
258   if (!DefRNA.preprocess) {
259     /* we should never get here */
260     CLOG_ERROR(&LOG, "only at preprocess time.");
261     return NULL;
262   }
263 
264   dsrna = rna_find_struct_def(srna);
265   dprop = dsrna->cont.properties.last;
266   for (; dprop; dprop = dprop->prev) {
267     if (dprop->prop == prop) {
268       return dprop;
269     }
270   }
271 
272   dsrna = DefRNA.structs.last;
273   for (; dsrna; dsrna = dsrna->cont.prev) {
274     dprop = dsrna->cont.properties.last;
275     for (; dprop; dprop = dprop->prev) {
276       if (dprop->prop == prop) {
277         return dprop;
278       }
279     }
280   }
281 
282   return NULL;
283 }
284 
285 #if 0
286 static PropertyDefRNA *rna_find_property_def(PropertyRNA *prop)
287 {
288   PropertyDefRNA *dprop;
289 
290   if (!DefRNA.preprocess) {
291     /* we should never get here */
292     CLOG_ERROR(&LOG, "only at preprocess time.");
293     return NULL;
294   }
295 
296   dprop = rna_find_struct_property_def(DefRNA.laststruct, prop);
297   if (dprop) {
298     return dprop;
299   }
300 
301   dprop = rna_find_parameter_def(prop);
302   if (dprop) {
303     return dprop;
304   }
305 
306   return NULL;
307 }
308 #endif
309 
rna_find_function_def(FunctionRNA * func)310 FunctionDefRNA *rna_find_function_def(FunctionRNA *func)
311 {
312   StructDefRNA *dsrna;
313   FunctionDefRNA *dfunc;
314 
315   if (!DefRNA.preprocess) {
316     /* we should never get here */
317     CLOG_ERROR(&LOG, "only at preprocess time.");
318     return NULL;
319   }
320 
321   dsrna = rna_find_struct_def(DefRNA.laststruct);
322   dfunc = dsrna->functions.last;
323   for (; dfunc; dfunc = dfunc->cont.prev) {
324     if (dfunc->func == func) {
325       return dfunc;
326     }
327   }
328 
329   dsrna = DefRNA.structs.last;
330   for (; dsrna; dsrna = dsrna->cont.prev) {
331     dfunc = dsrna->functions.last;
332     for (; dfunc; dfunc = dfunc->cont.prev) {
333       if (dfunc->func == func) {
334         return dfunc;
335       }
336     }
337   }
338 
339   return NULL;
340 }
341 
rna_find_parameter_def(PropertyRNA * parm)342 PropertyDefRNA *rna_find_parameter_def(PropertyRNA *parm)
343 {
344   StructDefRNA *dsrna;
345   FunctionDefRNA *dfunc;
346   PropertyDefRNA *dparm;
347 
348   if (!DefRNA.preprocess) {
349     /* we should never get here */
350     CLOG_ERROR(&LOG, "only at preprocess time.");
351     return NULL;
352   }
353 
354   dsrna = rna_find_struct_def(DefRNA.laststruct);
355   dfunc = dsrna->functions.last;
356   for (; dfunc; dfunc = dfunc->cont.prev) {
357     dparm = dfunc->cont.properties.last;
358     for (; dparm; dparm = dparm->prev) {
359       if (dparm->prop == parm) {
360         return dparm;
361       }
362     }
363   }
364 
365   dsrna = DefRNA.structs.last;
366   for (; dsrna; dsrna = dsrna->cont.prev) {
367     dfunc = dsrna->functions.last;
368     for (; dfunc; dfunc = dfunc->cont.prev) {
369       dparm = dfunc->cont.properties.last;
370       for (; dparm; dparm = dparm->prev) {
371         if (dparm->prop == parm) {
372           return dparm;
373         }
374       }
375     }
376   }
377 
378   return NULL;
379 }
380 
rna_find_container_def(ContainerRNA * cont)381 static ContainerDefRNA *rna_find_container_def(ContainerRNA *cont)
382 {
383   StructDefRNA *ds;
384   FunctionDefRNA *dfunc;
385 
386   if (!DefRNA.preprocess) {
387     /* we should never get here */
388     CLOG_ERROR(&LOG, "only at preprocess time.");
389     return NULL;
390   }
391 
392   ds = rna_find_struct_def((StructRNA *)cont);
393   if (ds) {
394     return &ds->cont;
395   }
396 
397   dfunc = rna_find_function_def((FunctionRNA *)cont);
398   if (dfunc) {
399     return &dfunc->cont;
400   }
401 
402   return NULL;
403 }
404 
405 /* DNA utility function for looking up members */
406 
407 typedef struct DNAStructMember {
408   const char *type;
409   const char *name;
410   int arraylength;
411   int pointerlevel;
412   int offset;
413   int size;
414 } DNAStructMember;
415 
rna_member_cmp(const char * name,const char * oname)416 static int rna_member_cmp(const char *name, const char *oname)
417 {
418   int a = 0;
419 
420   /* compare without pointer or array part */
421   while (name[0] == '*') {
422     name++;
423   }
424   while (oname[0] == '*') {
425     oname++;
426   }
427 
428   while (1) {
429     if (name[a] == '[' && oname[a] == 0) {
430       return 1;
431     }
432     if (name[a] == '[' && oname[a] == '[') {
433       return 1;
434     }
435     if (name[a] == 0) {
436       break;
437     }
438     if (name[a] != oname[a]) {
439       return 0;
440     }
441     a++;
442   }
443   if (name[a] == 0 && oname[a] == '.') {
444     return 2;
445   }
446   if (name[a] == 0 && oname[a] == '-' && oname[a + 1] == '>') {
447     return 3;
448   }
449 
450   return (name[a] == oname[a]);
451 }
452 
rna_find_sdna_member(SDNA * sdna,const char * structname,const char * membername,DNAStructMember * smember,int * offset)453 static int rna_find_sdna_member(SDNA *sdna,
454                                 const char *structname,
455                                 const char *membername,
456                                 DNAStructMember *smember,
457                                 int *offset)
458 {
459   const char *dnaname;
460   int b, structnr, cmp;
461 
462   if (!DefRNA.preprocess) {
463     CLOG_ERROR(&LOG, "only during preprocessing.");
464     return 0;
465   }
466   structnr = DNA_struct_find_nr_wrapper(sdna, structname);
467 
468   smember->offset = -1;
469   if (structnr == -1) {
470     if (offset) {
471       *offset = -1;
472     }
473     return 0;
474   }
475 
476   const SDNA_Struct *struct_info = sdna->structs[structnr];
477   for (int a = 0; a < struct_info->members_len; a++) {
478     const SDNA_StructMember *member = &struct_info->members[a];
479     const int size = DNA_elem_size_nr(sdna, member->type, member->name);
480     dnaname = sdna->alias.names[member->name];
481     cmp = rna_member_cmp(dnaname, membername);
482 
483     if (cmp == 1) {
484       smember->type = sdna->alias.types[member->type];
485       smember->name = dnaname;
486       smember->offset = *offset;
487       smember->size = size;
488 
489       if (strstr(membername, "[")) {
490         smember->arraylength = 0;
491       }
492       else {
493         smember->arraylength = DNA_elem_array_size(smember->name);
494       }
495 
496       smember->pointerlevel = 0;
497       for (b = 0; dnaname[b] == '*'; b++) {
498         smember->pointerlevel++;
499       }
500 
501       return 1;
502     }
503     if (cmp == 2) {
504       smember->type = "";
505       smember->name = dnaname;
506       smember->offset = *offset;
507       smember->size = size;
508       smember->pointerlevel = 0;
509       smember->arraylength = 0;
510 
511       membername = strstr(membername, ".") + strlen(".");
512       rna_find_sdna_member(sdna, sdna->alias.types[member->type], membername, smember, offset);
513 
514       return 1;
515     }
516     else if (cmp == 3) {
517       smember->type = "";
518       smember->name = dnaname;
519       smember->offset = *offset;
520       smember->size = size;
521       smember->pointerlevel = 0;
522       smember->arraylength = 0;
523 
524       if (offset) {
525         *offset = -1;
526       }
527       membername = strstr(membername, "->") + strlen("->");
528       rna_find_sdna_member(sdna, sdna->alias.types[member->type], membername, smember, offset);
529 
530       return 1;
531     }
532 
533     if (offset && *offset != -1) {
534       *offset += size;
535     }
536   }
537 
538   return 0;
539 }
540 
rna_validate_identifier(const char * identifier,char * error,bool property)541 static int rna_validate_identifier(const char *identifier, char *error, bool property)
542 {
543   int a = 0;
544 
545   /** List is from:
546    * \code{.py}
547    * ", ".join([
548    *     '"%s"' % kw for kw in __import__("keyword").kwlist
549    *     if kw not in {"False", "None", "True"}
550    * ])
551    * \endcode
552    */
553   static const char *kwlist[] = {
554       /* "False", "None", "True", */
555       "and",    "as",   "assert", "async",  "await",    "break", "class", "continue", "def",
556       "del",    "elif", "else",   "except", "finally",  "for",   "from",  "global",   "if",
557       "import", "in",   "is",     "lambda", "nonlocal", "not",   "or",    "pass",     "raise",
558       "return", "try",  "while",  "with",   "yield",    NULL,
559   };
560 
561   if (!isalpha(identifier[0])) {
562     strcpy(error, "first character failed isalpha() check");
563     return 0;
564   }
565 
566   for (a = 0; identifier[a]; a++) {
567     if (DefRNA.preprocess && property) {
568       if (isalpha(identifier[a]) && isupper(identifier[a])) {
569         strcpy(error, "property names must contain lower case characters only");
570         return 0;
571       }
572     }
573 
574     if (identifier[a] == '_') {
575       continue;
576     }
577 
578     if (identifier[a] == ' ') {
579       strcpy(error, "spaces are not okay in identifier names");
580       return 0;
581     }
582 
583     if (isalnum(identifier[a]) == 0) {
584       strcpy(error, "one of the characters failed an isalnum() check and is not an underscore");
585       return 0;
586     }
587   }
588 
589   for (a = 0; kwlist[a]; a++) {
590     if (STREQ(identifier, kwlist[a])) {
591       strcpy(error, "this keyword is reserved by python");
592       return 0;
593     }
594   }
595 
596   if (property) {
597     static const char *kwlist_prop[] = {
598         /* not keywords but reserved all the same because py uses */
599         "keys",
600         "values",
601         "items",
602         "get",
603         NULL,
604     };
605 
606     for (a = 0; kwlist_prop[a]; a++) {
607       if (STREQ(identifier, kwlist_prop[a])) {
608         strcpy(error, "this keyword is reserved by python");
609         return 0;
610       }
611     }
612   }
613 
614   return 1;
615 }
616 
RNA_identifier_sanitize(char * identifier,int property)617 void RNA_identifier_sanitize(char *identifier, int property)
618 {
619   int a = 0;
620 
621   /*  list from http://docs.python.org/py3k/reference/lexical_analysis.html#keywords */
622   static const char *kwlist[] = {
623       /* "False", "None", "True", */
624       "and",    "as",     "assert", "break",   "class",    "continue", "def",    "del",
625       "elif",   "else",   "except", "finally", "for",      "from",     "global", "if",
626       "import", "in",     "is",     "lambda",  "nonlocal", "not",      "or",     "pass",
627       "raise",  "return", "try",    "while",   "with",     "yield",    NULL,
628   };
629 
630   if (!isalpha(identifier[0])) {
631     /* first character failed isalpha() check */
632     identifier[0] = '_';
633   }
634 
635   for (a = 0; identifier[a]; a++) {
636     if (DefRNA.preprocess && property) {
637       if (isalpha(identifier[a]) && isupper(identifier[a])) {
638         /* property names must contain lower case characters only */
639         identifier[a] = tolower(identifier[a]);
640       }
641     }
642 
643     if (identifier[a] == '_') {
644       continue;
645     }
646 
647     if (identifier[a] == ' ') {
648       /* spaces are not okay in identifier names */
649       identifier[a] = '_';
650     }
651 
652     if (isalnum(identifier[a]) == 0) {
653       /* one of the characters failed an isalnum() check and is not an underscore */
654       identifier[a] = '_';
655     }
656   }
657 
658   for (a = 0; kwlist[a]; a++) {
659     if (STREQ(identifier, kwlist[a])) {
660       /* this keyword is reserved by python.
661        * just replace the last character by '_' to keep it readable.
662        */
663       identifier[strlen(identifier) - 1] = '_';
664       break;
665     }
666   }
667 
668   if (property) {
669     static const char *kwlist_prop[] = {
670         /* not keywords but reserved all the same because py uses */
671         "keys",
672         "values",
673         "items",
674         "get",
675         NULL,
676     };
677 
678     for (a = 0; kwlist_prop[a]; a++) {
679       if (STREQ(identifier, kwlist_prop[a])) {
680         /* this keyword is reserved by python.
681          * just replace the last character by '_' to keep it readable.
682          */
683         identifier[strlen(identifier) - 1] = '_';
684         break;
685       }
686     }
687   }
688 }
689 
690 /* Blender Data Definition */
691 
RNA_create(void)692 BlenderRNA *RNA_create(void)
693 {
694   BlenderRNA *brna;
695 
696   brna = MEM_callocN(sizeof(BlenderRNA), "BlenderRNA");
697   const char *error_message = NULL;
698 
699   BLI_listbase_clear(&DefRNA.structs);
700   brna->structs_map = BLI_ghash_str_new_ex(__func__, 2048);
701 
702   DefRNA.error = false;
703   DefRNA.preprocess = true;
704 
705   DefRNA.sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, &error_message);
706   if (DefRNA.sdna == NULL) {
707     CLOG_ERROR(&LOG, "Failed to decode SDNA: %s.", error_message);
708     DefRNA.error = true;
709   }
710 
711   /* We need both alias and static (on-disk) DNA names. */
712   DNA_sdna_alias_data_ensure(DefRNA.sdna);
713 
714 #ifndef RNA_RUNTIME
715   DNA_alias_maps(DNA_RENAME_STATIC_FROM_ALIAS, &g_version_data.struct_map_static_from_alias, NULL);
716 #endif
717 
718   return brna;
719 }
720 
RNA_define_free(BlenderRNA * UNUSED (brna))721 void RNA_define_free(BlenderRNA *UNUSED(brna))
722 {
723   StructDefRNA *ds;
724   FunctionDefRNA *dfunc;
725   AllocDefRNA *alloc;
726 
727   for (alloc = DefRNA.allocs.first; alloc; alloc = alloc->next) {
728     MEM_freeN(alloc->mem);
729   }
730   rna_freelistN(&DefRNA.allocs);
731 
732   for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
733     for (dfunc = ds->functions.first; dfunc; dfunc = dfunc->cont.next) {
734       rna_freelistN(&dfunc->cont.properties);
735     }
736 
737     rna_freelistN(&ds->cont.properties);
738     rna_freelistN(&ds->functions);
739   }
740 
741   rna_freelistN(&DefRNA.structs);
742 
743   if (DefRNA.sdna) {
744     DNA_sdna_free(DefRNA.sdna);
745     DefRNA.sdna = NULL;
746   }
747 
748   DefRNA.error = false;
749 }
750 
RNA_define_verify_sdna(bool verify)751 void RNA_define_verify_sdna(bool verify)
752 {
753   DefRNA.verify = verify;
754 }
755 
756 /**
757  * Properties defined when this is enabled are lib-overridable by default (except for Pointer
758  * ones).
759  */
RNA_define_lib_overridable(const bool make_overridable)760 void RNA_define_lib_overridable(const bool make_overridable)
761 {
762   DefRNA.make_overridable = make_overridable;
763 }
764 
765 #ifndef RNA_RUNTIME
RNA_define_animate_sdna(bool animate)766 void RNA_define_animate_sdna(bool animate)
767 {
768   DefRNA.animate = animate;
769 }
770 #endif
771 
772 #ifndef RNA_RUNTIME
RNA_define_fallback_property_update(int noteflag,const char * updatefunc)773 void RNA_define_fallback_property_update(int noteflag, const char *updatefunc)
774 {
775   DefRNA.fallback.property_update.noteflag = noteflag;
776   DefRNA.fallback.property_update.updatefunc = updatefunc;
777 }
778 #endif
779 
RNA_struct_free_extension(StructRNA * srna,ExtensionRNA * rna_ext)780 void RNA_struct_free_extension(StructRNA *srna, ExtensionRNA *rna_ext)
781 {
782 #ifdef RNA_RUNTIME
783   rna_ext->free(rna_ext->data);            /* decref's the PyObject that the srna owns */
784   RNA_struct_blender_type_set(srna, NULL); /* this gets accessed again - XXX fixme */
785 
786   /* NULL the srna's value so RNA_struct_free wont complain of a leak */
787   RNA_struct_py_type_set(srna, NULL);
788 
789 #else
790   (void)srna;
791   (void)rna_ext;
792 #endif
793 }
794 
RNA_struct_free(BlenderRNA * brna,StructRNA * srna)795 void RNA_struct_free(BlenderRNA *brna, StructRNA *srna)
796 {
797 #ifdef RNA_RUNTIME
798   FunctionRNA *func, *nextfunc;
799   PropertyRNA *prop, *nextprop;
800   PropertyRNA *parm, *nextparm;
801 
802 #  if 0
803   if (srna->flag & STRUCT_RUNTIME) {
804     if (RNA_struct_py_type_get(srna)) {
805       fprintf(stderr, "%s '%s' freed while holding a python reference.", srna->identifier);
806     }
807   }
808 #  endif
809 
810   for (prop = srna->cont.properties.first; prop; prop = nextprop) {
811     nextprop = prop->next;
812 
813     RNA_def_property_free_pointers(prop);
814 
815     if (prop->flag_internal & PROP_INTERN_RUNTIME) {
816       rna_freelinkN(&srna->cont.properties, prop);
817     }
818   }
819 
820   for (func = srna->functions.first; func; func = nextfunc) {
821     nextfunc = func->cont.next;
822 
823     for (parm = func->cont.properties.first; parm; parm = nextparm) {
824       nextparm = parm->next;
825 
826       RNA_def_property_free_pointers(parm);
827 
828       if (parm->flag_internal & PROP_INTERN_RUNTIME) {
829         rna_freelinkN(&func->cont.properties, parm);
830       }
831     }
832 
833     RNA_def_func_free_pointers(func);
834 
835     if (func->flag & FUNC_RUNTIME) {
836       rna_freelinkN(&srna->functions, func);
837     }
838   }
839 
840   rna_brna_structs_remove_and_free(brna, srna);
841 #else
842   UNUSED_VARS(brna, srna);
843 #endif
844 }
845 
RNA_free(BlenderRNA * brna)846 void RNA_free(BlenderRNA *brna)
847 {
848   StructRNA *srna, *nextsrna;
849   FunctionRNA *func;
850 
851   BLI_ghash_free(brna->structs_map, NULL, NULL);
852   brna->structs_map = NULL;
853 
854   if (DefRNA.preprocess) {
855     RNA_define_free(brna);
856 
857     for (srna = brna->structs.first; srna; srna = srna->cont.next) {
858       for (func = srna->functions.first; func; func = func->cont.next) {
859         rna_freelistN(&func->cont.properties);
860       }
861 
862       rna_freelistN(&srna->cont.properties);
863       rna_freelistN(&srna->functions);
864     }
865 
866     rna_freelistN(&brna->structs);
867 
868     MEM_freeN(brna);
869   }
870   else {
871     for (srna = brna->structs.first; srna; srna = nextsrna) {
872       nextsrna = srna->cont.next;
873       RNA_struct_free(brna, srna);
874     }
875   }
876 
877 #ifndef RNA_RUNTIME
878   BLI_ghash_free(g_version_data.struct_map_static_from_alias, NULL, NULL);
879   g_version_data.struct_map_static_from_alias = NULL;
880 #endif
881 }
882 
rna_property_type_sizeof(PropertyType type)883 static size_t rna_property_type_sizeof(PropertyType type)
884 {
885   switch (type) {
886     case PROP_BOOLEAN:
887       return sizeof(BoolPropertyRNA);
888     case PROP_INT:
889       return sizeof(IntPropertyRNA);
890     case PROP_FLOAT:
891       return sizeof(FloatPropertyRNA);
892     case PROP_STRING:
893       return sizeof(StringPropertyRNA);
894     case PROP_ENUM:
895       return sizeof(EnumPropertyRNA);
896     case PROP_POINTER:
897       return sizeof(PointerPropertyRNA);
898     case PROP_COLLECTION:
899       return sizeof(CollectionPropertyRNA);
900     default:
901       return 0;
902   }
903 }
904 
rna_find_def_struct(StructRNA * srna)905 static StructDefRNA *rna_find_def_struct(StructRNA *srna)
906 {
907   StructDefRNA *ds;
908 
909   for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
910     if (ds->srna == srna) {
911       return ds;
912     }
913   }
914 
915   return NULL;
916 }
917 
918 /* Struct Definition */
RNA_def_struct_ptr(BlenderRNA * brna,const char * identifier,StructRNA * srnafrom)919 StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom)
920 {
921   StructRNA *srna;
922   StructDefRNA *ds = NULL, *dsfrom = NULL;
923   PropertyRNA *prop;
924 
925   if (DefRNA.preprocess) {
926     char error[512];
927 
928     if (rna_validate_identifier(identifier, error, false) == 0) {
929       CLOG_ERROR(&LOG, "struct identifier \"%s\" error - %s", identifier, error);
930       DefRNA.error = true;
931     }
932   }
933 
934   srna = MEM_callocN(sizeof(StructRNA), "StructRNA");
935   DefRNA.laststruct = srna;
936 
937   if (srnafrom) {
938     /* copy from struct to derive stuff, a bit clumsy since we can't
939      * use MEM_dupallocN, data structs may not be alloced but builtin */
940     memcpy(srna, srnafrom, sizeof(StructRNA));
941     srna->cont.prophash = NULL;
942     BLI_listbase_clear(&srna->cont.properties);
943     BLI_listbase_clear(&srna->functions);
944     srna->py_type = NULL;
945 
946     srna->base = srnafrom;
947 
948     if (DefRNA.preprocess) {
949       dsfrom = rna_find_def_struct(srnafrom);
950     }
951     else {
952       if (srnafrom->flag & STRUCT_PUBLIC_NAMESPACE_INHERIT) {
953         srna->flag |= STRUCT_PUBLIC_NAMESPACE | STRUCT_PUBLIC_NAMESPACE_INHERIT;
954       }
955       else {
956         srna->flag &= ~(STRUCT_PUBLIC_NAMESPACE | STRUCT_PUBLIC_NAMESPACE_INHERIT);
957       }
958     }
959   }
960 
961   srna->identifier = identifier;
962   srna->name = identifier; /* may be overwritten later RNA_def_struct_ui_text */
963   srna->description = "";
964   /* may be overwritten later RNA_def_struct_translation_context */
965   srna->translation_context = BLT_I18NCONTEXT_DEFAULT_BPYRNA;
966   if (!srnafrom) {
967     srna->icon = ICON_DOT;
968     srna->flag |= STRUCT_UNDO;
969   }
970 
971   if (DefRNA.preprocess) {
972     srna->flag |= STRUCT_PUBLIC_NAMESPACE;
973   }
974 
975   rna_brna_structs_add(brna, srna);
976 
977   if (DefRNA.preprocess) {
978     ds = MEM_callocN(sizeof(StructDefRNA), "StructDefRNA");
979     ds->srna = srna;
980     rna_addtail(&DefRNA.structs, ds);
981 
982     if (dsfrom) {
983       ds->dnafromname = dsfrom->dnaname;
984     }
985   }
986 
987   /* in preprocess, try to find sdna */
988   if (DefRNA.preprocess) {
989     RNA_def_struct_sdna(srna, srna->identifier);
990   }
991   else {
992     srna->flag |= STRUCT_RUNTIME;
993   }
994 
995   if (srnafrom) {
996     srna->nameproperty = srnafrom->nameproperty;
997     srna->iteratorproperty = srnafrom->iteratorproperty;
998   }
999   else {
1000     /* define some builtin properties */
1001     prop = RNA_def_property(&srna->cont, "rna_properties", PROP_COLLECTION, PROP_NONE);
1002     prop->flag_internal |= PROP_INTERN_BUILTIN;
1003     RNA_def_property_ui_text(prop, "Properties", "RNA property collection");
1004 
1005     if (DefRNA.preprocess) {
1006       RNA_def_property_struct_type(prop, "Property");
1007       RNA_def_property_collection_funcs(prop,
1008                                         "rna_builtin_properties_begin",
1009                                         "rna_builtin_properties_next",
1010                                         "rna_iterator_listbase_end",
1011                                         "rna_builtin_properties_get",
1012                                         NULL,
1013                                         NULL,
1014                                         "rna_builtin_properties_lookup_string",
1015                                         NULL);
1016     }
1017     else {
1018 #ifdef RNA_RUNTIME
1019       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
1020       cprop->begin = rna_builtin_properties_begin;
1021       cprop->next = rna_builtin_properties_next;
1022       cprop->get = rna_builtin_properties_get;
1023       cprop->item_type = &RNA_Property;
1024 #endif
1025     }
1026 
1027     prop = RNA_def_property(&srna->cont, "rna_type", PROP_POINTER, PROP_NONE);
1028     RNA_def_property_flag(prop, PROP_HIDDEN);
1029     RNA_def_property_ui_text(prop, "RNA", "RNA type definition");
1030 
1031     if (DefRNA.preprocess) {
1032       RNA_def_property_struct_type(prop, "Struct");
1033       RNA_def_property_pointer_funcs(prop, "rna_builtin_type_get", NULL, NULL, NULL);
1034     }
1035     else {
1036 #ifdef RNA_RUNTIME
1037       PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1038       pprop->get = rna_builtin_type_get;
1039       pprop->type = &RNA_Struct;
1040 #endif
1041     }
1042   }
1043 
1044   return srna;
1045 }
1046 
RNA_def_struct(BlenderRNA * brna,const char * identifier,const char * from)1047 StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
1048 {
1049   StructRNA *srnafrom = NULL;
1050 
1051   /* only use RNA_def_struct() while pre-processing, otherwise use RNA_def_struct_ptr() */
1052   BLI_assert(DefRNA.preprocess);
1053 
1054   if (from) {
1055     /* find struct to derive from */
1056     /* Inline RNA_struct_find(...) because it wont link from here. */
1057     srnafrom = BLI_ghash_lookup(brna->structs_map, from);
1058     if (!srnafrom) {
1059       CLOG_ERROR(&LOG, "struct %s not found to define %s.", from, identifier);
1060       DefRNA.error = true;
1061     }
1062   }
1063 
1064   return RNA_def_struct_ptr(brna, identifier, srnafrom);
1065 }
1066 
RNA_def_struct_sdna(StructRNA * srna,const char * structname)1067 void RNA_def_struct_sdna(StructRNA *srna, const char *structname)
1068 {
1069   StructDefRNA *ds;
1070 
1071   if (!DefRNA.preprocess) {
1072     CLOG_ERROR(&LOG, "only during preprocessing.");
1073     return;
1074   }
1075 
1076   ds = rna_find_def_struct(srna);
1077 
1078   /* There are far too many structs which initialize without valid DNA struct names,
1079    * this can't be checked without adding an option to disable
1080    * (tested this and it means changes all over - Campbell) */
1081 #if 0
1082   if (DNA_struct_find_nr_wrapper(DefRNA.sdna, structname) == -1) {
1083     if (!DefRNA.silent) {
1084       CLOG_ERROR(&LOG, "%s not found.", structname);
1085       DefRNA.error = true;
1086     }
1087     return;
1088   }
1089 #endif
1090 
1091   ds->dnaname = structname;
1092 }
1093 
RNA_def_struct_sdna_from(StructRNA * srna,const char * structname,const char * propname)1094 void RNA_def_struct_sdna_from(StructRNA *srna, const char *structname, const char *propname)
1095 {
1096   StructDefRNA *ds;
1097 
1098   if (!DefRNA.preprocess) {
1099     CLOG_ERROR(&LOG, "only during preprocessing.");
1100     return;
1101   }
1102 
1103   ds = rna_find_def_struct(srna);
1104 
1105   if (!ds->dnaname) {
1106     CLOG_ERROR(&LOG, "%s base struct must know DNA already.", structname);
1107     return;
1108   }
1109 
1110   if (DNA_struct_find_nr_wrapper(DefRNA.sdna, structname) == -1) {
1111     if (!DefRNA.silent) {
1112       CLOG_ERROR(&LOG, "%s not found.", structname);
1113       DefRNA.error = true;
1114     }
1115     return;
1116   }
1117 
1118   ds->dnafromprop = propname;
1119   ds->dnaname = structname;
1120 }
1121 
RNA_def_struct_name_property(struct StructRNA * srna,struct PropertyRNA * prop)1122 void RNA_def_struct_name_property(struct StructRNA *srna, struct PropertyRNA *prop)
1123 {
1124   if (prop->type != PROP_STRING) {
1125     CLOG_ERROR(&LOG, "\"%s.%s\", must be a string property.", srna->identifier, prop->identifier);
1126     DefRNA.error = true;
1127   }
1128   else {
1129     srna->nameproperty = prop;
1130   }
1131 }
1132 
RNA_def_struct_nested(BlenderRNA * brna,StructRNA * srna,const char * structname)1133 void RNA_def_struct_nested(BlenderRNA *brna, StructRNA *srna, const char *structname)
1134 {
1135   StructRNA *srnafrom;
1136 
1137   /* find struct to derive from */
1138   srnafrom = BLI_ghash_lookup(brna->structs_map, structname);
1139   if (!srnafrom) {
1140     CLOG_ERROR(&LOG, "struct %s not found for %s.", structname, srna->identifier);
1141     DefRNA.error = true;
1142   }
1143 
1144   srna->nested = srnafrom;
1145 }
1146 
RNA_def_struct_flag(StructRNA * srna,int flag)1147 void RNA_def_struct_flag(StructRNA *srna, int flag)
1148 {
1149   srna->flag |= flag;
1150 }
1151 
RNA_def_struct_clear_flag(StructRNA * srna,int flag)1152 void RNA_def_struct_clear_flag(StructRNA *srna, int flag)
1153 {
1154   srna->flag &= ~flag;
1155 }
1156 
RNA_def_struct_property_tags(StructRNA * srna,const EnumPropertyItem * prop_tag_defines)1157 void RNA_def_struct_property_tags(StructRNA *srna, const EnumPropertyItem *prop_tag_defines)
1158 {
1159   srna->prop_tag_defines = prop_tag_defines;
1160 }
1161 
RNA_def_struct_refine_func(StructRNA * srna,const char * refine)1162 void RNA_def_struct_refine_func(StructRNA *srna, const char *refine)
1163 {
1164   if (!DefRNA.preprocess) {
1165     CLOG_ERROR(&LOG, "only during preprocessing.");
1166     return;
1167   }
1168 
1169   if (refine) {
1170     srna->refine = (StructRefineFunc)refine;
1171   }
1172 }
1173 
RNA_def_struct_idprops_func(StructRNA * srna,const char * idproperties)1174 void RNA_def_struct_idprops_func(StructRNA *srna, const char *idproperties)
1175 {
1176   if (!DefRNA.preprocess) {
1177     CLOG_ERROR(&LOG, "only during preprocessing.");
1178     return;
1179   }
1180 
1181   if (idproperties) {
1182     srna->idproperties = (IDPropertiesFunc)idproperties;
1183   }
1184 }
1185 
RNA_def_struct_register_funcs(StructRNA * srna,const char * reg,const char * unreg,const char * instance)1186 void RNA_def_struct_register_funcs(StructRNA *srna,
1187                                    const char *reg,
1188                                    const char *unreg,
1189                                    const char *instance)
1190 {
1191   if (!DefRNA.preprocess) {
1192     CLOG_ERROR(&LOG, "only during preprocessing.");
1193     return;
1194   }
1195 
1196   if (reg) {
1197     srna->reg = (StructRegisterFunc)reg;
1198   }
1199   if (unreg) {
1200     srna->unreg = (StructUnregisterFunc)unreg;
1201   }
1202   if (instance) {
1203     srna->instance = (StructInstanceFunc)instance;
1204   }
1205 }
1206 
RNA_def_struct_path_func(StructRNA * srna,const char * path)1207 void RNA_def_struct_path_func(StructRNA *srna, const char *path)
1208 {
1209   if (!DefRNA.preprocess) {
1210     CLOG_ERROR(&LOG, "only during preprocessing.");
1211     return;
1212   }
1213 
1214   if (path) {
1215     srna->path = (StructPathFunc)path;
1216   }
1217 }
1218 
RNA_def_struct_identifier(BlenderRNA * brna,StructRNA * srna,const char * identifier)1219 void RNA_def_struct_identifier(BlenderRNA *brna, StructRNA *srna, const char *identifier)
1220 {
1221   if (DefRNA.preprocess) {
1222     CLOG_ERROR(&LOG, "only at runtime.");
1223     return;
1224   }
1225 
1226   /* Operator registration may set twice, see: operator_properties_init */
1227   if (srna->flag & STRUCT_PUBLIC_NAMESPACE) {
1228     if (identifier != srna->identifier) {
1229       if (srna->identifier[0] != '\0') {
1230         BLI_ghash_remove(brna->structs_map, (void *)srna->identifier, NULL, NULL);
1231       }
1232       if (identifier[0] != '\0') {
1233         BLI_ghash_insert(brna->structs_map, (void *)identifier, srna);
1234       }
1235     }
1236   }
1237 
1238   srna->identifier = identifier;
1239 }
1240 
1241 /**
1242  * Only used in one case when we name the struct for the purpose of useful error messages.
1243  */
RNA_def_struct_identifier_no_struct_map(StructRNA * srna,const char * identifier)1244 void RNA_def_struct_identifier_no_struct_map(StructRNA *srna, const char *identifier)
1245 {
1246   if (DefRNA.preprocess) {
1247     CLOG_ERROR(&LOG, "only at runtime.");
1248     return;
1249   }
1250 
1251   srna->identifier = identifier;
1252 }
1253 
RNA_def_struct_ui_text(StructRNA * srna,const char * name,const char * description)1254 void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description)
1255 {
1256   DESCR_CHECK(description, srna->identifier, NULL);
1257 
1258   srna->name = name;
1259   srna->description = description;
1260 }
1261 
RNA_def_struct_ui_icon(StructRNA * srna,int icon)1262 void RNA_def_struct_ui_icon(StructRNA *srna, int icon)
1263 {
1264   srna->icon = icon;
1265 }
1266 
RNA_def_struct_translation_context(StructRNA * srna,const char * context)1267 void RNA_def_struct_translation_context(StructRNA *srna, const char *context)
1268 {
1269   srna->translation_context = context ? context : BLT_I18NCONTEXT_DEFAULT_BPYRNA;
1270 }
1271 
1272 /* Property Definition */
1273 
RNA_def_property(StructOrFunctionRNA * cont_,const char * identifier,int type,int subtype)1274 PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_,
1275                               const char *identifier,
1276                               int type,
1277                               int subtype)
1278 {
1279   /*StructRNA *srna = DefRNA.laststruct;*/ /* invalid for python defined props */
1280   ContainerRNA *cont = cont_;
1281   ContainerDefRNA *dcont;
1282   PropertyDefRNA *dprop = NULL;
1283   PropertyRNA *prop;
1284 
1285   if (DefRNA.preprocess) {
1286     char error[512];
1287 
1288     if (rna_validate_identifier(identifier, error, true) == 0) {
1289       CLOG_ERROR(
1290           &LOG, "property identifier \"%s.%s\" - %s", CONTAINER_RNA_ID(cont), identifier, error);
1291       DefRNA.error = true;
1292     }
1293 
1294     dcont = rna_find_container_def(cont);
1295 
1296     /* XXX - toto, detect supertype collisions */
1297     if (rna_findlink(&dcont->properties, identifier)) {
1298       CLOG_ERROR(&LOG, "duplicate identifier \"%s.%s\"", CONTAINER_RNA_ID(cont), identifier);
1299       DefRNA.error = true;
1300     }
1301 
1302     dprop = MEM_callocN(sizeof(PropertyDefRNA), "PropertyDefRNA");
1303     rna_addtail(&dcont->properties, dprop);
1304   }
1305   else {
1306 #ifdef DEBUG
1307     char error[512];
1308     if (rna_validate_identifier(identifier, error, true) == 0) {
1309       CLOG_ERROR(&LOG,
1310                  "runtime property identifier \"%s.%s\" - %s",
1311                  CONTAINER_RNA_ID(cont),
1312                  identifier,
1313                  error);
1314       DefRNA.error = true;
1315     }
1316 #endif
1317   }
1318 
1319   prop = MEM_callocN(rna_property_type_sizeof(type), "PropertyRNA");
1320 
1321   switch (type) {
1322     case PROP_BOOLEAN:
1323       if (DefRNA.preprocess) {
1324         if ((subtype & ~PROP_LAYER_MEMBER) != PROP_NONE) {
1325           CLOG_ERROR(&LOG,
1326                      "subtype does not apply to 'PROP_BOOLEAN' \"%s.%s\"",
1327                      CONTAINER_RNA_ID(cont),
1328                      identifier);
1329           DefRNA.error = true;
1330         }
1331       }
1332       break;
1333     case PROP_INT: {
1334       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1335 
1336 #ifndef RNA_RUNTIME
1337       if (subtype == PROP_DISTANCE) {
1338         CLOG_ERROR(&LOG,
1339                    "subtype does not apply to 'PROP_INT' \"%s.%s\"",
1340                    CONTAINER_RNA_ID(cont),
1341                    identifier);
1342         DefRNA.error = true;
1343       }
1344 #endif
1345 
1346       iprop->hardmin = (subtype == PROP_UNSIGNED) ? 0 : INT_MIN;
1347       iprop->hardmax = INT_MAX;
1348 
1349       iprop->softmin = (subtype == PROP_UNSIGNED) ? 0 : -10000; /* rather arbitrary .. */
1350       iprop->softmax = 10000;
1351       iprop->step = 1;
1352       break;
1353     }
1354     case PROP_FLOAT: {
1355       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
1356 
1357       fprop->hardmin = (subtype == PROP_UNSIGNED) ? 0.0f : -FLT_MAX;
1358       fprop->hardmax = FLT_MAX;
1359 
1360       if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
1361         fprop->softmin = fprop->hardmin = 0.0f;
1362         fprop->softmax = 1.0f;
1363       }
1364       else if (subtype == PROP_FACTOR) {
1365         fprop->softmin = fprop->hardmin = 0.0f;
1366         fprop->softmax = fprop->hardmax = 1.0f;
1367       }
1368       else {
1369         fprop->softmin = (subtype == PROP_UNSIGNED) ? 0.0f : -10000.0f; /* rather arbitrary .. */
1370         fprop->softmax = 10000.0f;
1371       }
1372       fprop->step = 10;
1373       fprop->precision = 3;
1374       break;
1375     }
1376     case PROP_STRING: {
1377       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
1378       /* By default don't allow NULL string args, callers may clear. */
1379       RNA_def_property_flag(prop, PROP_NEVER_NULL);
1380       sprop->defaultvalue = "";
1381       break;
1382     }
1383     case PROP_POINTER:
1384       prop->flag |= PROP_THICK_WRAP; /* needed for default behavior when PARM_RNAPTR is set */
1385       break;
1386     case PROP_ENUM:
1387     case PROP_COLLECTION:
1388       break;
1389     default:
1390       CLOG_ERROR(&LOG, "\"%s.%s\", invalid property type.", CONTAINER_RNA_ID(cont), identifier);
1391       DefRNA.error = true;
1392       return NULL;
1393   }
1394 
1395   if (DefRNA.preprocess) {
1396     dprop->cont = cont;
1397     dprop->prop = prop;
1398   }
1399 
1400   prop->magic = RNA_MAGIC;
1401   prop->identifier = identifier;
1402   prop->type = type;
1403   prop->subtype = subtype;
1404   prop->name = identifier;
1405   prop->description = "";
1406   prop->translation_context = BLT_I18NCONTEXT_DEFAULT_BPYRNA;
1407   /* a priori not raw editable */
1408   prop->rawtype = -1;
1409 
1410   if (type != PROP_COLLECTION && type != PROP_POINTER) {
1411     prop->flag = PROP_EDITABLE;
1412 
1413     if (type != PROP_STRING) {
1414 #ifdef RNA_RUNTIME
1415       prop->flag |= PROP_ANIMATABLE;
1416 #else
1417       if (DefRNA.animate) {
1418         prop->flag |= PROP_ANIMATABLE;
1419       }
1420 #endif
1421     }
1422   }
1423 
1424 #ifndef RNA_RUNTIME
1425   if (DefRNA.make_overridable) {
1426     prop->flag_override |= PROPOVERRIDE_OVERRIDABLE_LIBRARY;
1427   }
1428 #endif
1429 
1430   if (type == PROP_STRING) {
1431     /* used so generated 'get/length/set' functions skip a NULL check
1432      * in some cases we want it */
1433     RNA_def_property_flag(prop, PROP_NEVER_NULL);
1434   }
1435 
1436   if (DefRNA.preprocess) {
1437     switch (type) {
1438       case PROP_BOOLEAN:
1439         DefRNA.silent = true;
1440         RNA_def_property_boolean_sdna(prop, NULL, identifier, 0);
1441         DefRNA.silent = false;
1442         break;
1443       case PROP_INT: {
1444         DefRNA.silent = true;
1445         RNA_def_property_int_sdna(prop, NULL, identifier);
1446         DefRNA.silent = false;
1447         break;
1448       }
1449       case PROP_FLOAT: {
1450         DefRNA.silent = true;
1451         RNA_def_property_float_sdna(prop, NULL, identifier);
1452         DefRNA.silent = false;
1453         break;
1454       }
1455       case PROP_STRING: {
1456         DefRNA.silent = true;
1457         RNA_def_property_string_sdna(prop, NULL, identifier);
1458         DefRNA.silent = false;
1459         break;
1460       }
1461       case PROP_ENUM:
1462         DefRNA.silent = true;
1463         RNA_def_property_enum_sdna(prop, NULL, identifier);
1464         DefRNA.silent = false;
1465         break;
1466       case PROP_POINTER:
1467         DefRNA.silent = true;
1468         RNA_def_property_pointer_sdna(prop, NULL, identifier);
1469         DefRNA.silent = false;
1470         break;
1471       case PROP_COLLECTION:
1472         DefRNA.silent = true;
1473         RNA_def_property_collection_sdna(prop, NULL, identifier, NULL);
1474         DefRNA.silent = false;
1475         break;
1476     }
1477   }
1478   else {
1479     prop->flag |= PROP_IDPROPERTY;
1480     prop->flag_internal |= PROP_INTERN_RUNTIME;
1481 #ifdef RNA_RUNTIME
1482     if (cont->prophash) {
1483       BLI_ghash_insert(cont->prophash, (void *)prop->identifier, prop);
1484     }
1485 #endif
1486   }
1487 
1488   /* Override handling. */
1489   if (DefRNA.preprocess) {
1490     prop->override_diff = (RNAPropOverrideDiff) "rna_property_override_diff_default";
1491     prop->override_store = (RNAPropOverrideStore) "rna_property_override_store_default";
1492     prop->override_apply = (RNAPropOverrideApply) "rna_property_override_apply_default";
1493   }
1494   /* TODO: do we want that for runtime-defined stuff too? I’d say no, but... maybe yes :/ */
1495 
1496 #ifndef RNA_RUNTIME
1497   /* Both are typically cleared. */
1498   RNA_def_property_update(
1499       prop, DefRNA.fallback.property_update.noteflag, DefRNA.fallback.property_update.updatefunc);
1500 #endif
1501 
1502   rna_addtail(&cont->properties, prop);
1503 
1504   return prop;
1505 }
1506 
RNA_def_property_flag(PropertyRNA * prop,PropertyFlag flag)1507 void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
1508 {
1509   prop->flag |= flag;
1510 }
1511 
RNA_def_property_clear_flag(PropertyRNA * prop,PropertyFlag flag)1512 void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag)
1513 {
1514   prop->flag &= ~flag;
1515   if (flag & PROP_PTR_NO_OWNERSHIP) {
1516     prop->flag_internal |= PROP_INTERN_PTR_OWNERSHIP_FORCED;
1517   }
1518 }
1519 
RNA_def_property_override_flag(PropertyRNA * prop,PropertyOverrideFlag flag)1520 void RNA_def_property_override_flag(PropertyRNA *prop, PropertyOverrideFlag flag)
1521 {
1522   prop->flag_override |= flag;
1523 }
1524 
RNA_def_property_override_clear_flag(PropertyRNA * prop,PropertyOverrideFlag flag)1525 void RNA_def_property_override_clear_flag(PropertyRNA *prop, PropertyOverrideFlag flag)
1526 {
1527   prop->flag_override &= ~flag;
1528 }
1529 
1530 /**
1531  * Add the property-tags passed as \a tags to \a prop (if valid).
1532  *
1533  * \note Multiple tags can be set by passing them within \a tags (using bitflags).
1534  * \note Doesn't do any type-checking with the tags defined in the parent StructRNA
1535  *       of \a prop. This should be done before (e.g. see #WM_operatortype_prop_tag).
1536  */
RNA_def_property_tags(PropertyRNA * prop,int tags)1537 void RNA_def_property_tags(PropertyRNA *prop, int tags)
1538 {
1539   prop->tags |= tags;
1540 }
1541 
RNA_def_parameter_flags(PropertyRNA * prop,PropertyFlag flag_property,ParameterFlag flag_parameter)1542 void RNA_def_parameter_flags(PropertyRNA *prop,
1543                              PropertyFlag flag_property,
1544                              ParameterFlag flag_parameter)
1545 {
1546   prop->flag |= flag_property;
1547   prop->flag_parameter |= flag_parameter;
1548 }
1549 
RNA_def_parameter_clear_flags(PropertyRNA * prop,PropertyFlag flag_property,ParameterFlag flag_parameter)1550 void RNA_def_parameter_clear_flags(PropertyRNA *prop,
1551                                    PropertyFlag flag_property,
1552                                    ParameterFlag flag_parameter)
1553 {
1554   prop->flag &= ~flag_property;
1555   prop->flag_parameter &= ~flag_parameter;
1556 }
1557 
RNA_def_property_subtype(PropertyRNA * prop,PropertySubType subtype)1558 void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype)
1559 {
1560   prop->subtype = subtype;
1561 }
1562 
RNA_def_property_array(PropertyRNA * prop,int length)1563 void RNA_def_property_array(PropertyRNA *prop, int length)
1564 {
1565   StructRNA *srna = DefRNA.laststruct;
1566 
1567   if (length < 0) {
1568     CLOG_ERROR(&LOG,
1569                "\"%s.%s\", array length must be zero of greater.",
1570                srna->identifier,
1571                prop->identifier);
1572     DefRNA.error = true;
1573     return;
1574   }
1575 
1576   if (length > RNA_MAX_ARRAY_LENGTH) {
1577     CLOG_ERROR(&LOG,
1578                "\"%s.%s\", array length must be smaller than %d.",
1579                srna->identifier,
1580                prop->identifier,
1581                RNA_MAX_ARRAY_LENGTH);
1582     DefRNA.error = true;
1583     return;
1584   }
1585 
1586   if (prop->arraydimension > 1) {
1587     CLOG_ERROR(&LOG,
1588                "\"%s.%s\", array dimensions has been set to %u but would be overwritten as 1.",
1589                srna->identifier,
1590                prop->identifier,
1591                prop->arraydimension);
1592     DefRNA.error = true;
1593     return;
1594   }
1595 
1596   switch (prop->type) {
1597     case PROP_BOOLEAN:
1598     case PROP_INT:
1599     case PROP_FLOAT:
1600       prop->arraylength[0] = length;
1601       prop->totarraylength = length;
1602       prop->arraydimension = 1;
1603       break;
1604     default:
1605       CLOG_ERROR(&LOG,
1606                  "\"%s.%s\", only boolean/int/float can be array.",
1607                  srna->identifier,
1608                  prop->identifier);
1609       DefRNA.error = true;
1610       break;
1611   }
1612 }
1613 
1614 /* common args for defaults. */
1615 const float rna_default_quaternion[4] = {1, 0, 0, 0};
1616 const float rna_default_axis_angle[4] = {0, 0, 1, 0};
1617 const float rna_default_scale_3d[3] = {1, 1, 1};
1618 
1619 /* common args for length */
1620 const int rna_matrix_dimsize_3x3[] = {3, 3};
1621 const int rna_matrix_dimsize_4x4[] = {4, 4};
1622 const int rna_matrix_dimsize_4x2[] = {4, 2};
1623 
RNA_def_property_multi_array(PropertyRNA * prop,int dimension,const int length[])1624 void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, const int length[])
1625 {
1626   StructRNA *srna = DefRNA.laststruct;
1627   int i;
1628 
1629   if (dimension < 1 || dimension > RNA_MAX_ARRAY_DIMENSION) {
1630     CLOG_ERROR(&LOG,
1631                "\"%s.%s\", array dimension must be between 1 and %d.",
1632                srna->identifier,
1633                prop->identifier,
1634                RNA_MAX_ARRAY_DIMENSION);
1635     DefRNA.error = true;
1636     return;
1637   }
1638 
1639   switch (prop->type) {
1640     case PROP_BOOLEAN:
1641     case PROP_INT:
1642     case PROP_FLOAT:
1643       break;
1644     default:
1645       CLOG_ERROR(&LOG,
1646                  "\"%s.%s\", only boolean/int/float can be array.",
1647                  srna->identifier,
1648                  prop->identifier);
1649       DefRNA.error = true;
1650       break;
1651   }
1652 
1653   prop->arraydimension = dimension;
1654   prop->totarraylength = 0;
1655 
1656   if (length) {
1657     memcpy(prop->arraylength, length, sizeof(int) * dimension);
1658 
1659     prop->totarraylength = length[0];
1660     for (i = 1; i < dimension; i++) {
1661       prop->totarraylength *= length[i];
1662     }
1663   }
1664   else {
1665     memset(prop->arraylength, 0, sizeof(prop->arraylength));
1666   }
1667 
1668   /* TODO make sure arraylength values are sane  */
1669 }
1670 
RNA_def_property_ui_text(PropertyRNA * prop,const char * name,const char * description)1671 void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
1672 {
1673   DESCR_CHECK(description, prop->identifier, NULL);
1674 
1675   prop->name = name;
1676   prop->description = description;
1677 }
1678 
RNA_def_property_ui_icon(PropertyRNA * prop,int icon,int consecutive)1679 void RNA_def_property_ui_icon(PropertyRNA *prop, int icon, int consecutive)
1680 {
1681   prop->icon = icon;
1682   if (consecutive != 0) {
1683     prop->flag |= PROP_ICONS_CONSECUTIVE;
1684   }
1685   if (consecutive < 0) {
1686     prop->flag |= PROP_ICONS_REVERSE;
1687   }
1688 }
1689 
1690 /**
1691  * The values hare are a little confusing:
1692  *
1693  * \param step: Used as the value to increase/decrease when clicking on number buttons,
1694  * as well as scaling mouse input for click-dragging number buttons.
1695  * For floats this is (step * UI_PRECISION_FLOAT_SCALE), why? - nobody knows.
1696  * For ints, whole values are used.
1697  *
1698  * \param precision: The number of zeros to show
1699  * (as a whole number - common range is 1 - 6), see UI_PRECISION_FLOAT_MAX
1700  */
RNA_def_property_ui_range(PropertyRNA * prop,double min,double max,double step,int precision)1701 void RNA_def_property_ui_range(
1702     PropertyRNA *prop, double min, double max, double step, int precision)
1703 {
1704   StructRNA *srna = DefRNA.laststruct;
1705 
1706 #ifndef NDEBUG
1707   if (min > max) {
1708     CLOG_ERROR(&LOG, "\"%s.%s\", min > max.", srna->identifier, prop->identifier);
1709     DefRNA.error = true;
1710   }
1711 
1712   if (step < 0 || step > 100) {
1713     CLOG_ERROR(&LOG, "\"%s.%s\", step outside range.", srna->identifier, prop->identifier);
1714     DefRNA.error = true;
1715   }
1716 
1717   if (step == 0) {
1718     CLOG_ERROR(&LOG, "\"%s.%s\", step is zero.", srna->identifier, prop->identifier);
1719     DefRNA.error = true;
1720   }
1721 
1722   if (precision < -1 || precision > UI_PRECISION_FLOAT_MAX) {
1723     CLOG_ERROR(&LOG, "\"%s.%s\", precision outside range.", srna->identifier, prop->identifier);
1724     DefRNA.error = true;
1725   }
1726 #endif
1727 
1728   switch (prop->type) {
1729     case PROP_INT: {
1730       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1731       iprop->softmin = (int)min;
1732       iprop->softmax = (int)max;
1733       iprop->step = (int)step;
1734       break;
1735     }
1736     case PROP_FLOAT: {
1737       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
1738       fprop->softmin = (float)min;
1739       fprop->softmax = (float)max;
1740       fprop->step = (float)step;
1741       fprop->precision = (int)precision;
1742       break;
1743     }
1744     default:
1745       CLOG_ERROR(
1746           &LOG, "\"%s.%s\", invalid type for ui range.", srna->identifier, prop->identifier);
1747       DefRNA.error = true;
1748       break;
1749   }
1750 }
1751 
RNA_def_property_range(PropertyRNA * prop,double min,double max)1752 void RNA_def_property_range(PropertyRNA *prop, double min, double max)
1753 {
1754   StructRNA *srna = DefRNA.laststruct;
1755 
1756 #ifdef DEBUG
1757   if (min > max) {
1758     CLOG_ERROR(&LOG, "\"%s.%s\", min > max.", srna->identifier, prop->identifier);
1759     DefRNA.error = true;
1760   }
1761 #endif
1762 
1763   switch (prop->type) {
1764     case PROP_INT: {
1765       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1766       iprop->hardmin = (int)min;
1767       iprop->hardmax = (int)max;
1768       iprop->softmin = MAX2((int)min, iprop->hardmin);
1769       iprop->softmax = MIN2((int)max, iprop->hardmax);
1770       break;
1771     }
1772     case PROP_FLOAT: {
1773       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
1774       fprop->hardmin = (float)min;
1775       fprop->hardmax = (float)max;
1776       fprop->softmin = MAX2((float)min, fprop->hardmin);
1777       fprop->softmax = MIN2((float)max, fprop->hardmax);
1778       break;
1779     }
1780     default:
1781       CLOG_ERROR(&LOG, "\"%s.%s\", invalid type for range.", srna->identifier, prop->identifier);
1782       DefRNA.error = true;
1783       break;
1784   }
1785 }
1786 
RNA_def_property_struct_type(PropertyRNA * prop,const char * type)1787 void RNA_def_property_struct_type(PropertyRNA *prop, const char *type)
1788 {
1789   StructRNA *srna = DefRNA.laststruct;
1790 
1791   if (!DefRNA.preprocess) {
1792     fprintf(stderr, "\"%s.%s\": only during preprocessing.", srna->identifier, prop->identifier);
1793     return;
1794   }
1795 
1796   switch (prop->type) {
1797     case PROP_POINTER: {
1798       PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1799       pprop->type = (StructRNA *)type;
1800       break;
1801     }
1802     case PROP_COLLECTION: {
1803       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
1804       cprop->item_type = (StructRNA *)type;
1805       break;
1806     }
1807     default:
1808       CLOG_ERROR(
1809           &LOG, "\"%s.%s\", invalid type for struct type.", srna->identifier, prop->identifier);
1810       DefRNA.error = true;
1811       break;
1812   }
1813 }
1814 
RNA_def_property_struct_runtime(PropertyRNA * prop,StructRNA * type)1815 void RNA_def_property_struct_runtime(PropertyRNA *prop, StructRNA *type)
1816 {
1817   StructRNA *srna = DefRNA.laststruct;
1818 
1819   if (DefRNA.preprocess) {
1820     CLOG_ERROR(&LOG, "only at runtime.");
1821     return;
1822   }
1823 
1824   switch (prop->type) {
1825     case PROP_POINTER: {
1826       PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1827       pprop->type = type;
1828 
1829       if (type && (type->flag & STRUCT_ID_REFCOUNT)) {
1830         prop->flag |= PROP_ID_REFCOUNT;
1831       }
1832 
1833       break;
1834     }
1835     case PROP_COLLECTION: {
1836       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
1837       cprop->item_type = type;
1838       break;
1839     }
1840     default:
1841       CLOG_ERROR(
1842           &LOG, "\"%s.%s\", invalid type for struct type.", srna->identifier, prop->identifier);
1843       DefRNA.error = true;
1844       break;
1845   }
1846 }
1847 
RNA_def_property_enum_native_type(PropertyRNA * prop,const char * native_enum_type)1848 void RNA_def_property_enum_native_type(PropertyRNA *prop, const char *native_enum_type)
1849 {
1850   StructRNA *srna = DefRNA.laststruct;
1851   switch (prop->type) {
1852     case PROP_ENUM: {
1853       EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
1854       eprop->native_enum_type = native_enum_type;
1855       break;
1856     }
1857     default:
1858       CLOG_ERROR(
1859           &LOG, "\"%s.%s\", invalid type for struct type.", srna->identifier, prop->identifier);
1860       DefRNA.error = true;
1861       break;
1862   }
1863 }
1864 
RNA_def_property_enum_items(PropertyRNA * prop,const EnumPropertyItem * item)1865 void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item)
1866 {
1867   StructRNA *srna = DefRNA.laststruct;
1868   int i, defaultfound = 0;
1869 
1870   switch (prop->type) {
1871     case PROP_ENUM: {
1872       EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
1873       eprop->item = (EnumPropertyItem *)item;
1874       eprop->totitem = 0;
1875       for (i = 0; item[i].identifier; i++) {
1876         eprop->totitem++;
1877 
1878         if (item[i].identifier[0]) {
1879           /* Don't allow spaces in internal enum items (it's fine for Python ones). */
1880           if (DefRNA.preprocess && strstr(item[i].identifier, " ")) {
1881             CLOG_ERROR(&LOG,
1882                        "\"%s.%s\", enum identifiers must not contain spaces.",
1883                        srna->identifier,
1884                        prop->identifier);
1885             DefRNA.error = true;
1886             break;
1887           }
1888           if (item[i].value == eprop->defaultvalue) {
1889             defaultfound = 1;
1890           }
1891         }
1892       }
1893 
1894       if (!defaultfound) {
1895         for (i = 0; item[i].identifier; i++) {
1896           if (item[i].identifier[0]) {
1897             eprop->defaultvalue = item[i].value;
1898             break;
1899           }
1900         }
1901       }
1902 
1903       break;
1904     }
1905     default:
1906       CLOG_ERROR(
1907           &LOG, "\"%s.%s\", invalid type for struct type.", srna->identifier, prop->identifier);
1908       DefRNA.error = true;
1909       break;
1910   }
1911 }
1912 
RNA_def_property_string_maxlength(PropertyRNA * prop,int maxlength)1913 void RNA_def_property_string_maxlength(PropertyRNA *prop, int maxlength)
1914 {
1915   StructRNA *srna = DefRNA.laststruct;
1916 
1917   switch (prop->type) {
1918     case PROP_STRING: {
1919       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
1920       sprop->maxlength = maxlength;
1921       break;
1922     }
1923     default:
1924       CLOG_ERROR(&LOG, "\"%s.%s\", type is not string.", srna->identifier, prop->identifier);
1925       DefRNA.error = true;
1926       break;
1927   }
1928 }
1929 
RNA_def_property_boolean_default(PropertyRNA * prop,bool value)1930 void RNA_def_property_boolean_default(PropertyRNA *prop, bool value)
1931 {
1932   StructRNA *srna = DefRNA.laststruct;
1933 
1934   switch (prop->type) {
1935     case PROP_BOOLEAN: {
1936       BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1937       BLI_assert(ELEM(value, false, true));
1938 #ifndef RNA_RUNTIME
1939       /* Default may be set from items. */
1940       if (bprop->defaultvalue) {
1941         CLOG_ERROR(&LOG, "\"%s.%s\", set from DNA.", srna->identifier, prop->identifier);
1942       }
1943 #endif
1944       bprop->defaultvalue = value;
1945       break;
1946     }
1947     default:
1948       CLOG_ERROR(&LOG, "\"%s.%s\", type is not boolean.", srna->identifier, prop->identifier);
1949       DefRNA.error = true;
1950       break;
1951   }
1952 }
1953 
RNA_def_property_boolean_array_default(PropertyRNA * prop,const bool * array)1954 void RNA_def_property_boolean_array_default(PropertyRNA *prop, const bool *array)
1955 {
1956   StructRNA *srna = DefRNA.laststruct;
1957 
1958   switch (prop->type) {
1959     case PROP_BOOLEAN: {
1960       BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1961       bprop->defaultarray = array;
1962       break;
1963     }
1964     default:
1965       CLOG_ERROR(&LOG, "\"%s.%s\", type is not boolean.", srna->identifier, prop->identifier);
1966       DefRNA.error = true;
1967       break;
1968   }
1969 }
1970 
RNA_def_property_int_default(PropertyRNA * prop,int value)1971 void RNA_def_property_int_default(PropertyRNA *prop, int value)
1972 {
1973   StructRNA *srna = DefRNA.laststruct;
1974 
1975   switch (prop->type) {
1976     case PROP_INT: {
1977       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1978 #ifndef RNA_RUNTIME
1979       if (iprop->defaultvalue != 0) {
1980         CLOG_ERROR(&LOG, "\"%s.%s\", set from DNA.", srna->identifier, prop->identifier);
1981       }
1982 #endif
1983       iprop->defaultvalue = value;
1984       break;
1985     }
1986     default:
1987       CLOG_ERROR(&LOG, "\"%s.%s\", type is not int.", srna->identifier, prop->identifier);
1988       DefRNA.error = true;
1989       break;
1990   }
1991 }
1992 
RNA_def_property_int_array_default(PropertyRNA * prop,const int * array)1993 void RNA_def_property_int_array_default(PropertyRNA *prop, const int *array)
1994 {
1995   StructRNA *srna = DefRNA.laststruct;
1996 
1997   switch (prop->type) {
1998     case PROP_INT: {
1999       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2000 #ifndef RNA_RUNTIME
2001       if (iprop->defaultarray != NULL) {
2002         CLOG_ERROR(&LOG, "\"%s.%s\", set from DNA.", srna->identifier, prop->identifier);
2003       }
2004 #endif
2005       iprop->defaultarray = array;
2006       break;
2007     }
2008     default:
2009       CLOG_ERROR(&LOG, "\"%s.%s\", type is not int.", srna->identifier, prop->identifier);
2010       DefRNA.error = true;
2011       break;
2012   }
2013 }
2014 
RNA_def_property_float_default(PropertyRNA * prop,float value)2015 void RNA_def_property_float_default(PropertyRNA *prop, float value)
2016 {
2017   StructRNA *srna = DefRNA.laststruct;
2018 
2019   switch (prop->type) {
2020     case PROP_FLOAT: {
2021       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2022 #ifndef RNA_RUNTIME
2023       if (fprop->defaultvalue != 0) {
2024         CLOG_ERROR(&LOG, "\"%s.%s\", set from DNA.", srna->identifier, prop->identifier);
2025       }
2026 #endif
2027       fprop->defaultvalue = value;
2028       break;
2029     }
2030     default:
2031       CLOG_ERROR(&LOG, "\"%s.%s\", type is not float.", srna->identifier, prop->identifier);
2032       DefRNA.error = true;
2033       break;
2034   }
2035 }
2036 /* array must remain valid after this function finishes */
RNA_def_property_float_array_default(PropertyRNA * prop,const float * array)2037 void RNA_def_property_float_array_default(PropertyRNA *prop, const float *array)
2038 {
2039   StructRNA *srna = DefRNA.laststruct;
2040 
2041   switch (prop->type) {
2042     case PROP_FLOAT: {
2043       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2044 #ifndef RNA_RUNTIME
2045       if (fprop->defaultarray != NULL) {
2046         CLOG_ERROR(&LOG, "\"%s.%s\", set from DNA.", srna->identifier, prop->identifier);
2047       }
2048 #endif
2049       fprop->defaultarray = array; /* WARNING, this array must not come from the stack and lost */
2050       break;
2051     }
2052     default:
2053       CLOG_ERROR(&LOG, "\"%s.%s\", type is not float.", srna->identifier, prop->identifier);
2054       DefRNA.error = true;
2055       break;
2056   }
2057 }
2058 
RNA_def_property_string_default(PropertyRNA * prop,const char * value)2059 void RNA_def_property_string_default(PropertyRNA *prop, const char *value)
2060 {
2061   StructRNA *srna = DefRNA.laststruct;
2062 
2063   switch (prop->type) {
2064     case PROP_STRING: {
2065       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2066 
2067       if (value == NULL) {
2068         CLOG_ERROR(&LOG,
2069                    "\"%s.%s\", NULL string passed (dont call in this case).",
2070                    srna->identifier,
2071                    prop->identifier);
2072         DefRNA.error = true;
2073         break;
2074       }
2075 
2076       if (!value[0]) {
2077         CLOG_ERROR(&LOG,
2078                    "\"%s.%s\", empty string passed (dont call in this case).",
2079                    srna->identifier,
2080                    prop->identifier);
2081         DefRNA.error = true;
2082         // BLI_assert(0);
2083         break;
2084       }
2085 #ifndef RNA_RUNTIME
2086       if (sprop->defaultvalue != NULL && sprop->defaultvalue[0]) {
2087         CLOG_ERROR(&LOG, "\"%s.%s\", set from DNA.", srna->identifier, prop->identifier);
2088       }
2089 #endif
2090       sprop->defaultvalue = value;
2091       break;
2092     }
2093     default:
2094       CLOG_ERROR(&LOG, "\"%s.%s\", type is not string.", srna->identifier, prop->identifier);
2095       DefRNA.error = true;
2096       break;
2097   }
2098 }
2099 
RNA_def_property_enum_default(PropertyRNA * prop,int value)2100 void RNA_def_property_enum_default(PropertyRNA *prop, int value)
2101 {
2102   StructRNA *srna = DefRNA.laststruct;
2103   int i, defaultfound = 0;
2104 
2105   switch (prop->type) {
2106     case PROP_ENUM: {
2107       EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2108       eprop->defaultvalue = value;
2109 
2110       if (prop->flag & PROP_ENUM_FLAG) {
2111         /* check all bits are accounted for */
2112         int totflag = 0;
2113         for (i = 0; i < eprop->totitem; i++) {
2114           if (eprop->item[i].identifier[0]) {
2115             totflag |= eprop->item[i].value;
2116           }
2117         }
2118 
2119         if (eprop->defaultvalue & ~totflag) {
2120           CLOG_ERROR(&LOG,
2121                      "\"%s.%s\", default includes unused bits (%d).",
2122                      srna->identifier,
2123                      prop->identifier,
2124                      eprop->defaultvalue & ~totflag);
2125           DefRNA.error = true;
2126         }
2127       }
2128       else {
2129         for (i = 0; i < eprop->totitem; i++) {
2130           if (eprop->item[i].identifier[0] && eprop->item[i].value == eprop->defaultvalue) {
2131             defaultfound = 1;
2132           }
2133         }
2134 
2135         if (!defaultfound && eprop->totitem) {
2136           if (value == 0) {
2137             eprop->defaultvalue = eprop->item[0].value;
2138           }
2139           else {
2140             CLOG_ERROR(
2141                 &LOG, "\"%s.%s\", default is not in items.", srna->identifier, prop->identifier);
2142             DefRNA.error = true;
2143           }
2144         }
2145       }
2146 
2147       break;
2148     }
2149     default:
2150       CLOG_ERROR(&LOG, "\"%s.%s\", type is not enum.", srna->identifier, prop->identifier);
2151       DefRNA.error = true;
2152       break;
2153   }
2154 }
2155 
2156 /* SDNA */
2157 
rna_def_property_sdna(PropertyRNA * prop,const char * structname,const char * propname)2158 static PropertyDefRNA *rna_def_property_sdna(PropertyRNA *prop,
2159                                              const char *structname,
2160                                              const char *propname)
2161 {
2162   DNAStructMember smember;
2163   StructDefRNA *ds;
2164   PropertyDefRNA *dp;
2165 
2166   dp = rna_find_struct_property_def(DefRNA.laststruct, prop);
2167   if (dp == NULL) {
2168     return NULL;
2169   }
2170 
2171   ds = rna_find_struct_def((StructRNA *)dp->cont);
2172 
2173   if (!structname) {
2174     structname = ds->dnaname;
2175   }
2176   if (!propname) {
2177     propname = prop->identifier;
2178   }
2179 
2180   int dnaoffset = 0;
2181   if (!rna_find_sdna_member(DefRNA.sdna, structname, propname, &smember, &dnaoffset)) {
2182     if (DefRNA.silent) {
2183       return NULL;
2184     }
2185     if (!DefRNA.verify) {
2186       /* some basic values to survive even with sdna info */
2187       dp->dnastructname = structname;
2188       dp->dnaname = propname;
2189       if (prop->type == PROP_BOOLEAN) {
2190         dp->dnaarraylength = 1;
2191       }
2192       if (prop->type == PROP_POINTER) {
2193         dp->dnapointerlevel = 1;
2194       }
2195       dp->dnaoffset = smember.offset;
2196       return dp;
2197     }
2198     else {
2199       CLOG_ERROR(&LOG,
2200                  "\"%s.%s\" (identifier \"%s\") not found. Struct must be in DNA.",
2201                  structname,
2202                  propname,
2203                  prop->identifier);
2204       DefRNA.error = true;
2205       return NULL;
2206     }
2207   }
2208 
2209   if (smember.arraylength > 1) {
2210     prop->arraylength[0] = smember.arraylength;
2211     prop->totarraylength = smember.arraylength;
2212     prop->arraydimension = 1;
2213   }
2214   else {
2215     prop->arraydimension = 0;
2216     prop->totarraylength = 0;
2217   }
2218 
2219   dp->dnastructname = structname;
2220   dp->dnastructfromname = ds->dnafromname;
2221   dp->dnastructfromprop = ds->dnafromprop;
2222   dp->dnaname = propname;
2223   dp->dnatype = smember.type;
2224   dp->dnaarraylength = smember.arraylength;
2225   dp->dnapointerlevel = smember.pointerlevel;
2226   dp->dnaoffset = smember.offset;
2227   dp->dnasize = smember.size;
2228 
2229   return dp;
2230 }
2231 
RNA_def_property_boolean_sdna(PropertyRNA * prop,const char * structname,const char * propname,int64_t bit)2232 void RNA_def_property_boolean_sdna(PropertyRNA *prop,
2233                                    const char *structname,
2234                                    const char *propname,
2235                                    int64_t bit)
2236 {
2237   PropertyDefRNA *dp;
2238   BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2239   StructRNA *srna = DefRNA.laststruct;
2240 
2241   if (!DefRNA.preprocess) {
2242     CLOG_ERROR(&LOG, "only during preprocessing.");
2243     return;
2244   }
2245 
2246   if (prop->type != PROP_BOOLEAN) {
2247     CLOG_ERROR(&LOG, "\"%s.%s\", type is not boolean.", srna->identifier, prop->identifier);
2248     DefRNA.error = true;
2249     return;
2250   }
2251 
2252   if ((dp = rna_def_property_sdna(prop, structname, propname))) {
2253 
2254     if (!DefRNA.silent) {
2255       /* error check to ensure floats are not wrapped as ints/bools */
2256       if (dp->dnatype && *dp->dnatype && IS_DNATYPE_BOOLEAN_COMPAT(dp->dnatype) == 0) {
2257         CLOG_ERROR(&LOG,
2258                    "%s.%s is a '%s' but wrapped as type '%s'.",
2259                    srna->identifier,
2260                    prop->identifier,
2261                    dp->dnatype,
2262                    RNA_property_typename(prop->type));
2263         DefRNA.error = true;
2264         return;
2265       }
2266     }
2267 
2268     dp->booleanbit = bit;
2269 
2270 #ifndef RNA_RUNTIME
2271     /* Set the default if possible. */
2272     if (dp->dnaoffset != -1) {
2273       int SDNAnr = DNA_struct_find_nr_wrapper(DefRNA.sdna, dp->dnastructname);
2274       if (SDNAnr != -1) {
2275         const void *default_data = DNA_default_table[SDNAnr];
2276         if (default_data) {
2277           default_data = POINTER_OFFSET(default_data, dp->dnaoffset);
2278           bool has_default = true;
2279           if (prop->totarraylength > 0) {
2280             has_default = false;
2281             if (debugSRNA_defaults) {
2282               fprintf(stderr, "%s default: unsupported boolean array default\n", __func__);
2283             }
2284           }
2285           else {
2286             if (STREQ(dp->dnatype, "char")) {
2287               bprop->defaultvalue = *(const char *)default_data & bit;
2288             }
2289             else if (STREQ(dp->dnatype, "short")) {
2290               bprop->defaultvalue = *(const short *)default_data & bit;
2291             }
2292             else if (STREQ(dp->dnatype, "int")) {
2293               bprop->defaultvalue = *(const int *)default_data & bit;
2294             }
2295             else {
2296               has_default = false;
2297               if (debugSRNA_defaults) {
2298                 fprintf(
2299                     stderr, "%s default: unsupported boolean type (%s)\n", __func__, dp->dnatype);
2300               }
2301             }
2302 
2303             if (has_default) {
2304               if (dp->booleannegative) {
2305                 bprop->defaultvalue = !bprop->defaultvalue;
2306               }
2307 
2308               if (debugSRNA_defaults) {
2309                 fprintf(stderr, "value=%d, ", bprop->defaultvalue);
2310                 print_defult_info(dp);
2311               }
2312             }
2313           }
2314         }
2315       }
2316     }
2317 #else
2318     UNUSED_VARS(bprop);
2319 #endif
2320   }
2321 }
2322 
RNA_def_property_boolean_negative_sdna(PropertyRNA * prop,const char * structname,const char * propname,int64_t booleanbit)2323 void RNA_def_property_boolean_negative_sdna(PropertyRNA *prop,
2324                                             const char *structname,
2325                                             const char *propname,
2326                                             int64_t booleanbit)
2327 {
2328   PropertyDefRNA *dp;
2329 
2330   RNA_def_property_boolean_sdna(prop, structname, propname, booleanbit);
2331 
2332   dp = rna_find_struct_property_def(DefRNA.laststruct, prop);
2333 
2334   if (dp) {
2335     dp->booleannegative = true;
2336   }
2337 }
2338 
RNA_def_property_int_sdna(PropertyRNA * prop,const char * structname,const char * propname)2339 void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const char *propname)
2340 {
2341   PropertyDefRNA *dp;
2342   IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2343   StructRNA *srna = DefRNA.laststruct;
2344 
2345   if (!DefRNA.preprocess) {
2346     CLOG_ERROR(&LOG, "only during preprocessing.");
2347     return;
2348   }
2349 
2350   if (prop->type != PROP_INT) {
2351     CLOG_ERROR(&LOG, "\"%s.%s\", type is not int.", srna->identifier, prop->identifier);
2352     DefRNA.error = true;
2353     return;
2354   }
2355 
2356   if ((dp = rna_def_property_sdna(prop, structname, propname))) {
2357 
2358     /* error check to ensure floats are not wrapped as ints/bools */
2359     if (!DefRNA.silent) {
2360       if (dp->dnatype && *dp->dnatype && IS_DNATYPE_INT_COMPAT(dp->dnatype) == 0) {
2361         CLOG_ERROR(&LOG,
2362                    "%s.%s is a '%s' but wrapped as type '%s'.",
2363                    srna->identifier,
2364                    prop->identifier,
2365                    dp->dnatype,
2366                    RNA_property_typename(prop->type));
2367         DefRNA.error = true;
2368         return;
2369       }
2370     }
2371 
2372     /* SDNA doesn't pass us unsigned unfortunately .. */
2373     if (dp->dnatype && STREQ(dp->dnatype, "char")) {
2374       iprop->hardmin = iprop->softmin = CHAR_MIN;
2375       iprop->hardmax = iprop->softmax = CHAR_MAX;
2376     }
2377     else if (dp->dnatype && STREQ(dp->dnatype, "short")) {
2378       iprop->hardmin = iprop->softmin = SHRT_MIN;
2379       iprop->hardmax = iprop->softmax = SHRT_MAX;
2380     }
2381     else if (dp->dnatype && STREQ(dp->dnatype, "int")) {
2382       iprop->hardmin = INT_MIN;
2383       iprop->hardmax = INT_MAX;
2384 
2385       iprop->softmin = -10000; /* rather arbitrary .. */
2386       iprop->softmax = 10000;
2387     }
2388 
2389     if (prop->subtype == PROP_UNSIGNED || prop->subtype == PROP_PERCENTAGE ||
2390         prop->subtype == PROP_FACTOR) {
2391       iprop->hardmin = iprop->softmin = 0;
2392     }
2393 
2394 #ifndef RNA_RUNTIME
2395     /* Set the default if possible. */
2396     if (dp->dnaoffset != -1) {
2397       int SDNAnr = DNA_struct_find_nr_wrapper(DefRNA.sdna, dp->dnastructname);
2398       if (SDNAnr != -1) {
2399         const void *default_data = DNA_default_table[SDNAnr];
2400         if (default_data) {
2401           default_data = POINTER_OFFSET(default_data, dp->dnaoffset);
2402           /* NOTE: Currently doesn't store sign, assume chars are unsigned because
2403            * we build with this enabled, otherwise check 'PROP_UNSIGNED'. */
2404           bool has_default = true;
2405           if (prop->totarraylength > 0) {
2406             const void *default_data_end = POINTER_OFFSET(default_data, dp->dnasize);
2407             const int size_final = sizeof(int) * prop->totarraylength;
2408             if (STREQ(dp->dnatype, "char")) {
2409               int *defaultarray = rna_calloc(size_final);
2410               for (int i = 0; i < prop->totarraylength && default_data < default_data_end; i++) {
2411                 defaultarray[i] = *(const char *)default_data;
2412                 default_data = POINTER_OFFSET(default_data, sizeof(char));
2413               }
2414               iprop->defaultarray = defaultarray;
2415             }
2416             else if (STREQ(dp->dnatype, "short")) {
2417 
2418               int *defaultarray = rna_calloc(size_final);
2419               for (int i = 0; i < prop->totarraylength && default_data < default_data_end; i++) {
2420                 defaultarray[i] = (prop->subtype != PROP_UNSIGNED) ? *(const short *)default_data :
2421                                                                      *(const ushort *)default_data;
2422                 default_data = POINTER_OFFSET(default_data, sizeof(short));
2423               }
2424               iprop->defaultarray = defaultarray;
2425             }
2426             else if (STREQ(dp->dnatype, "int")) {
2427               int *defaultarray = rna_calloc(size_final);
2428               memcpy(defaultarray, default_data, MIN2(size_final, dp->dnasize));
2429               iprop->defaultarray = defaultarray;
2430             }
2431             else {
2432               has_default = false;
2433               if (debugSRNA_defaults) {
2434                 fprintf(stderr,
2435                         "%s default: unsupported int array type (%s)\n",
2436                         __func__,
2437                         dp->dnatype);
2438               }
2439             }
2440 
2441             if (has_default) {
2442               if (debugSRNA_defaults) {
2443                 fprintf(stderr, "value=(");
2444                 for (int i = 0; i < prop->totarraylength; i++) {
2445                   fprintf(stderr, "%d, ", iprop->defaultarray[i]);
2446                 }
2447                 fprintf(stderr, "), ");
2448                 print_defult_info(dp);
2449               }
2450             }
2451           }
2452           else {
2453             if (STREQ(dp->dnatype, "char")) {
2454               iprop->defaultvalue = *(const char *)default_data;
2455             }
2456             else if (STREQ(dp->dnatype, "short")) {
2457               iprop->defaultvalue = (prop->subtype != PROP_UNSIGNED) ?
2458                                         *(const short *)default_data :
2459                                         *(const ushort *)default_data;
2460             }
2461             else if (STREQ(dp->dnatype, "int")) {
2462               iprop->defaultvalue = (prop->subtype != PROP_UNSIGNED) ? *(const int *)default_data :
2463                                                                        *(const uint *)default_data;
2464             }
2465             else {
2466               has_default = false;
2467               if (debugSRNA_defaults) {
2468                 fprintf(stderr, "%s default: unsupported int type (%s)\n", __func__, dp->dnatype);
2469               }
2470             }
2471 
2472             if (has_default) {
2473               if (debugSRNA_defaults) {
2474                 fprintf(stderr, "value=%d, ", iprop->defaultvalue);
2475                 print_defult_info(dp);
2476               }
2477             }
2478           }
2479         }
2480       }
2481     }
2482 #endif
2483   }
2484 }
2485 
RNA_def_property_float_sdna(PropertyRNA * prop,const char * structname,const char * propname)2486 void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, const char *propname)
2487 {
2488   PropertyDefRNA *dp;
2489   FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2490   StructRNA *srna = DefRNA.laststruct;
2491 
2492   if (!DefRNA.preprocess) {
2493     CLOG_ERROR(&LOG, "only during preprocessing.");
2494     return;
2495   }
2496 
2497   if (prop->type != PROP_FLOAT) {
2498     CLOG_ERROR(&LOG, "\"%s.%s\", type is not float.", srna->identifier, prop->identifier);
2499     DefRNA.error = true;
2500     return;
2501   }
2502 
2503   if ((dp = rna_def_property_sdna(prop, structname, propname))) {
2504     /* silent is for internal use */
2505     if (!DefRNA.silent) {
2506       if (dp->dnatype && *dp->dnatype && IS_DNATYPE_FLOAT_COMPAT(dp->dnatype) == 0) {
2507         /* Colors are an exception. these get translated. */
2508         if (prop->subtype != PROP_COLOR_GAMMA) {
2509           CLOG_ERROR(&LOG,
2510                      "%s.%s is a '%s' but wrapped as type '%s'.",
2511                      srna->identifier,
2512                      prop->identifier,
2513                      dp->dnatype,
2514                      RNA_property_typename(prop->type));
2515           DefRNA.error = true;
2516           return;
2517         }
2518       }
2519     }
2520 
2521     if (dp->dnatype && STREQ(dp->dnatype, "char")) {
2522       fprop->hardmin = fprop->softmin = 0.0f;
2523       fprop->hardmax = fprop->softmax = 1.0f;
2524     }
2525 
2526 #ifndef RNA_RUNTIME
2527     /* Set the default if possible. */
2528     if (dp->dnaoffset != -1) {
2529       int SDNAnr = DNA_struct_find_nr_wrapper(DefRNA.sdna, dp->dnastructname);
2530       if (SDNAnr != -1) {
2531         const void *default_data = DNA_default_table[SDNAnr];
2532         if (default_data) {
2533           default_data = POINTER_OFFSET(default_data, dp->dnaoffset);
2534           bool has_default = true;
2535           if (prop->totarraylength > 0) {
2536             if (STREQ(dp->dnatype, "float")) {
2537               const int size_final = sizeof(float) * prop->totarraylength;
2538               float *defaultarray = rna_calloc(size_final);
2539               memcpy(defaultarray, default_data, MIN2(size_final, dp->dnasize));
2540               fprop->defaultarray = defaultarray;
2541             }
2542             else {
2543               has_default = false;
2544               if (debugSRNA_defaults) {
2545                 fprintf(stderr,
2546                         "%s default: unsupported float array type (%s)\n",
2547                         __func__,
2548                         dp->dnatype);
2549               }
2550             }
2551 
2552             if (has_default) {
2553               if (debugSRNA_defaults) {
2554                 fprintf(stderr, "value=(");
2555                 for (int i = 0; i < prop->totarraylength; i++) {
2556                   fprintf(stderr, "%g, ", fprop->defaultarray[i]);
2557                 }
2558                 fprintf(stderr, "), ");
2559                 print_defult_info(dp);
2560               }
2561             }
2562           }
2563           else {
2564             if (STREQ(dp->dnatype, "float")) {
2565               fprop->defaultvalue = *(const float *)default_data;
2566             }
2567             else if (STREQ(dp->dnatype, "char")) {
2568               fprop->defaultvalue = (float)*(const char *)default_data * (1.0f / 255.0f);
2569             }
2570             else {
2571               has_default = false;
2572               if (debugSRNA_defaults) {
2573                 fprintf(
2574                     stderr, "%s default: unsupported float type (%s)\n", __func__, dp->dnatype);
2575               }
2576             }
2577 
2578             if (has_default) {
2579               if (debugSRNA_defaults) {
2580                 fprintf(stderr, "value=%g, ", fprop->defaultvalue);
2581                 print_defult_info(dp);
2582               }
2583             }
2584           }
2585         }
2586       }
2587     }
2588 #endif
2589   }
2590 
2591   rna_def_property_sdna(prop, structname, propname);
2592 }
2593 
RNA_def_property_enum_sdna(PropertyRNA * prop,const char * structname,const char * propname)2594 void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const char *propname)
2595 {
2596   PropertyDefRNA *dp;
2597   EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2598   StructRNA *srna = DefRNA.laststruct;
2599 
2600   if (!DefRNA.preprocess) {
2601     CLOG_ERROR(&LOG, "only during preprocessing.");
2602     return;
2603   }
2604 
2605   if (prop->type != PROP_ENUM) {
2606     CLOG_ERROR(&LOG, "\"%s.%s\", type is not enum.", srna->identifier, prop->identifier);
2607     DefRNA.error = true;
2608     return;
2609   }
2610 
2611   if ((dp = rna_def_property_sdna(prop, structname, propname))) {
2612     if (prop->arraydimension) {
2613       prop->arraydimension = 0;
2614       prop->totarraylength = 0;
2615 
2616       if (!DefRNA.silent) {
2617         CLOG_ERROR(&LOG, "\"%s.%s\", array not supported for enum type.", structname, propname);
2618         DefRNA.error = true;
2619       }
2620     }
2621 
2622 #ifndef RNA_RUNTIME
2623     /* Set the default if possible. */
2624     if (dp->dnaoffset != -1) {
2625       int SDNAnr = DNA_struct_find_nr_wrapper(DefRNA.sdna, dp->dnastructname);
2626       if (SDNAnr != -1) {
2627         const void *default_data = DNA_default_table[SDNAnr];
2628         if (default_data) {
2629           default_data = POINTER_OFFSET(default_data, dp->dnaoffset);
2630           bool has_default = true;
2631           if (STREQ(dp->dnatype, "char")) {
2632             eprop->defaultvalue = *(const char *)default_data;
2633           }
2634           else if (STREQ(dp->dnatype, "short")) {
2635             eprop->defaultvalue = *(const short *)default_data;
2636           }
2637           else if (STREQ(dp->dnatype, "int")) {
2638             eprop->defaultvalue = *(const int *)default_data;
2639           }
2640           else {
2641             has_default = false;
2642             if (debugSRNA_defaults) {
2643               fprintf(stderr, "%s default: unsupported enum type (%s)\n", __func__, dp->dnatype);
2644             }
2645           }
2646 
2647           if (has_default) {
2648             if (debugSRNA_defaults) {
2649               fprintf(stderr, "value=%d, ", eprop->defaultvalue);
2650               print_defult_info(dp);
2651             }
2652           }
2653         }
2654       }
2655     }
2656 #else
2657     UNUSED_VARS(eprop);
2658 #endif
2659   }
2660 }
2661 
RNA_def_property_enum_bitflag_sdna(PropertyRNA * prop,const char * structname,const char * propname)2662 void RNA_def_property_enum_bitflag_sdna(PropertyRNA *prop,
2663                                         const char *structname,
2664                                         const char *propname)
2665 {
2666   PropertyDefRNA *dp;
2667 
2668   RNA_def_property_enum_sdna(prop, structname, propname);
2669 
2670   dp = rna_find_struct_property_def(DefRNA.laststruct, prop);
2671 
2672   if (dp) {
2673     dp->enumbitflags = 1;
2674 
2675 #ifndef RNA_RUNTIME
2676     int defaultvalue_mask = 0;
2677     EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2678     for (int i = 0; i < eprop->totitem; i++) {
2679       if (eprop->item[i].identifier[0]) {
2680         defaultvalue_mask |= eprop->defaultvalue & eprop->item[i].value;
2681       }
2682     }
2683     eprop->defaultvalue = defaultvalue_mask;
2684 #endif
2685   }
2686 }
2687 
RNA_def_property_string_sdna(PropertyRNA * prop,const char * structname,const char * propname)2688 void RNA_def_property_string_sdna(PropertyRNA *prop, const char *structname, const char *propname)
2689 {
2690   PropertyDefRNA *dp;
2691   StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2692   StructRNA *srna = DefRNA.laststruct;
2693 
2694   if (!DefRNA.preprocess) {
2695     CLOG_ERROR(&LOG, "only during preprocessing.");
2696     return;
2697   }
2698 
2699   if (prop->type != PROP_STRING) {
2700     CLOG_ERROR(&LOG, "\"%s.%s\", type is not string.", srna->identifier, prop->identifier);
2701     DefRNA.error = true;
2702     return;
2703   }
2704 
2705   if ((dp = rna_def_property_sdna(prop, structname, propname))) {
2706     if (prop->arraydimension) {
2707       sprop->maxlength = prop->totarraylength;
2708       prop->arraydimension = 0;
2709       prop->totarraylength = 0;
2710     }
2711 
2712 #ifndef RNA_RUNTIME
2713     /* Set the default if possible. */
2714     if ((dp->dnaoffset != -1) && (dp->dnapointerlevel != 0)) {
2715       int SDNAnr = DNA_struct_find_nr_wrapper(DefRNA.sdna, dp->dnastructname);
2716       if (SDNAnr != -1) {
2717         const void *default_data = DNA_default_table[SDNAnr];
2718         if (default_data) {
2719           default_data = POINTER_OFFSET(default_data, dp->dnaoffset);
2720           sprop->defaultvalue = default_data;
2721 
2722           if (debugSRNA_defaults) {
2723             fprintf(stderr, "value=\"%s\", ", sprop->defaultvalue);
2724             print_defult_info(dp);
2725           }
2726         }
2727       }
2728     }
2729 #endif
2730   }
2731 }
2732 
RNA_def_property_pointer_sdna(PropertyRNA * prop,const char * structname,const char * propname)2733 void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, const char *propname)
2734 {
2735   /* PropertyDefRNA *dp; */
2736   StructRNA *srna = DefRNA.laststruct;
2737 
2738   if (!DefRNA.preprocess) {
2739     CLOG_ERROR(&LOG, "only during preprocessing.");
2740     return;
2741   }
2742 
2743   if (prop->type != PROP_POINTER) {
2744     CLOG_ERROR(&LOG, "\"%s.%s\", type is not pointer.", srna->identifier, prop->identifier);
2745     DefRNA.error = true;
2746     return;
2747   }
2748 
2749   if ((/* dp= */ rna_def_property_sdna(prop, structname, propname))) {
2750     if (prop->arraydimension) {
2751       prop->arraydimension = 0;
2752       prop->totarraylength = 0;
2753 
2754       if (!DefRNA.silent) {
2755         CLOG_ERROR(&LOG, "\"%s.%s\", array not supported for pointer type.", structname, propname);
2756         DefRNA.error = true;
2757       }
2758     }
2759   }
2760 }
2761 
RNA_def_property_collection_sdna(PropertyRNA * prop,const char * structname,const char * propname,const char * lengthpropname)2762 void RNA_def_property_collection_sdna(PropertyRNA *prop,
2763                                       const char *structname,
2764                                       const char *propname,
2765                                       const char *lengthpropname)
2766 {
2767   PropertyDefRNA *dp;
2768   CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
2769   StructRNA *srna = DefRNA.laststruct;
2770 
2771   if (!DefRNA.preprocess) {
2772     CLOG_ERROR(&LOG, "only during preprocessing.");
2773     return;
2774   }
2775 
2776   if (prop->type != PROP_COLLECTION) {
2777     CLOG_ERROR(&LOG, "\"%s.%s\", type is not collection.", srna->identifier, prop->identifier);
2778     DefRNA.error = true;
2779     return;
2780   }
2781 
2782   if ((dp = rna_def_property_sdna(prop, structname, propname))) {
2783     if (prop->arraydimension && !lengthpropname) {
2784       prop->arraydimension = 0;
2785       prop->totarraylength = 0;
2786 
2787       if (!DefRNA.silent) {
2788         CLOG_ERROR(&LOG, "\"%s.%s\", array of collections not supported.", structname, propname);
2789         DefRNA.error = true;
2790       }
2791     }
2792 
2793     if (dp->dnatype && STREQ(dp->dnatype, "ListBase")) {
2794       cprop->next = (PropCollectionNextFunc) "rna_iterator_listbase_next";
2795       cprop->get = (PropCollectionGetFunc) "rna_iterator_listbase_get";
2796       cprop->end = (PropCollectionEndFunc) "rna_iterator_listbase_end";
2797     }
2798   }
2799 
2800   if (dp && lengthpropname) {
2801     DNAStructMember smember;
2802     StructDefRNA *ds = rna_find_struct_def((StructRNA *)dp->cont);
2803 
2804     if (!structname) {
2805       structname = ds->dnaname;
2806     }
2807 
2808     int dnaoffset = 0;
2809     if (lengthpropname[0] == 0 ||
2810         rna_find_sdna_member(DefRNA.sdna, structname, lengthpropname, &smember, &dnaoffset)) {
2811       if (lengthpropname[0] == 0) {
2812         dp->dnalengthfixed = prop->totarraylength;
2813         prop->arraydimension = 0;
2814         prop->totarraylength = 0;
2815       }
2816       else {
2817         dp->dnalengthstructname = structname;
2818         dp->dnalengthname = lengthpropname;
2819         prop->totarraylength = 0;
2820       }
2821 
2822       cprop->next = (PropCollectionNextFunc) "rna_iterator_array_next";
2823       cprop->end = (PropCollectionEndFunc) "rna_iterator_array_end";
2824 
2825       if (dp->dnapointerlevel >= 2) {
2826         cprop->get = (PropCollectionGetFunc) "rna_iterator_array_dereference_get";
2827       }
2828       else {
2829         cprop->get = (PropCollectionGetFunc) "rna_iterator_array_get";
2830       }
2831     }
2832     else {
2833       if (!DefRNA.silent) {
2834         CLOG_ERROR(&LOG, "\"%s.%s\" not found.", structname, lengthpropname);
2835         DefRNA.error = true;
2836       }
2837     }
2838   }
2839 }
2840 
RNA_def_property_translation_context(PropertyRNA * prop,const char * context)2841 void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
2842 {
2843   prop->translation_context = context ? context : BLT_I18NCONTEXT_DEFAULT_BPYRNA;
2844 }
2845 
2846 /* Functions */
2847 
RNA_def_property_editable_func(PropertyRNA * prop,const char * editable)2848 void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable)
2849 {
2850   if (!DefRNA.preprocess) {
2851     CLOG_ERROR(&LOG, "only during preprocessing.");
2852     return;
2853   }
2854 
2855   if (editable) {
2856     prop->editable = (EditableFunc)editable;
2857   }
2858 }
2859 
RNA_def_property_editable_array_func(PropertyRNA * prop,const char * editable)2860 void RNA_def_property_editable_array_func(PropertyRNA *prop, const char *editable)
2861 {
2862   if (!DefRNA.preprocess) {
2863     CLOG_ERROR(&LOG, "only during preprocessing.");
2864     return;
2865   }
2866 
2867   if (editable) {
2868     prop->itemeditable = (ItemEditableFunc)editable;
2869   }
2870 }
2871 
2872 /**
2873  * Set custom callbacks for override operations handling.
2874  *
2875  * \note \a diff callback will also be used by RNA comparison/equality functions.
2876  */
RNA_def_property_override_funcs(PropertyRNA * prop,const char * diff,const char * store,const char * apply)2877 void RNA_def_property_override_funcs(PropertyRNA *prop,
2878                                      const char *diff,
2879                                      const char *store,
2880                                      const char *apply)
2881 {
2882   if (!DefRNA.preprocess) {
2883     CLOG_ERROR(&LOG, "only during preprocessing.");
2884     return;
2885   }
2886 
2887   if (diff) {
2888     prop->override_diff = (RNAPropOverrideDiff)diff;
2889   }
2890   if (store) {
2891     prop->override_store = (RNAPropOverrideStore)store;
2892   }
2893   if (apply) {
2894     prop->override_apply = (RNAPropOverrideApply)apply;
2895   }
2896 }
2897 
RNA_def_property_update(PropertyRNA * prop,int noteflag,const char * func)2898 void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *func)
2899 {
2900   if (!DefRNA.preprocess) {
2901     CLOG_ERROR(&LOG, "only during preprocessing.");
2902     return;
2903   }
2904 
2905   prop->noteflag = noteflag;
2906   prop->update = (UpdateFunc)func;
2907 }
2908 
RNA_def_property_update_runtime(PropertyRNA * prop,const void * func)2909 void RNA_def_property_update_runtime(PropertyRNA *prop, const void *func)
2910 {
2911   prop->update = (void *)func;
2912 }
2913 
RNA_def_property_poll_runtime(PropertyRNA * prop,const void * func)2914 void RNA_def_property_poll_runtime(PropertyRNA *prop, const void *func)
2915 {
2916   if (prop->type == PROP_POINTER) {
2917     ((PointerPropertyRNA *)prop)->poll = (void *)func;
2918   }
2919   else {
2920     CLOG_ERROR(&LOG, "%s is not a Pointer Property.", prop->identifier);
2921   }
2922 }
2923 
RNA_def_property_dynamic_array_funcs(PropertyRNA * prop,const char * getlength)2924 void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength)
2925 {
2926   if (!DefRNA.preprocess) {
2927     CLOG_ERROR(&LOG, "only during preprocessing.");
2928     return;
2929   }
2930 
2931   if (!(prop->flag & PROP_DYNAMIC)) {
2932     CLOG_ERROR(&LOG, "property is a not dynamic array.");
2933     DefRNA.error = true;
2934     return;
2935   }
2936 
2937   if (getlength) {
2938     prop->getlength = (PropArrayLengthGetFunc)getlength;
2939   }
2940 }
2941 
RNA_def_property_boolean_funcs(PropertyRNA * prop,const char * get,const char * set)2942 void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set)
2943 {
2944   StructRNA *srna = DefRNA.laststruct;
2945 
2946   if (!DefRNA.preprocess) {
2947     CLOG_ERROR(&LOG, "only during preprocessing.");
2948     return;
2949   }
2950 
2951   switch (prop->type) {
2952     case PROP_BOOLEAN: {
2953       BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2954 
2955       if (prop->arraydimension) {
2956         if (get) {
2957           bprop->getarray = (PropBooleanArrayGetFunc)get;
2958         }
2959         if (set) {
2960           bprop->setarray = (PropBooleanArraySetFunc)set;
2961         }
2962       }
2963       else {
2964         if (get) {
2965           bprop->get = (PropBooleanGetFunc)get;
2966         }
2967         if (set) {
2968           bprop->set = (PropBooleanSetFunc)set;
2969         }
2970       }
2971       break;
2972     }
2973     default:
2974       CLOG_ERROR(&LOG, "\"%s.%s\", type is not boolean.", srna->identifier, prop->identifier);
2975       DefRNA.error = true;
2976       break;
2977   }
2978 }
2979 
RNA_def_property_boolean_funcs_runtime(PropertyRNA * prop,BooleanPropertyGetFunc getfunc,BooleanPropertySetFunc setfunc)2980 void RNA_def_property_boolean_funcs_runtime(PropertyRNA *prop,
2981                                             BooleanPropertyGetFunc getfunc,
2982                                             BooleanPropertySetFunc setfunc)
2983 {
2984   BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2985 
2986   if (getfunc) {
2987     bprop->get_ex = getfunc;
2988   }
2989   if (setfunc) {
2990     bprop->set_ex = setfunc;
2991   }
2992 
2993   if (getfunc || setfunc) {
2994     /* don't save in id properties */
2995     prop->flag &= ~PROP_IDPROPERTY;
2996 
2997     if (!setfunc) {
2998       prop->flag &= ~PROP_EDITABLE;
2999     }
3000   }
3001 }
3002 
RNA_def_property_boolean_array_funcs_runtime(PropertyRNA * prop,BooleanArrayPropertyGetFunc getfunc,BooleanArrayPropertySetFunc setfunc)3003 void RNA_def_property_boolean_array_funcs_runtime(PropertyRNA *prop,
3004                                                   BooleanArrayPropertyGetFunc getfunc,
3005                                                   BooleanArrayPropertySetFunc setfunc)
3006 {
3007   BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
3008 
3009   if (getfunc) {
3010     bprop->getarray_ex = getfunc;
3011   }
3012   if (setfunc) {
3013     bprop->setarray_ex = setfunc;
3014   }
3015 
3016   if (getfunc || setfunc) {
3017     /* don't save in id properties */
3018     prop->flag &= ~PROP_IDPROPERTY;
3019 
3020     if (!setfunc) {
3021       prop->flag &= ~PROP_EDITABLE;
3022     }
3023   }
3024 }
3025 
RNA_def_property_int_funcs(PropertyRNA * prop,const char * get,const char * set,const char * range)3026 void RNA_def_property_int_funcs(PropertyRNA *prop,
3027                                 const char *get,
3028                                 const char *set,
3029                                 const char *range)
3030 {
3031   StructRNA *srna = DefRNA.laststruct;
3032 
3033   if (!DefRNA.preprocess) {
3034     CLOG_ERROR(&LOG, "only during preprocessing.");
3035     return;
3036   }
3037 
3038   switch (prop->type) {
3039     case PROP_INT: {
3040       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
3041 
3042       if (prop->arraydimension) {
3043         if (get) {
3044           iprop->getarray = (PropIntArrayGetFunc)get;
3045         }
3046         if (set) {
3047           iprop->setarray = (PropIntArraySetFunc)set;
3048         }
3049       }
3050       else {
3051         if (get) {
3052           iprop->get = (PropIntGetFunc)get;
3053         }
3054         if (set) {
3055           iprop->set = (PropIntSetFunc)set;
3056         }
3057       }
3058       if (range) {
3059         iprop->range = (PropIntRangeFunc)range;
3060       }
3061       break;
3062     }
3063     default:
3064       CLOG_ERROR(&LOG, "\"%s.%s\", type is not int.", srna->identifier, prop->identifier);
3065       DefRNA.error = true;
3066       break;
3067   }
3068 }
3069 
RNA_def_property_int_funcs_runtime(PropertyRNA * prop,IntPropertyGetFunc getfunc,IntPropertySetFunc setfunc,IntPropertyRangeFunc rangefunc)3070 void RNA_def_property_int_funcs_runtime(PropertyRNA *prop,
3071                                         IntPropertyGetFunc getfunc,
3072                                         IntPropertySetFunc setfunc,
3073                                         IntPropertyRangeFunc rangefunc)
3074 {
3075   IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
3076 
3077   if (getfunc) {
3078     iprop->get_ex = getfunc;
3079   }
3080   if (setfunc) {
3081     iprop->set_ex = setfunc;
3082   }
3083   if (rangefunc) {
3084     iprop->range_ex = rangefunc;
3085   }
3086 
3087   if (getfunc || setfunc) {
3088     /* don't save in id properties */
3089     prop->flag &= ~PROP_IDPROPERTY;
3090 
3091     if (!setfunc) {
3092       prop->flag &= ~PROP_EDITABLE;
3093     }
3094   }
3095 }
3096 
RNA_def_property_int_array_funcs_runtime(PropertyRNA * prop,IntArrayPropertyGetFunc getfunc,IntArrayPropertySetFunc setfunc,IntPropertyRangeFunc rangefunc)3097 void RNA_def_property_int_array_funcs_runtime(PropertyRNA *prop,
3098                                               IntArrayPropertyGetFunc getfunc,
3099                                               IntArrayPropertySetFunc setfunc,
3100                                               IntPropertyRangeFunc rangefunc)
3101 {
3102   IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
3103 
3104   if (getfunc) {
3105     iprop->getarray_ex = getfunc;
3106   }
3107   if (setfunc) {
3108     iprop->setarray_ex = setfunc;
3109   }
3110   if (rangefunc) {
3111     iprop->range_ex = rangefunc;
3112   }
3113 
3114   if (getfunc || setfunc) {
3115     /* don't save in id properties */
3116     prop->flag &= ~PROP_IDPROPERTY;
3117 
3118     if (!setfunc) {
3119       prop->flag &= ~PROP_EDITABLE;
3120     }
3121   }
3122 }
3123 
RNA_def_property_float_funcs(PropertyRNA * prop,const char * get,const char * set,const char * range)3124 void RNA_def_property_float_funcs(PropertyRNA *prop,
3125                                   const char *get,
3126                                   const char *set,
3127                                   const char *range)
3128 {
3129   StructRNA *srna = DefRNA.laststruct;
3130 
3131   if (!DefRNA.preprocess) {
3132     CLOG_ERROR(&LOG, "only during preprocessing.");
3133     return;
3134   }
3135 
3136   switch (prop->type) {
3137     case PROP_FLOAT: {
3138       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
3139 
3140       if (prop->arraydimension) {
3141         if (get) {
3142           fprop->getarray = (PropFloatArrayGetFunc)get;
3143         }
3144         if (set) {
3145           fprop->setarray = (PropFloatArraySetFunc)set;
3146         }
3147       }
3148       else {
3149         if (get) {
3150           fprop->get = (PropFloatGetFunc)get;
3151         }
3152         if (set) {
3153           fprop->set = (PropFloatSetFunc)set;
3154         }
3155       }
3156       if (range) {
3157         fprop->range = (PropFloatRangeFunc)range;
3158       }
3159       break;
3160     }
3161     default:
3162       CLOG_ERROR(&LOG, "\"%s.%s\", type is not float.", srna->identifier, prop->identifier);
3163       DefRNA.error = true;
3164       break;
3165   }
3166 }
3167 
RNA_def_property_float_funcs_runtime(PropertyRNA * prop,FloatPropertyGetFunc getfunc,FloatPropertySetFunc setfunc,FloatPropertyRangeFunc rangefunc)3168 void RNA_def_property_float_funcs_runtime(PropertyRNA *prop,
3169                                           FloatPropertyGetFunc getfunc,
3170                                           FloatPropertySetFunc setfunc,
3171                                           FloatPropertyRangeFunc rangefunc)
3172 {
3173   FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
3174 
3175   if (getfunc) {
3176     fprop->get_ex = getfunc;
3177   }
3178   if (setfunc) {
3179     fprop->set_ex = setfunc;
3180   }
3181   if (rangefunc) {
3182     fprop->range_ex = rangefunc;
3183   }
3184 
3185   if (getfunc || setfunc) {
3186     /* don't save in id properties */
3187     prop->flag &= ~PROP_IDPROPERTY;
3188 
3189     if (!setfunc) {
3190       prop->flag &= ~PROP_EDITABLE;
3191     }
3192   }
3193 }
3194 
RNA_def_property_float_array_funcs_runtime(PropertyRNA * prop,FloatArrayPropertyGetFunc getfunc,FloatArrayPropertySetFunc setfunc,FloatPropertyRangeFunc rangefunc)3195 void RNA_def_property_float_array_funcs_runtime(PropertyRNA *prop,
3196                                                 FloatArrayPropertyGetFunc getfunc,
3197                                                 FloatArrayPropertySetFunc setfunc,
3198                                                 FloatPropertyRangeFunc rangefunc)
3199 {
3200   FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
3201 
3202   if (getfunc) {
3203     fprop->getarray_ex = getfunc;
3204   }
3205   if (setfunc) {
3206     fprop->setarray_ex = setfunc;
3207   }
3208   if (rangefunc) {
3209     fprop->range_ex = rangefunc;
3210   }
3211 
3212   if (getfunc || setfunc) {
3213     /* don't save in id properties */
3214     prop->flag &= ~PROP_IDPROPERTY;
3215 
3216     if (!setfunc) {
3217       prop->flag &= ~PROP_EDITABLE;
3218     }
3219   }
3220 }
3221 
RNA_def_property_enum_funcs(PropertyRNA * prop,const char * get,const char * set,const char * item)3222 void RNA_def_property_enum_funcs(PropertyRNA *prop,
3223                                  const char *get,
3224                                  const char *set,
3225                                  const char *item)
3226 {
3227   StructRNA *srna = DefRNA.laststruct;
3228 
3229   if (!DefRNA.preprocess) {
3230     CLOG_ERROR(&LOG, "only during preprocessing.");
3231     return;
3232   }
3233 
3234   switch (prop->type) {
3235     case PROP_ENUM: {
3236       EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
3237 
3238       if (get) {
3239         eprop->get = (PropEnumGetFunc)get;
3240       }
3241       if (set) {
3242         eprop->set = (PropEnumSetFunc)set;
3243       }
3244       if (item) {
3245         eprop->itemf = (PropEnumItemFunc)item;
3246       }
3247       break;
3248     }
3249     default:
3250       CLOG_ERROR(&LOG, "\"%s.%s\", type is not enum.", srna->identifier, prop->identifier);
3251       DefRNA.error = true;
3252       break;
3253   }
3254 }
3255 
RNA_def_property_enum_funcs_runtime(PropertyRNA * prop,EnumPropertyGetFunc getfunc,EnumPropertySetFunc setfunc,EnumPropertyItemFunc itemfunc)3256 void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop,
3257                                          EnumPropertyGetFunc getfunc,
3258                                          EnumPropertySetFunc setfunc,
3259                                          EnumPropertyItemFunc itemfunc)
3260 {
3261   EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
3262 
3263   if (getfunc) {
3264     eprop->get_ex = getfunc;
3265   }
3266   if (setfunc) {
3267     eprop->set_ex = setfunc;
3268   }
3269   if (itemfunc) {
3270     eprop->itemf = itemfunc;
3271   }
3272 
3273   if (getfunc || setfunc) {
3274     /* don't save in id properties */
3275     prop->flag &= ~PROP_IDPROPERTY;
3276 
3277     if (!setfunc) {
3278       prop->flag &= ~PROP_EDITABLE;
3279     }
3280   }
3281 }
3282 
RNA_def_property_enum_py_data(PropertyRNA * prop,void * py_data)3283 void RNA_def_property_enum_py_data(PropertyRNA *prop, void *py_data)
3284 {
3285   EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
3286   eprop->py_data = py_data;
3287 }
3288 
RNA_def_property_string_funcs(PropertyRNA * prop,const char * get,const char * length,const char * set)3289 void RNA_def_property_string_funcs(PropertyRNA *prop,
3290                                    const char *get,
3291                                    const char *length,
3292                                    const char *set)
3293 {
3294   StructRNA *srna = DefRNA.laststruct;
3295 
3296   if (!DefRNA.preprocess) {
3297     CLOG_ERROR(&LOG, "only during preprocessing.");
3298     return;
3299   }
3300 
3301   switch (prop->type) {
3302     case PROP_STRING: {
3303       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
3304 
3305       if (get) {
3306         sprop->get = (PropStringGetFunc)get;
3307       }
3308       if (length) {
3309         sprop->length = (PropStringLengthFunc)length;
3310       }
3311       if (set) {
3312         sprop->set = (PropStringSetFunc)set;
3313       }
3314       break;
3315     }
3316     default:
3317       CLOG_ERROR(&LOG, "\"%s.%s\", type is not string.", srna->identifier, prop->identifier);
3318       DefRNA.error = true;
3319       break;
3320   }
3321 }
3322 
RNA_def_property_string_funcs_runtime(PropertyRNA * prop,StringPropertyGetFunc getfunc,StringPropertyLengthFunc lengthfunc,StringPropertySetFunc setfunc)3323 void RNA_def_property_string_funcs_runtime(PropertyRNA *prop,
3324                                            StringPropertyGetFunc getfunc,
3325                                            StringPropertyLengthFunc lengthfunc,
3326                                            StringPropertySetFunc setfunc)
3327 {
3328   StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
3329 
3330   if (getfunc) {
3331     sprop->get_ex = getfunc;
3332   }
3333   if (lengthfunc) {
3334     sprop->length_ex = lengthfunc;
3335   }
3336   if (setfunc) {
3337     sprop->set_ex = setfunc;
3338   }
3339 
3340   if (getfunc || setfunc) {
3341     /* don't save in id properties */
3342     prop->flag &= ~PROP_IDPROPERTY;
3343 
3344     if (!setfunc) {
3345       prop->flag &= ~PROP_EDITABLE;
3346     }
3347   }
3348 }
3349 
RNA_def_property_pointer_funcs(PropertyRNA * prop,const char * get,const char * set,const char * typef,const char * poll)3350 void RNA_def_property_pointer_funcs(
3351     PropertyRNA *prop, const char *get, const char *set, const char *typef, const char *poll)
3352 {
3353   StructRNA *srna = DefRNA.laststruct;
3354 
3355   if (!DefRNA.preprocess) {
3356     CLOG_ERROR(&LOG, "only during preprocessing.");
3357     return;
3358   }
3359 
3360   switch (prop->type) {
3361     case PROP_POINTER: {
3362       PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
3363 
3364       if (get) {
3365         pprop->get = (PropPointerGetFunc)get;
3366       }
3367       if (set) {
3368         pprop->set = (PropPointerSetFunc)set;
3369       }
3370       if (typef) {
3371         pprop->typef = (PropPointerTypeFunc)typef;
3372       }
3373       if (poll) {
3374         pprop->poll = (PropPointerPollFunc)poll;
3375       }
3376       break;
3377     }
3378     default:
3379       CLOG_ERROR(&LOG, "\"%s.%s\", type is not pointer.", srna->identifier, prop->identifier);
3380       DefRNA.error = true;
3381       break;
3382   }
3383 }
3384 
RNA_def_property_collection_funcs(PropertyRNA * prop,const char * begin,const char * next,const char * end,const char * get,const char * length,const char * lookupint,const char * lookupstring,const char * assignint)3385 void RNA_def_property_collection_funcs(PropertyRNA *prop,
3386                                        const char *begin,
3387                                        const char *next,
3388                                        const char *end,
3389                                        const char *get,
3390                                        const char *length,
3391                                        const char *lookupint,
3392                                        const char *lookupstring,
3393                                        const char *assignint)
3394 {
3395   StructRNA *srna = DefRNA.laststruct;
3396 
3397   if (!DefRNA.preprocess) {
3398     CLOG_ERROR(&LOG, "only during preprocessing.");
3399     return;
3400   }
3401 
3402   switch (prop->type) {
3403     case PROP_COLLECTION: {
3404       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
3405 
3406       if (begin) {
3407         cprop->begin = (PropCollectionBeginFunc)begin;
3408       }
3409       if (next) {
3410         cprop->next = (PropCollectionNextFunc)next;
3411       }
3412       if (end) {
3413         cprop->end = (PropCollectionEndFunc)end;
3414       }
3415       if (get) {
3416         cprop->get = (PropCollectionGetFunc)get;
3417       }
3418       if (length) {
3419         cprop->length = (PropCollectionLengthFunc)length;
3420       }
3421       if (lookupint) {
3422         cprop->lookupint = (PropCollectionLookupIntFunc)lookupint;
3423       }
3424       if (lookupstring) {
3425         cprop->lookupstring = (PropCollectionLookupStringFunc)lookupstring;
3426       }
3427       if (assignint) {
3428         cprop->assignint = (PropCollectionAssignIntFunc)assignint;
3429       }
3430       break;
3431     }
3432     default:
3433       CLOG_ERROR(&LOG, "\"%s.%s\", type is not collection.", srna->identifier, prop->identifier);
3434       DefRNA.error = true;
3435       break;
3436   }
3437 }
3438 
RNA_def_property_srna(PropertyRNA * prop,const char * type)3439 void RNA_def_property_srna(PropertyRNA *prop, const char *type)
3440 {
3441   prop->srna = (StructRNA *)type;
3442 }
3443 
RNA_def_py_data(PropertyRNA * prop,void * py_data)3444 void RNA_def_py_data(PropertyRNA *prop, void *py_data)
3445 {
3446   prop->py_data = py_data;
3447 }
3448 
3449 /* Compact definitions */
3450 
RNA_def_boolean(StructOrFunctionRNA * cont_,const char * identifier,bool default_value,const char * ui_name,const char * ui_description)3451 PropertyRNA *RNA_def_boolean(StructOrFunctionRNA *cont_,
3452                              const char *identifier,
3453                              bool default_value,
3454                              const char *ui_name,
3455                              const char *ui_description)
3456 {
3457   ContainerRNA *cont = cont_;
3458   PropertyRNA *prop;
3459 
3460   prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_NONE);
3461   RNA_def_property_boolean_default(prop, default_value);
3462   RNA_def_property_ui_text(prop, ui_name, ui_description);
3463 
3464   return prop;
3465 }
3466 
RNA_def_boolean_array(StructOrFunctionRNA * cont_,const char * identifier,int len,bool * default_value,const char * ui_name,const char * ui_description)3467 PropertyRNA *RNA_def_boolean_array(StructOrFunctionRNA *cont_,
3468                                    const char *identifier,
3469                                    int len,
3470                                    bool *default_value,
3471                                    const char *ui_name,
3472                                    const char *ui_description)
3473 {
3474   ContainerRNA *cont = cont_;
3475   PropertyRNA *prop;
3476 
3477   prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_NONE);
3478   if (len != 0) {
3479     RNA_def_property_array(prop, len);
3480   }
3481   if (default_value) {
3482     RNA_def_property_boolean_array_default(prop, default_value);
3483   }
3484   RNA_def_property_ui_text(prop, ui_name, ui_description);
3485 
3486   return prop;
3487 }
3488 
RNA_def_boolean_layer(StructOrFunctionRNA * cont_,const char * identifier,int len,bool * default_value,const char * ui_name,const char * ui_description)3489 PropertyRNA *RNA_def_boolean_layer(StructOrFunctionRNA *cont_,
3490                                    const char *identifier,
3491                                    int len,
3492                                    bool *default_value,
3493                                    const char *ui_name,
3494                                    const char *ui_description)
3495 {
3496   ContainerRNA *cont = cont_;
3497   PropertyRNA *prop;
3498 
3499   prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_LAYER);
3500   if (len != 0) {
3501     RNA_def_property_array(prop, len);
3502   }
3503   if (default_value) {
3504     RNA_def_property_boolean_array_default(prop, default_value);
3505   }
3506   RNA_def_property_ui_text(prop, ui_name, ui_description);
3507 
3508   return prop;
3509 }
3510 
RNA_def_boolean_layer_member(StructOrFunctionRNA * cont_,const char * identifier,int len,bool * default_value,const char * ui_name,const char * ui_description)3511 PropertyRNA *RNA_def_boolean_layer_member(StructOrFunctionRNA *cont_,
3512                                           const char *identifier,
3513                                           int len,
3514                                           bool *default_value,
3515                                           const char *ui_name,
3516                                           const char *ui_description)
3517 {
3518   ContainerRNA *cont = cont_;
3519   PropertyRNA *prop;
3520 
3521   prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_LAYER_MEMBER);
3522   if (len != 0) {
3523     RNA_def_property_array(prop, len);
3524   }
3525   if (default_value) {
3526     RNA_def_property_boolean_array_default(prop, default_value);
3527   }
3528   RNA_def_property_ui_text(prop, ui_name, ui_description);
3529 
3530   return prop;
3531 }
3532 
RNA_def_boolean_vector(StructOrFunctionRNA * cont_,const char * identifier,int len,bool * default_value,const char * ui_name,const char * ui_description)3533 PropertyRNA *RNA_def_boolean_vector(StructOrFunctionRNA *cont_,
3534                                     const char *identifier,
3535                                     int len,
3536                                     bool *default_value,
3537                                     const char *ui_name,
3538                                     const char *ui_description)
3539 {
3540   ContainerRNA *cont = cont_;
3541   PropertyRNA *prop;
3542 
3543   prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_XYZ); /* XXX */
3544   if (len != 0) {
3545     RNA_def_property_array(prop, len);
3546   }
3547   if (default_value) {
3548     RNA_def_property_boolean_array_default(prop, default_value);
3549   }
3550   RNA_def_property_ui_text(prop, ui_name, ui_description);
3551 
3552   return prop;
3553 }
3554 
RNA_def_int(StructOrFunctionRNA * cont_,const char * identifier,int default_value,int hardmin,int hardmax,const char * ui_name,const char * ui_description,int softmin,int softmax)3555 PropertyRNA *RNA_def_int(StructOrFunctionRNA *cont_,
3556                          const char *identifier,
3557                          int default_value,
3558                          int hardmin,
3559                          int hardmax,
3560                          const char *ui_name,
3561                          const char *ui_description,
3562                          int softmin,
3563                          int softmax)
3564 {
3565   ContainerRNA *cont = cont_;
3566   PropertyRNA *prop;
3567 
3568   ASSERT_SOFT_HARD_LIMITS;
3569 
3570   prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE);
3571   RNA_def_property_int_default(prop, default_value);
3572   if (hardmin != hardmax) {
3573     RNA_def_property_range(prop, hardmin, hardmax);
3574   }
3575   RNA_def_property_ui_text(prop, ui_name, ui_description);
3576   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3577 
3578   return prop;
3579 }
3580 
RNA_def_int_vector(StructOrFunctionRNA * cont_,const char * identifier,int len,const int * default_value,int hardmin,int hardmax,const char * ui_name,const char * ui_description,int softmin,int softmax)3581 PropertyRNA *RNA_def_int_vector(StructOrFunctionRNA *cont_,
3582                                 const char *identifier,
3583                                 int len,
3584                                 const int *default_value,
3585                                 int hardmin,
3586                                 int hardmax,
3587                                 const char *ui_name,
3588                                 const char *ui_description,
3589                                 int softmin,
3590                                 int softmax)
3591 {
3592   ContainerRNA *cont = cont_;
3593   PropertyRNA *prop;
3594 
3595   ASSERT_SOFT_HARD_LIMITS;
3596 
3597   prop = RNA_def_property(cont, identifier, PROP_INT, PROP_XYZ); /* XXX */
3598   if (len != 0) {
3599     RNA_def_property_array(prop, len);
3600   }
3601   if (default_value) {
3602     RNA_def_property_int_array_default(prop, default_value);
3603   }
3604   if (hardmin != hardmax) {
3605     RNA_def_property_range(prop, hardmin, hardmax);
3606   }
3607   RNA_def_property_ui_text(prop, ui_name, ui_description);
3608   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3609 
3610   return prop;
3611 }
3612 
RNA_def_int_array(StructOrFunctionRNA * cont_,const char * identifier,int len,const int * default_value,int hardmin,int hardmax,const char * ui_name,const char * ui_description,int softmin,int softmax)3613 PropertyRNA *RNA_def_int_array(StructOrFunctionRNA *cont_,
3614                                const char *identifier,
3615                                int len,
3616                                const int *default_value,
3617                                int hardmin,
3618                                int hardmax,
3619                                const char *ui_name,
3620                                const char *ui_description,
3621                                int softmin,
3622                                int softmax)
3623 {
3624   ContainerRNA *cont = cont_;
3625   PropertyRNA *prop;
3626 
3627   ASSERT_SOFT_HARD_LIMITS;
3628 
3629   prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE);
3630   if (len != 0) {
3631     RNA_def_property_array(prop, len);
3632   }
3633   if (default_value) {
3634     RNA_def_property_int_array_default(prop, default_value);
3635   }
3636   if (hardmin != hardmax) {
3637     RNA_def_property_range(prop, hardmin, hardmax);
3638   }
3639   RNA_def_property_ui_text(prop, ui_name, ui_description);
3640   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3641 
3642   return prop;
3643 }
3644 
RNA_def_string(StructOrFunctionRNA * cont_,const char * identifier,const char * default_value,int maxlen,const char * ui_name,const char * ui_description)3645 PropertyRNA *RNA_def_string(StructOrFunctionRNA *cont_,
3646                             const char *identifier,
3647                             const char *default_value,
3648                             int maxlen,
3649                             const char *ui_name,
3650                             const char *ui_description)
3651 {
3652   ContainerRNA *cont = cont_;
3653   PropertyRNA *prop;
3654 
3655   BLI_assert(default_value == NULL || default_value[0]);
3656 
3657   prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_NONE);
3658   if (maxlen != 0) {
3659     RNA_def_property_string_maxlength(prop, maxlen);
3660   }
3661   if (default_value) {
3662     RNA_def_property_string_default(prop, default_value);
3663   }
3664   RNA_def_property_ui_text(prop, ui_name, ui_description);
3665 
3666   return prop;
3667 }
3668 
RNA_def_string_file_path(StructOrFunctionRNA * cont_,const char * identifier,const char * default_value,int maxlen,const char * ui_name,const char * ui_description)3669 PropertyRNA *RNA_def_string_file_path(StructOrFunctionRNA *cont_,
3670                                       const char *identifier,
3671                                       const char *default_value,
3672                                       int maxlen,
3673                                       const char *ui_name,
3674                                       const char *ui_description)
3675 {
3676   ContainerRNA *cont = cont_;
3677   PropertyRNA *prop;
3678 
3679   BLI_assert(default_value == NULL || default_value[0]);
3680 
3681   prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_FILEPATH);
3682   if (maxlen != 0) {
3683     RNA_def_property_string_maxlength(prop, maxlen);
3684   }
3685   if (default_value) {
3686     RNA_def_property_string_default(prop, default_value);
3687   }
3688   RNA_def_property_ui_text(prop, ui_name, ui_description);
3689 
3690   return prop;
3691 }
3692 
RNA_def_string_dir_path(StructOrFunctionRNA * cont_,const char * identifier,const char * default_value,int maxlen,const char * ui_name,const char * ui_description)3693 PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont_,
3694                                      const char *identifier,
3695                                      const char *default_value,
3696                                      int maxlen,
3697                                      const char *ui_name,
3698                                      const char *ui_description)
3699 {
3700   ContainerRNA *cont = cont_;
3701   PropertyRNA *prop;
3702 
3703   BLI_assert(default_value == NULL || default_value[0]);
3704 
3705   prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_DIRPATH);
3706   if (maxlen != 0) {
3707     RNA_def_property_string_maxlength(prop, maxlen);
3708   }
3709   if (default_value) {
3710     RNA_def_property_string_default(prop, default_value);
3711   }
3712   RNA_def_property_ui_text(prop, ui_name, ui_description);
3713 
3714   return prop;
3715 }
3716 
RNA_def_string_file_name(StructOrFunctionRNA * cont_,const char * identifier,const char * default_value,int maxlen,const char * ui_name,const char * ui_description)3717 PropertyRNA *RNA_def_string_file_name(StructOrFunctionRNA *cont_,
3718                                       const char *identifier,
3719                                       const char *default_value,
3720                                       int maxlen,
3721                                       const char *ui_name,
3722                                       const char *ui_description)
3723 {
3724   ContainerRNA *cont = cont_;
3725   PropertyRNA *prop;
3726 
3727   BLI_assert(default_value == NULL || default_value[0]);
3728 
3729   prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_FILENAME);
3730   if (maxlen != 0) {
3731     RNA_def_property_string_maxlength(prop, maxlen);
3732   }
3733   if (default_value) {
3734     RNA_def_property_string_default(prop, default_value);
3735   }
3736   RNA_def_property_ui_text(prop, ui_name, ui_description);
3737 
3738   return prop;
3739 }
3740 
RNA_def_enum(StructOrFunctionRNA * cont_,const char * identifier,const EnumPropertyItem * items,int default_value,const char * ui_name,const char * ui_description)3741 PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_,
3742                           const char *identifier,
3743                           const EnumPropertyItem *items,
3744                           int default_value,
3745                           const char *ui_name,
3746                           const char *ui_description)
3747 {
3748   ContainerRNA *cont = cont_;
3749   PropertyRNA *prop;
3750 
3751   if (items == NULL) {
3752     CLOG_ERROR(&LOG, "items not allowed to be NULL.");
3753     return NULL;
3754   }
3755 
3756   prop = RNA_def_property(cont, identifier, PROP_ENUM, PROP_NONE);
3757   RNA_def_property_enum_items(prop, items);
3758   RNA_def_property_enum_default(prop, default_value);
3759   RNA_def_property_ui_text(prop, ui_name, ui_description);
3760 
3761   return prop;
3762 }
3763 
3764 /* same as above but sets 'PROP_ENUM_FLAG' before setting the default value */
RNA_def_enum_flag(StructOrFunctionRNA * cont_,const char * identifier,const EnumPropertyItem * items,int default_value,const char * ui_name,const char * ui_description)3765 PropertyRNA *RNA_def_enum_flag(StructOrFunctionRNA *cont_,
3766                                const char *identifier,
3767                                const EnumPropertyItem *items,
3768                                int default_value,
3769                                const char *ui_name,
3770                                const char *ui_description)
3771 {
3772   ContainerRNA *cont = cont_;
3773   PropertyRNA *prop;
3774 
3775   if (items == NULL) {
3776     CLOG_ERROR(&LOG, "items not allowed to be NULL.");
3777     return NULL;
3778   }
3779 
3780   prop = RNA_def_property(cont, identifier, PROP_ENUM, PROP_NONE);
3781   RNA_def_property_flag(prop, PROP_ENUM_FLAG); /* important to run before default set */
3782   RNA_def_property_enum_items(prop, items);
3783   RNA_def_property_enum_default(prop, default_value);
3784   RNA_def_property_ui_text(prop, ui_name, ui_description);
3785 
3786   return prop;
3787 }
3788 
RNA_def_enum_funcs(PropertyRNA * prop,EnumPropertyItemFunc itemfunc)3789 void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
3790 {
3791   EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
3792   eprop->itemf = itemfunc;
3793 }
3794 
RNA_def_float(StructOrFunctionRNA * cont_,const char * identifier,float default_value,float hardmin,float hardmax,const char * ui_name,const char * ui_description,float softmin,float softmax)3795 PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont_,
3796                            const char *identifier,
3797                            float default_value,
3798                            float hardmin,
3799                            float hardmax,
3800                            const char *ui_name,
3801                            const char *ui_description,
3802                            float softmin,
3803                            float softmax)
3804 {
3805   ContainerRNA *cont = cont_;
3806   PropertyRNA *prop;
3807 
3808   ASSERT_SOFT_HARD_LIMITS;
3809 
3810   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE);
3811   RNA_def_property_float_default(prop, default_value);
3812   if (hardmin != hardmax) {
3813     RNA_def_property_range(prop, hardmin, hardmax);
3814   }
3815   RNA_def_property_ui_text(prop, ui_name, ui_description);
3816   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3817 
3818   return prop;
3819 }
3820 
RNA_def_float_vector(StructOrFunctionRNA * cont_,const char * identifier,int len,const float * default_value,float hardmin,float hardmax,const char * ui_name,const char * ui_description,float softmin,float softmax)3821 PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont_,
3822                                   const char *identifier,
3823                                   int len,
3824                                   const float *default_value,
3825                                   float hardmin,
3826                                   float hardmax,
3827                                   const char *ui_name,
3828                                   const char *ui_description,
3829                                   float softmin,
3830                                   float softmax)
3831 {
3832   ContainerRNA *cont = cont_;
3833   PropertyRNA *prop;
3834 
3835   ASSERT_SOFT_HARD_LIMITS;
3836 
3837   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_XYZ);
3838   if (len != 0) {
3839     RNA_def_property_array(prop, len);
3840   }
3841   if (default_value) {
3842     RNA_def_property_float_array_default(prop, default_value);
3843   }
3844   if (hardmin != hardmax) {
3845     RNA_def_property_range(prop, hardmin, hardmax);
3846   }
3847   RNA_def_property_ui_text(prop, ui_name, ui_description);
3848   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3849 
3850   return prop;
3851 }
3852 
RNA_def_float_vector_xyz(StructOrFunctionRNA * cont_,const char * identifier,int len,const float * default_value,float hardmin,float hardmax,const char * ui_name,const char * ui_description,float softmin,float softmax)3853 PropertyRNA *RNA_def_float_vector_xyz(StructOrFunctionRNA *cont_,
3854                                       const char *identifier,
3855                                       int len,
3856                                       const float *default_value,
3857                                       float hardmin,
3858                                       float hardmax,
3859                                       const char *ui_name,
3860                                       const char *ui_description,
3861                                       float softmin,
3862                                       float softmax)
3863 {
3864   PropertyRNA *prop;
3865 
3866   prop = RNA_def_float_vector(cont_,
3867                               identifier,
3868                               len,
3869                               default_value,
3870                               hardmin,
3871                               hardmax,
3872                               ui_name,
3873                               ui_description,
3874                               softmin,
3875                               softmax);
3876   prop->subtype = PROP_XYZ_LENGTH;
3877 
3878   return prop;
3879 }
3880 
RNA_def_float_color(StructOrFunctionRNA * cont_,const char * identifier,int len,const float * default_value,float hardmin,float hardmax,const char * ui_name,const char * ui_description,float softmin,float softmax)3881 PropertyRNA *RNA_def_float_color(StructOrFunctionRNA *cont_,
3882                                  const char *identifier,
3883                                  int len,
3884                                  const float *default_value,
3885                                  float hardmin,
3886                                  float hardmax,
3887                                  const char *ui_name,
3888                                  const char *ui_description,
3889                                  float softmin,
3890                                  float softmax)
3891 {
3892   ContainerRNA *cont = cont_;
3893   PropertyRNA *prop;
3894 
3895   ASSERT_SOFT_HARD_LIMITS;
3896 
3897   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_COLOR);
3898   if (len != 0) {
3899     RNA_def_property_array(prop, len);
3900   }
3901   if (default_value) {
3902     RNA_def_property_float_array_default(prop, default_value);
3903   }
3904   if (hardmin != hardmax) {
3905     RNA_def_property_range(prop, hardmin, hardmax);
3906   }
3907   RNA_def_property_ui_text(prop, ui_name, ui_description);
3908   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3909 
3910   return prop;
3911 }
3912 
RNA_def_float_matrix(StructOrFunctionRNA * cont_,const char * identifier,int rows,int columns,const float * default_value,float hardmin,float hardmax,const char * ui_name,const char * ui_description,float softmin,float softmax)3913 PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont_,
3914                                   const char *identifier,
3915                                   int rows,
3916                                   int columns,
3917                                   const float *default_value,
3918                                   float hardmin,
3919                                   float hardmax,
3920                                   const char *ui_name,
3921                                   const char *ui_description,
3922                                   float softmin,
3923                                   float softmax)
3924 {
3925   ContainerRNA *cont = cont_;
3926   PropertyRNA *prop;
3927   const int length[2] = {rows, columns};
3928 
3929   ASSERT_SOFT_HARD_LIMITS;
3930 
3931   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_MATRIX);
3932   RNA_def_property_multi_array(prop, 2, length);
3933   if (default_value) {
3934     RNA_def_property_float_array_default(prop, default_value);
3935   }
3936   if (hardmin != hardmax) {
3937     RNA_def_property_range(prop, hardmin, hardmax);
3938   }
3939   RNA_def_property_ui_text(prop, ui_name, ui_description);
3940   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3941 
3942   return prop;
3943 }
3944 
RNA_def_float_translation(StructOrFunctionRNA * cont_,const char * identifier,int len,const float * default_value,float hardmin,float hardmax,const char * ui_name,const char * ui_description,float softmin,float softmax)3945 PropertyRNA *RNA_def_float_translation(StructOrFunctionRNA *cont_,
3946                                        const char *identifier,
3947                                        int len,
3948                                        const float *default_value,
3949                                        float hardmin,
3950                                        float hardmax,
3951                                        const char *ui_name,
3952                                        const char *ui_description,
3953                                        float softmin,
3954                                        float softmax)
3955 {
3956   PropertyRNA *prop;
3957 
3958   prop = RNA_def_float_vector(cont_,
3959                               identifier,
3960                               len,
3961                               default_value,
3962                               hardmin,
3963                               hardmax,
3964                               ui_name,
3965                               ui_description,
3966                               softmin,
3967                               softmax);
3968   prop->subtype = PROP_TRANSLATION;
3969 
3970   RNA_def_property_ui_range(prop, softmin, softmax, 1, RNA_TRANSLATION_PREC_DEFAULT);
3971 
3972   return prop;
3973 }
3974 
RNA_def_float_rotation(StructOrFunctionRNA * cont_,const char * identifier,int len,const float * default_value,float hardmin,float hardmax,const char * ui_name,const char * ui_description,float softmin,float softmax)3975 PropertyRNA *RNA_def_float_rotation(StructOrFunctionRNA *cont_,
3976                                     const char *identifier,
3977                                     int len,
3978                                     const float *default_value,
3979                                     float hardmin,
3980                                     float hardmax,
3981                                     const char *ui_name,
3982                                     const char *ui_description,
3983                                     float softmin,
3984                                     float softmax)
3985 {
3986   ContainerRNA *cont = cont_;
3987   PropertyRNA *prop;
3988 
3989   ASSERT_SOFT_HARD_LIMITS;
3990 
3991   prop = RNA_def_property(cont, identifier, PROP_FLOAT, (len >= 3) ? PROP_EULER : PROP_ANGLE);
3992   if (len != 0) {
3993     RNA_def_property_array(prop, len);
3994     if (default_value) {
3995       RNA_def_property_float_array_default(prop, default_value);
3996     }
3997   }
3998   else {
3999     /* RNA_def_property_float_default must be called outside */
4000     BLI_assert(default_value == NULL);
4001   }
4002   if (hardmin != hardmax) {
4003     RNA_def_property_range(prop, hardmin, hardmax);
4004   }
4005   RNA_def_property_ui_text(prop, ui_name, ui_description);
4006   RNA_def_property_ui_range(prop, softmin, softmax, 10, 3);
4007 
4008   return prop;
4009 }
4010 
RNA_def_float_distance(StructOrFunctionRNA * cont_,const char * identifier,float default_value,float hardmin,float hardmax,const char * ui_name,const char * ui_description,float softmin,float softmax)4011 PropertyRNA *RNA_def_float_distance(StructOrFunctionRNA *cont_,
4012                                     const char *identifier,
4013                                     float default_value,
4014                                     float hardmin,
4015                                     float hardmax,
4016                                     const char *ui_name,
4017                                     const char *ui_description,
4018                                     float softmin,
4019                                     float softmax)
4020 {
4021   PropertyRNA *prop = RNA_def_float(cont_,
4022                                     identifier,
4023                                     default_value,
4024                                     hardmin,
4025                                     hardmax,
4026                                     ui_name,
4027                                     ui_description,
4028                                     softmin,
4029                                     softmax);
4030   RNA_def_property_subtype(prop, PROP_DISTANCE);
4031 
4032   return prop;
4033 }
4034 
RNA_def_float_array(StructOrFunctionRNA * cont_,const char * identifier,int len,const float * default_value,float hardmin,float hardmax,const char * ui_name,const char * ui_description,float softmin,float softmax)4035 PropertyRNA *RNA_def_float_array(StructOrFunctionRNA *cont_,
4036                                  const char *identifier,
4037                                  int len,
4038                                  const float *default_value,
4039                                  float hardmin,
4040                                  float hardmax,
4041                                  const char *ui_name,
4042                                  const char *ui_description,
4043                                  float softmin,
4044                                  float softmax)
4045 {
4046   ContainerRNA *cont = cont_;
4047   PropertyRNA *prop;
4048 
4049   ASSERT_SOFT_HARD_LIMITS;
4050 
4051   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE);
4052   if (len != 0) {
4053     RNA_def_property_array(prop, len);
4054   }
4055   if (default_value) {
4056     RNA_def_property_float_array_default(prop, default_value);
4057   }
4058   if (hardmin != hardmax) {
4059     RNA_def_property_range(prop, hardmin, hardmax);
4060   }
4061   RNA_def_property_ui_text(prop, ui_name, ui_description);
4062   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
4063 
4064   return prop;
4065 }
4066 
RNA_def_float_percentage(StructOrFunctionRNA * cont_,const char * identifier,float default_value,float hardmin,float hardmax,const char * ui_name,const char * ui_description,float softmin,float softmax)4067 PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont_,
4068                                       const char *identifier,
4069                                       float default_value,
4070                                       float hardmin,
4071                                       float hardmax,
4072                                       const char *ui_name,
4073                                       const char *ui_description,
4074                                       float softmin,
4075                                       float softmax)
4076 {
4077   ContainerRNA *cont = cont_;
4078   PropertyRNA *prop;
4079 
4080   ASSERT_SOFT_HARD_LIMITS;
4081 
4082   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_PERCENTAGE);
4083   RNA_def_property_float_default(prop, default_value);
4084   if (hardmin != hardmax) {
4085     RNA_def_property_range(prop, hardmin, hardmax);
4086   }
4087   RNA_def_property_ui_text(prop, ui_name, ui_description);
4088   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
4089 
4090   return prop;
4091 }
4092 
RNA_def_float_factor(StructOrFunctionRNA * cont_,const char * identifier,float default_value,float hardmin,float hardmax,const char * ui_name,const char * ui_description,float softmin,float softmax)4093 PropertyRNA *RNA_def_float_factor(StructOrFunctionRNA *cont_,
4094                                   const char *identifier,
4095                                   float default_value,
4096                                   float hardmin,
4097                                   float hardmax,
4098                                   const char *ui_name,
4099                                   const char *ui_description,
4100                                   float softmin,
4101                                   float softmax)
4102 {
4103   ContainerRNA *cont = cont_;
4104   PropertyRNA *prop;
4105 
4106   ASSERT_SOFT_HARD_LIMITS;
4107 
4108   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_FACTOR);
4109   RNA_def_property_float_default(prop, default_value);
4110   if (hardmin != hardmax) {
4111     RNA_def_property_range(prop, hardmin, hardmax);
4112   }
4113   RNA_def_property_ui_text(prop, ui_name, ui_description);
4114   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
4115 
4116   return prop;
4117 }
4118 
RNA_def_pointer(StructOrFunctionRNA * cont_,const char * identifier,const char * type,const char * ui_name,const char * ui_description)4119 PropertyRNA *RNA_def_pointer(StructOrFunctionRNA *cont_,
4120                              const char *identifier,
4121                              const char *type,
4122                              const char *ui_name,
4123                              const char *ui_description)
4124 {
4125   ContainerRNA *cont = cont_;
4126   PropertyRNA *prop;
4127 
4128   prop = RNA_def_property(cont, identifier, PROP_POINTER, PROP_NONE);
4129   RNA_def_property_struct_type(prop, type);
4130   RNA_def_property_ui_text(prop, ui_name, ui_description);
4131 
4132   return prop;
4133 }
4134 
RNA_def_pointer_runtime(StructOrFunctionRNA * cont_,const char * identifier,StructRNA * type,const char * ui_name,const char * ui_description)4135 PropertyRNA *RNA_def_pointer_runtime(StructOrFunctionRNA *cont_,
4136                                      const char *identifier,
4137                                      StructRNA *type,
4138                                      const char *ui_name,
4139                                      const char *ui_description)
4140 {
4141   ContainerRNA *cont = cont_;
4142   PropertyRNA *prop;
4143 
4144   prop = RNA_def_property(cont, identifier, PROP_POINTER, PROP_NONE);
4145   RNA_def_property_struct_runtime(prop, type);
4146   if ((type->flag & STRUCT_ID) != 0) {
4147     prop->flag |= PROP_EDITABLE;
4148   }
4149   RNA_def_property_ui_text(prop, ui_name, ui_description);
4150 
4151   return prop;
4152 }
4153 
RNA_def_collection(StructOrFunctionRNA * cont_,const char * identifier,const char * type,const char * ui_name,const char * ui_description)4154 PropertyRNA *RNA_def_collection(StructOrFunctionRNA *cont_,
4155                                 const char *identifier,
4156                                 const char *type,
4157                                 const char *ui_name,
4158                                 const char *ui_description)
4159 {
4160   ContainerRNA *cont = cont_;
4161   PropertyRNA *prop;
4162 
4163   prop = RNA_def_property(cont, identifier, PROP_COLLECTION, PROP_NONE);
4164   RNA_def_property_struct_type(prop, type);
4165   RNA_def_property_ui_text(prop, ui_name, ui_description);
4166 
4167   return prop;
4168 }
4169 
RNA_def_collection_runtime(StructOrFunctionRNA * cont_,const char * identifier,StructRNA * type,const char * ui_name,const char * ui_description)4170 PropertyRNA *RNA_def_collection_runtime(StructOrFunctionRNA *cont_,
4171                                         const char *identifier,
4172                                         StructRNA *type,
4173                                         const char *ui_name,
4174                                         const char *ui_description)
4175 {
4176   ContainerRNA *cont = cont_;
4177   PropertyRNA *prop;
4178 
4179   prop = RNA_def_property(cont, identifier, PROP_COLLECTION, PROP_NONE);
4180   RNA_def_property_struct_runtime(prop, type);
4181   RNA_def_property_ui_text(prop, ui_name, ui_description);
4182 
4183   return prop;
4184 }
4185 
4186 /* Function */
4187 
rna_def_function(StructRNA * srna,const char * identifier)4188 static FunctionRNA *rna_def_function(StructRNA *srna, const char *identifier)
4189 {
4190   FunctionRNA *func;
4191   StructDefRNA *dsrna;
4192   FunctionDefRNA *dfunc;
4193 
4194   if (DefRNA.preprocess) {
4195     char error[512];
4196 
4197     if (rna_validate_identifier(identifier, error, false) == 0) {
4198       CLOG_ERROR(&LOG, "function identifier \"%s\" - %s", identifier, error);
4199       DefRNA.error = true;
4200     }
4201   }
4202 
4203   func = MEM_callocN(sizeof(FunctionRNA), "FunctionRNA");
4204   func->identifier = identifier;
4205   func->description = identifier;
4206 
4207   rna_addtail(&srna->functions, func);
4208 
4209   if (DefRNA.preprocess) {
4210     dsrna = rna_find_struct_def(srna);
4211     dfunc = MEM_callocN(sizeof(FunctionDefRNA), "FunctionDefRNA");
4212     rna_addtail(&dsrna->functions, dfunc);
4213     dfunc->func = func;
4214   }
4215   else {
4216     func->flag |= FUNC_RUNTIME;
4217   }
4218 
4219   return func;
4220 }
4221 
RNA_def_function(StructRNA * srna,const char * identifier,const char * call)4222 FunctionRNA *RNA_def_function(StructRNA *srna, const char *identifier, const char *call)
4223 {
4224   FunctionRNA *func;
4225   FunctionDefRNA *dfunc;
4226 
4227   if (BLI_findstring_ptr(&srna->functions, identifier, offsetof(FunctionRNA, identifier))) {
4228     CLOG_ERROR(&LOG, "%s.%s already defined.", srna->identifier, identifier);
4229     return NULL;
4230   }
4231 
4232   func = rna_def_function(srna, identifier);
4233 
4234   if (!DefRNA.preprocess) {
4235     CLOG_ERROR(&LOG, "only at preprocess time.");
4236     return func;
4237   }
4238 
4239   dfunc = rna_find_function_def(func);
4240   dfunc->call = call;
4241 
4242   return func;
4243 }
4244 
RNA_def_function_runtime(StructRNA * srna,const char * identifier,CallFunc call)4245 FunctionRNA *RNA_def_function_runtime(StructRNA *srna, const char *identifier, CallFunc call)
4246 {
4247   FunctionRNA *func;
4248 
4249   func = rna_def_function(srna, identifier);
4250 
4251   if (DefRNA.preprocess) {
4252     CLOG_ERROR(&LOG, "only at runtime.");
4253     return func;
4254   }
4255 
4256   func->call = call;
4257 
4258   return func;
4259 }
4260 
4261 /* C return value only!, multiple RNA returns can be done with RNA_def_function_output */
RNA_def_function_return(FunctionRNA * func,PropertyRNA * ret)4262 void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret)
4263 {
4264   if (ret->flag & PROP_DYNAMIC) {
4265     CLOG_ERROR(&LOG,
4266                "\"%s.%s\", dynamic values are not allowed as strict returns, "
4267                "use RNA_def_function_output instead.",
4268                func->identifier,
4269                ret->identifier);
4270     return;
4271   }
4272   if (ret->arraydimension) {
4273     CLOG_ERROR(&LOG,
4274                "\"%s.%s\", arrays are not allowed as strict returns, "
4275                "use RNA_def_function_output instead.",
4276                func->identifier,
4277                ret->identifier);
4278     return;
4279   }
4280 
4281   BLI_assert(func->c_ret == NULL);
4282   func->c_ret = ret;
4283 
4284   RNA_def_function_output(func, ret);
4285 }
4286 
RNA_def_function_output(FunctionRNA * UNUSED (func),PropertyRNA * ret)4287 void RNA_def_function_output(FunctionRNA *UNUSED(func), PropertyRNA *ret)
4288 {
4289   ret->flag_parameter |= PARM_OUTPUT;
4290 }
4291 
RNA_def_function_flag(FunctionRNA * func,int flag)4292 void RNA_def_function_flag(FunctionRNA *func, int flag)
4293 {
4294   func->flag |= flag;
4295 }
4296 
RNA_def_function_ui_description(FunctionRNA * func,const char * description)4297 void RNA_def_function_ui_description(FunctionRNA *func, const char *description)
4298 {
4299   func->description = description;
4300 }
4301 
rna_parameter_size(PropertyRNA * parm)4302 int rna_parameter_size(PropertyRNA *parm)
4303 {
4304   PropertyType ptype = parm->type;
4305   int len = parm->totarraylength;
4306 
4307   /* XXX in other parts is mentioned that strings can be dynamic as well */
4308   if (parm->flag & PROP_DYNAMIC) {
4309     return sizeof(ParameterDynAlloc);
4310   }
4311 
4312   if (len > 0) {
4313     switch (ptype) {
4314       case PROP_BOOLEAN:
4315         return sizeof(bool) * len;
4316       case PROP_INT:
4317         return sizeof(int) * len;
4318       case PROP_FLOAT:
4319         return sizeof(float) * len;
4320       default:
4321         break;
4322     }
4323   }
4324   else {
4325     switch (ptype) {
4326       case PROP_BOOLEAN:
4327         return sizeof(bool);
4328       case PROP_INT:
4329       case PROP_ENUM:
4330         return sizeof(int);
4331       case PROP_FLOAT:
4332         return sizeof(float);
4333       case PROP_STRING:
4334         /* return values don't store a pointer to the original */
4335         if (parm->flag & PROP_THICK_WRAP) {
4336           StringPropertyRNA *sparm = (StringPropertyRNA *)parm;
4337           return sizeof(char) * sparm->maxlength;
4338         }
4339         else {
4340           return sizeof(char *);
4341         }
4342       case PROP_POINTER: {
4343 #ifdef RNA_RUNTIME
4344         if (parm->flag_parameter & PARM_RNAPTR) {
4345           if (parm->flag & PROP_THICK_WRAP) {
4346             return sizeof(PointerRNA);
4347           }
4348           else {
4349             return sizeof(PointerRNA *);
4350           }
4351         }
4352         else {
4353           return sizeof(void *);
4354         }
4355 #else
4356         if (parm->flag_parameter & PARM_RNAPTR) {
4357           if (parm->flag & PROP_THICK_WRAP) {
4358             return sizeof(PointerRNA);
4359           }
4360           return sizeof(PointerRNA *);
4361         }
4362         else {
4363           return sizeof(void *);
4364         }
4365 #endif
4366       }
4367       case PROP_COLLECTION:
4368         return sizeof(ListBase);
4369     }
4370   }
4371 
4372   return sizeof(void *);
4373 }
4374 
4375 /* Dynamic Enums */
4376 
RNA_enum_item_add(EnumPropertyItem ** items,int * totitem,const EnumPropertyItem * item)4377 void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
4378 {
4379   int tot = *totitem;
4380 
4381   if (tot == 0) {
4382     *items = MEM_callocN(sizeof(EnumPropertyItem[8]), __func__);
4383   }
4384   else if (tot >= 8 && (tot & (tot - 1)) == 0) {
4385     /* power of two > 8 */
4386     *items = MEM_recallocN_id(*items, sizeof(EnumPropertyItem) * tot * 2, __func__);
4387   }
4388 
4389   (*items)[tot] = *item;
4390   *totitem = tot + 1;
4391 
4392   /* Ensure we get crashes on missing calls to 'RNA_enum_item_end', see T74227. */
4393 #ifdef DEBUG
4394   static const EnumPropertyItem item_error = {
4395       -1, POINTER_FROM_INT(-1), -1, POINTER_FROM_INT(-1), POINTER_FROM_INT(-1)};
4396   if (item != &item_error) {
4397     RNA_enum_item_add(items, totitem, &item_error);
4398     *totitem -= 1;
4399   }
4400 #endif
4401 }
4402 
RNA_enum_item_add_separator(EnumPropertyItem ** items,int * totitem)4403 void RNA_enum_item_add_separator(EnumPropertyItem **items, int *totitem)
4404 {
4405   static const EnumPropertyItem sepr = {0, "", 0, NULL, NULL};
4406   RNA_enum_item_add(items, totitem, &sepr);
4407 }
4408 
RNA_enum_items_add(EnumPropertyItem ** items,int * totitem,const EnumPropertyItem * item)4409 void RNA_enum_items_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
4410 {
4411   for (; item->identifier; item++) {
4412     RNA_enum_item_add(items, totitem, item);
4413   }
4414 }
4415 
RNA_enum_items_add_value(EnumPropertyItem ** items,int * totitem,const EnumPropertyItem * item,int value)4416 void RNA_enum_items_add_value(EnumPropertyItem **items,
4417                               int *totitem,
4418                               const EnumPropertyItem *item,
4419                               int value)
4420 {
4421   for (; item->identifier; item++) {
4422     if (item->value == value) {
4423       RNA_enum_item_add(items, totitem, item);
4424       /* break on first match - does this break anything?
4425        * (is quick hack to get object->parent_type working ok for armature/lattice) */
4426       break;
4427     }
4428   }
4429 }
4430 
RNA_enum_item_end(EnumPropertyItem ** items,int * totitem)4431 void RNA_enum_item_end(EnumPropertyItem **items, int *totitem)
4432 {
4433   static const EnumPropertyItem empty = {0, NULL, 0, NULL, NULL};
4434   RNA_enum_item_add(items, totitem, &empty);
4435 }
4436 
4437 /* Memory management */
4438 
4439 #ifdef RNA_RUNTIME
RNA_def_struct_duplicate_pointers(BlenderRNA * brna,StructRNA * srna)4440 void RNA_def_struct_duplicate_pointers(BlenderRNA *brna, StructRNA *srna)
4441 {
4442   if (srna->identifier) {
4443     srna->identifier = BLI_strdup(srna->identifier);
4444     if (srna->flag & STRUCT_PUBLIC_NAMESPACE) {
4445       BLI_ghash_replace_key(brna->structs_map, (void *)srna->identifier);
4446     }
4447   }
4448   if (srna->name) {
4449     srna->name = BLI_strdup(srna->name);
4450   }
4451   if (srna->description) {
4452     srna->description = BLI_strdup(srna->description);
4453   }
4454 
4455   srna->flag |= STRUCT_FREE_POINTERS;
4456 }
4457 
RNA_def_struct_free_pointers(BlenderRNA * brna,StructRNA * srna)4458 void RNA_def_struct_free_pointers(BlenderRNA *brna, StructRNA *srna)
4459 {
4460   if (srna->flag & STRUCT_FREE_POINTERS) {
4461     if (srna->identifier) {
4462       if (srna->flag & STRUCT_PUBLIC_NAMESPACE) {
4463         if (brna != NULL) {
4464           BLI_ghash_remove(brna->structs_map, (void *)srna->identifier, NULL, NULL);
4465         }
4466       }
4467       MEM_freeN((void *)srna->identifier);
4468     }
4469     if (srna->name) {
4470       MEM_freeN((void *)srna->name);
4471     }
4472     if (srna->description) {
4473       MEM_freeN((void *)srna->description);
4474     }
4475   }
4476 }
4477 
RNA_def_func_duplicate_pointers(FunctionRNA * func)4478 void RNA_def_func_duplicate_pointers(FunctionRNA *func)
4479 {
4480   if (func->identifier) {
4481     func->identifier = BLI_strdup(func->identifier);
4482   }
4483   if (func->description) {
4484     func->description = BLI_strdup(func->description);
4485   }
4486 
4487   func->flag |= FUNC_FREE_POINTERS;
4488 }
4489 
RNA_def_func_free_pointers(FunctionRNA * func)4490 void RNA_def_func_free_pointers(FunctionRNA *func)
4491 {
4492   if (func->flag & FUNC_FREE_POINTERS) {
4493     if (func->identifier) {
4494       MEM_freeN((void *)func->identifier);
4495     }
4496     if (func->description) {
4497       MEM_freeN((void *)func->description);
4498     }
4499   }
4500 }
4501 
RNA_def_property_duplicate_pointers(StructOrFunctionRNA * cont_,PropertyRNA * prop)4502 void RNA_def_property_duplicate_pointers(StructOrFunctionRNA *cont_, PropertyRNA *prop)
4503 {
4504   ContainerRNA *cont = cont_;
4505   int a;
4506 
4507   /* annoying since we just added this to a hash, could make this add the correct key to the hash
4508    * in the first place */
4509   if (prop->identifier) {
4510     if (cont->prophash) {
4511       prop->identifier = BLI_strdup(prop->identifier);
4512       BLI_ghash_reinsert(cont->prophash, (void *)prop->identifier, prop, NULL, NULL);
4513     }
4514     else {
4515       prop->identifier = BLI_strdup(prop->identifier);
4516     }
4517   }
4518 
4519   if (prop->name) {
4520     prop->name = BLI_strdup(prop->name);
4521   }
4522   if (prop->description) {
4523     prop->description = BLI_strdup(prop->description);
4524   }
4525 
4526   switch (prop->type) {
4527     case PROP_BOOLEAN: {
4528       BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
4529 
4530       if (bprop->defaultarray) {
4531         bool *array = MEM_mallocN(sizeof(bool) * prop->totarraylength, "RNA_def_property_store");
4532         memcpy(array, bprop->defaultarray, sizeof(bool) * prop->totarraylength);
4533         bprop->defaultarray = array;
4534       }
4535       break;
4536     }
4537     case PROP_INT: {
4538       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
4539 
4540       if (iprop->defaultarray) {
4541         int *array = MEM_mallocN(sizeof(int) * prop->totarraylength, "RNA_def_property_store");
4542         memcpy(array, iprop->defaultarray, sizeof(int) * prop->totarraylength);
4543         iprop->defaultarray = array;
4544       }
4545       break;
4546     }
4547     case PROP_ENUM: {
4548       EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
4549 
4550       if (eprop->item) {
4551         EnumPropertyItem *array = MEM_mallocN(sizeof(EnumPropertyItem) * (eprop->totitem + 1),
4552                                               "RNA_def_property_store");
4553         memcpy(array, eprop->item, sizeof(EnumPropertyItem) * (eprop->totitem + 1));
4554         eprop->item = array;
4555 
4556         for (a = 0; a < eprop->totitem; a++) {
4557           if (array[a].identifier) {
4558             array[a].identifier = BLI_strdup(array[a].identifier);
4559           }
4560           if (array[a].name) {
4561             array[a].name = BLI_strdup(array[a].name);
4562           }
4563           if (array[a].description) {
4564             array[a].description = BLI_strdup(array[a].description);
4565           }
4566         }
4567       }
4568       break;
4569     }
4570     case PROP_FLOAT: {
4571       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
4572 
4573       if (fprop->defaultarray) {
4574         float *array = MEM_mallocN(sizeof(float) * prop->totarraylength, "RNA_def_property_store");
4575         memcpy(array, fprop->defaultarray, sizeof(float) * prop->totarraylength);
4576         fprop->defaultarray = array;
4577       }
4578       break;
4579     }
4580     case PROP_STRING: {
4581       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
4582       if (sprop->defaultvalue) {
4583         sprop->defaultvalue = BLI_strdup(sprop->defaultvalue);
4584       }
4585       break;
4586     }
4587     default:
4588       break;
4589   }
4590 
4591   prop->flag_internal |= PROP_INTERN_FREE_POINTERS;
4592 }
4593 
RNA_def_property_free_pointers(PropertyRNA * prop)4594 void RNA_def_property_free_pointers(PropertyRNA *prop)
4595 {
4596   if (prop->flag_internal & PROP_INTERN_FREE_POINTERS) {
4597     int a;
4598 
4599     if (prop->identifier) {
4600       MEM_freeN((void *)prop->identifier);
4601     }
4602     if (prop->name) {
4603       MEM_freeN((void *)prop->name);
4604     }
4605     if (prop->description) {
4606       MEM_freeN((void *)prop->description);
4607     }
4608     if (prop->py_data) {
4609       MEM_freeN(prop->py_data);
4610     }
4611 
4612     switch (prop->type) {
4613       case PROP_BOOLEAN: {
4614         BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
4615         if (bprop->defaultarray) {
4616           MEM_freeN((void *)bprop->defaultarray);
4617         }
4618         break;
4619       }
4620       case PROP_INT: {
4621         IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
4622         if (iprop->defaultarray) {
4623           MEM_freeN((void *)iprop->defaultarray);
4624         }
4625         break;
4626       }
4627       case PROP_FLOAT: {
4628         FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
4629         if (fprop->defaultarray) {
4630           MEM_freeN((void *)fprop->defaultarray);
4631         }
4632         break;
4633       }
4634       case PROP_ENUM: {
4635         EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
4636 
4637         for (a = 0; a < eprop->totitem; a++) {
4638           if (eprop->item[a].identifier) {
4639             MEM_freeN((void *)eprop->item[a].identifier);
4640           }
4641           if (eprop->item[a].name) {
4642             MEM_freeN((void *)eprop->item[a].name);
4643           }
4644           if (eprop->item[a].description) {
4645             MEM_freeN((void *)eprop->item[a].description);
4646           }
4647         }
4648 
4649         if (eprop->item) {
4650           MEM_freeN((void *)eprop->item);
4651         }
4652         break;
4653       }
4654       case PROP_STRING: {
4655         StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
4656         if (sprop->defaultvalue) {
4657           MEM_freeN((void *)sprop->defaultvalue);
4658         }
4659         break;
4660       }
4661       default:
4662         break;
4663     }
4664   }
4665 }
4666 
rna_def_property_free(StructOrFunctionRNA * cont_,PropertyRNA * prop)4667 static void rna_def_property_free(StructOrFunctionRNA *cont_, PropertyRNA *prop)
4668 {
4669   ContainerRNA *cont = cont_;
4670 
4671   if (prop->flag_internal & PROP_INTERN_RUNTIME) {
4672     if (cont->prophash) {
4673       BLI_ghash_remove(cont->prophash, prop->identifier, NULL, NULL);
4674     }
4675 
4676     RNA_def_property_free_pointers(prop);
4677     rna_freelinkN(&cont->properties, prop);
4678   }
4679   else {
4680     RNA_def_property_free_pointers(prop);
4681   }
4682 }
4683 
4684 /* note: only intended for removing dynamic props */
RNA_def_property_free_identifier(StructOrFunctionRNA * cont_,const char * identifier)4685 int RNA_def_property_free_identifier(StructOrFunctionRNA *cont_, const char *identifier)
4686 {
4687   ContainerRNA *cont = cont_;
4688   PropertyRNA *prop;
4689 
4690   for (prop = cont->properties.first; prop; prop = prop->next) {
4691     if (STREQ(prop->identifier, identifier)) {
4692       if (prop->flag_internal & PROP_INTERN_RUNTIME) {
4693         rna_def_property_free(cont_, prop);
4694         return 1;
4695       }
4696       else {
4697         return -1;
4698       }
4699     }
4700   }
4701   return 0;
4702 }
4703 #endif /* RNA_RUNTIME */
4704 
RNA_property_typename(PropertyType type)4705 const char *RNA_property_typename(PropertyType type)
4706 {
4707   switch (type) {
4708     case PROP_BOOLEAN:
4709       return "PROP_BOOLEAN";
4710     case PROP_INT:
4711       return "PROP_INT";
4712     case PROP_FLOAT:
4713       return "PROP_FLOAT";
4714     case PROP_STRING:
4715       return "PROP_STRING";
4716     case PROP_ENUM:
4717       return "PROP_ENUM";
4718     case PROP_POINTER:
4719       return "PROP_POINTER";
4720     case PROP_COLLECTION:
4721       return "PROP_COLLECTION";
4722   }
4723 
4724   return "PROP_UNKNOWN";
4725 }
4726