20fbbed572cb0ca616f3fdf1b09eb305d198418f
[blender.git] / source / blender / makesrna / intern / rna_define.c
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 <float.h>
22 #include <limits.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <stddef.h>
26 #include <string.h>
27 #include <ctype.h>
28
29 #include "BLI_utildefines.h"
30 #include "MEM_guardedalloc.h"
31
32 #include "DNA_genfile.h"
33 #include "DNA_sdna_types.h"
34
35 #include "BLI_listbase.h"
36 #include "BLI_ghash.h"
37
38 #include "BLT_translation.h"
39
40 #include "UI_interface.h" /* For things like UI_PRECISION_FLOAT_MAX... */
41
42 #include "RNA_define.h"
43
44 #include "rna_internal.h"
45
46 #include "CLG_log.h"
47
48 static CLG_LogRef LOG = {"rna.define"};
49
50 #ifdef DEBUG
51 #  define ASSERT_SOFT_HARD_LIMITS \
52     if (softmin < hardmin || softmax > hardmax) { \
53       CLOG_ERROR(&LOG, "error with soft/hard limits: %s.%s", CONTAINER_RNA_ID(cont), identifier); \
54       BLI_assert(!"invalid soft/hard limits"); \
55     } \
56     (void)0
57 #else
58 #  define ASSERT_SOFT_HARD_LIMITS (void)0
59 #endif
60
61 /* Global used during defining */
62
63 BlenderDefRNA DefRNA = {NULL, {NULL, NULL}, {NULL, NULL}, NULL, 0, 0, 0, 1, 1};
64
65 #ifndef RNA_RUNTIME
66 static struct {
67   GHash *struct_map_static_from_alias;
68 } g_version_data;
69 #endif
70
71 /* Duplicated code since we can't link in blenkernel or blenlib */
72
73 /* pedantic check for final '.', note '...' are allowed though. */
74 #ifndef NDEBUG
75 #  define DESCR_CHECK(description, id1, id2) \
76     if (description && (description)[0]) { \
77       int i = strlen(description); \
78       if (i > 3 && (description)[i - 1] == '.' && (description)[i - 3] != '.') { \
79         CLOG_WARN(&LOG, \
80                   "'%s' description from '%s' '%s' ends with a '.' !", \
81                   description, \
82                   id1 ? id1 : "", \
83                   id2 ? id2 : ""); \
84       } \
85     } \
86     (void)0
87
88 #else
89 #  define DESCR_CHECK(description, id1, id2)
90 #endif
91
92 void rna_addtail(ListBase *listbase, void *vlink)
93 {
94   Link *link = vlink;
95
96   link->next = NULL;
97   link->prev = listbase->last;
98
99   if (listbase->last) {
100     ((Link *)listbase->last)->next = link;
101   }
102   if (listbase->first == NULL) {
103     listbase->first = link;
104   }
105   listbase->last = link;
106 }
107
108 static void rna_remlink(ListBase *listbase, void *vlink)
109 {
110   Link *link = vlink;
111
112   if (link->next) {
113     link->next->prev = link->prev;
114   }
115   if (link->prev) {
116     link->prev->next = link->next;
117   }
118
119   if (listbase->last == link) {
120     listbase->last = link->prev;
121   }
122   if (listbase->first == link) {
123     listbase->first = link->next;
124   }
125 }
126
127 PropertyDefRNA *rna_findlink(ListBase *listbase, const char *identifier)
128 {
129   Link *link;
130
131   for (link = listbase->first; link; link = link->next) {
132     PropertyRNA *prop = ((PropertyDefRNA *)link)->prop;
133     if (prop && (STREQ(prop->identifier, identifier))) {
134       return (PropertyDefRNA *)link;
135     }
136   }
137
138   return NULL;
139 }
140
141 void rna_freelinkN(ListBase *listbase, void *vlink)
142 {
143   rna_remlink(listbase, vlink);
144   MEM_freeN(vlink);
145 }
146
147 void rna_freelistN(ListBase *listbase)
148 {
149   Link *link, *next;
150
151   for (link = listbase->first; link; link = next) {
152     next = link->next;
153     MEM_freeN(link);
154   }
155
156   listbase->first = listbase->last = NULL;
157 }
158
159 static void rna_brna_structs_add(BlenderRNA *brna, StructRNA *srna)
160 {
161   rna_addtail(&brna->structs, srna);
162   brna->structs_len += 1;
163
164   /* This exception is only needed for pre-processing.
165    * otherwise we don't allow empty names. */
166   if ((srna->flag & STRUCT_PUBLIC_NAMESPACE) && (srna->identifier[0] != '\0')) {
167     BLI_ghash_insert(brna->structs_map, (void *)srna->identifier, srna);
168   }
169 }
170
171 #ifdef RNA_RUNTIME
172 static void rna_brna_structs_remove_and_free(BlenderRNA *brna, StructRNA *srna)
173 {
174   if ((srna->flag & STRUCT_PUBLIC_NAMESPACE) && brna->structs_map) {
175     if (srna->identifier[0] != '\0') {
176       BLI_ghash_remove(brna->structs_map, (void *)srna->identifier, NULL, NULL);
177     }
178   }
179
180   RNA_def_struct_free_pointers(NULL, srna);
181
182   if (srna->flag & STRUCT_RUNTIME) {
183     rna_freelinkN(&brna->structs, srna);
184   }
185   brna->structs_len -= 1;
186 }
187 #endif
188
189 static int DNA_struct_find_nr_wrapper(const struct SDNA *sdna, const char *struct_name)
190 {
191   struct_name = DNA_struct_rename_legacy_hack_static_from_alias(struct_name);
192 #ifdef RNA_RUNTIME
193   /* We may support this at some point but for now we don't. */
194   BLI_assert(0);
195 #else
196   struct_name = BLI_ghash_lookup_default(
197       g_version_data.struct_map_static_from_alias, struct_name, (void *)struct_name);
198 #endif
199   return DNA_struct_find_nr(sdna, struct_name);
200 }
201
202 StructDefRNA *rna_find_struct_def(StructRNA *srna)
203 {
204   StructDefRNA *dsrna;
205
206   if (!DefRNA.preprocess) {
207     /* we should never get here */
208     CLOG_ERROR(&LOG, "only at preprocess time.");
209     return NULL;
210   }
211
212   dsrna = DefRNA.structs.last;
213   for (; dsrna; dsrna = dsrna->cont.prev) {
214     if (dsrna->srna == srna) {
215       return dsrna;
216     }
217   }
218
219   return NULL;
220 }
221
222 PropertyDefRNA *rna_find_struct_property_def(StructRNA *srna, PropertyRNA *prop)
223 {
224   StructDefRNA *dsrna;
225   PropertyDefRNA *dprop;
226
227   if (!DefRNA.preprocess) {
228     /* we should never get here */
229     CLOG_ERROR(&LOG, "only at preprocess time.");
230     return NULL;
231   }
232
233   dsrna = rna_find_struct_def(srna);
234   dprop = dsrna->cont.properties.last;
235   for (; dprop; dprop = dprop->prev) {
236     if (dprop->prop == prop) {
237       return dprop;
238     }
239   }
240
241   dsrna = DefRNA.structs.last;
242   for (; dsrna; dsrna = dsrna->cont.prev) {
243     dprop = dsrna->cont.properties.last;
244     for (; dprop; dprop = dprop->prev) {
245       if (dprop->prop == prop) {
246         return dprop;
247       }
248     }
249   }
250
251   return NULL;
252 }
253
254 #if 0
255 static PropertyDefRNA *rna_find_property_def(PropertyRNA *prop)
256 {
257   PropertyDefRNA *dprop;
258
259   if (!DefRNA.preprocess) {
260     /* we should never get here */
261     CLOG_ERROR(&LOG, "only at preprocess time.");
262     return NULL;
263   }
264
265   dprop = rna_find_struct_property_def(DefRNA.laststruct, prop);
266   if (dprop)
267     return dprop;
268
269   dprop = rna_find_parameter_def(prop);
270   if (dprop)
271     return dprop;
272
273   return NULL;
274 }
275 #endif
276
277 FunctionDefRNA *rna_find_function_def(FunctionRNA *func)
278 {
279   StructDefRNA *dsrna;
280   FunctionDefRNA *dfunc;
281
282   if (!DefRNA.preprocess) {
283     /* we should never get here */
284     CLOG_ERROR(&LOG, "only at preprocess time.");
285     return NULL;
286   }
287
288   dsrna = rna_find_struct_def(DefRNA.laststruct);
289   dfunc = dsrna->functions.last;
290   for (; dfunc; dfunc = dfunc->cont.prev) {
291     if (dfunc->func == func) {
292       return dfunc;
293     }
294   }
295
296   dsrna = DefRNA.structs.last;
297   for (; dsrna; dsrna = dsrna->cont.prev) {
298     dfunc = dsrna->functions.last;
299     for (; dfunc; dfunc = dfunc->cont.prev) {
300       if (dfunc->func == func) {
301         return dfunc;
302       }
303     }
304   }
305
306   return NULL;
307 }
308
309 PropertyDefRNA *rna_find_parameter_def(PropertyRNA *parm)
310 {
311   StructDefRNA *dsrna;
312   FunctionDefRNA *dfunc;
313   PropertyDefRNA *dparm;
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     dparm = dfunc->cont.properties.last;
325     for (; dparm; dparm = dparm->prev) {
326       if (dparm->prop == parm) {
327         return dparm;
328       }
329     }
330   }
331
332   dsrna = DefRNA.structs.last;
333   for (; dsrna; dsrna = dsrna->cont.prev) {
334     dfunc = dsrna->functions.last;
335     for (; dfunc; dfunc = dfunc->cont.prev) {
336       dparm = dfunc->cont.properties.last;
337       for (; dparm; dparm = dparm->prev) {
338         if (dparm->prop == parm) {
339           return dparm;
340         }
341       }
342     }
343   }
344
345   return NULL;
346 }
347
348 static ContainerDefRNA *rna_find_container_def(ContainerRNA *cont)
349 {
350   StructDefRNA *ds;
351   FunctionDefRNA *dfunc;
352
353   if (!DefRNA.preprocess) {
354     /* we should never get here */
355     CLOG_ERROR(&LOG, "only at preprocess time.");
356     return NULL;
357   }
358
359   ds = rna_find_struct_def((StructRNA *)cont);
360   if (ds) {
361     return &ds->cont;
362   }
363
364   dfunc = rna_find_function_def((FunctionRNA *)cont);
365   if (dfunc) {
366     return &dfunc->cont;
367   }
368
369   return NULL;
370 }
371
372 /* DNA utility function for looking up members */
373
374 typedef struct DNAStructMember {
375   const char *type;
376   const char *name;
377   int arraylength;
378   int pointerlevel;
379 } DNAStructMember;
380
381 static int rna_member_cmp(const char *name, const char *oname)
382 {
383   int a = 0;
384
385   /* compare without pointer or array part */
386   while (name[0] == '*') {
387     name++;
388   }
389   while (oname[0] == '*') {
390     oname++;
391   }
392
393   while (1) {
394     if (name[a] == '[' && oname[a] == 0) {
395       return 1;
396     }
397     if (name[a] == '[' && oname[a] == '[') {
398       return 1;
399     }
400     if (name[a] == 0) {
401       break;
402     }
403     if (name[a] != oname[a]) {
404       return 0;
405     }
406     a++;
407   }
408   if (name[a] == 0 && oname[a] == '.') {
409     return 2;
410   }
411   if (name[a] == 0 && oname[a] == '-' && oname[a + 1] == '>') {
412     return 3;
413   }
414
415   return (name[a] == oname[a]);
416 }
417
418 static int rna_find_sdna_member(SDNA *sdna,
419                                 const char *structname,
420                                 const char *membername,
421                                 DNAStructMember *smember)
422 {
423   const char *dnaname;
424   const short *sp;
425   int a, b, structnr, totmember, cmp;
426
427   if (!DefRNA.preprocess) {
428     CLOG_ERROR(&LOG, "only during preprocessing.");
429     return 0;
430   }
431   structnr = DNA_struct_find_nr_wrapper(sdna, structname);
432
433   if (structnr == -1) {
434     return 0;
435   }
436
437   sp = sdna->structs[structnr];
438   totmember = sp[1];
439   sp += 2;
440
441   for (a = 0; a < totmember; a++, sp += 2) {
442     dnaname = sdna->alias.names[sp[1]];
443     cmp = rna_member_cmp(dnaname, membername);
444
445     if (cmp == 1) {
446       smember->type = sdna->alias.types[sp[0]];
447       smember->name = dnaname;
448
449       if (strstr(membername, "[")) {
450         smember->arraylength = 0;
451       }
452       else {
453         smember->arraylength = DNA_elem_array_size(smember->name);
454       }
455
456       smember->pointerlevel = 0;
457       for (b = 0; dnaname[b] == '*'; b++) {
458         smember->pointerlevel++;
459       }
460
461       return 1;
462     }
463     else if (cmp == 2) {
464       smember->type = "";
465       smember->name = dnaname;
466       smember->pointerlevel = 0;
467       smember->arraylength = 0;
468
469       membername = strstr(membername, ".") + strlen(".");
470       rna_find_sdna_member(sdna, sdna->alias.types[sp[0]], membername, smember);
471
472       return 1;
473     }
474     else if (cmp == 3) {
475       smember->type = "";
476       smember->name = dnaname;
477       smember->pointerlevel = 0;
478       smember->arraylength = 0;
479
480       membername = strstr(membername, "->") + strlen("->");
481       rna_find_sdna_member(sdna, sdna->alias.types[sp[0]], membername, smember);
482
483       return 1;
484     }
485   }
486
487   return 0;
488 }
489
490 static int rna_validate_identifier(const char *identifier, char *error, bool property)
491 {
492   int a = 0;
493
494   /** List is from:
495    * \code{.py}
496    * ", ".join([
497    *     '"%s"' % kw for kw in __import__("keyword").kwlist
498    *     if kw not in {"False", "None", "True"}
499    * ])
500    * \endcode
501    */
502   static const char *kwlist[] = {
503       /* "False", "None", "True", */
504       "and",    "as",   "assert", "async",  "await",    "break", "class", "continue", "def",
505       "del",    "elif", "else",   "except", "finally",  "for",   "from",  "global",   "if",
506       "import", "in",   "is",     "lambda", "nonlocal", "not",   "or",    "pass",     "raise",
507       "return", "try",  "while",  "with",   "yield",    NULL,
508   };
509
510   if (!isalpha(identifier[0])) {
511     strcpy(error, "first character failed isalpha() check");
512     return 0;
513   }
514
515   for (a = 0; identifier[a]; a++) {
516     if (DefRNA.preprocess && property) {
517       if (isalpha(identifier[a]) && isupper(identifier[a])) {
518         strcpy(error, "property names must contain lower case characters only");
519         return 0;
520       }
521     }
522
523     if (identifier[a] == '_') {
524       continue;
525     }
526
527     if (identifier[a] == ' ') {
528       strcpy(error, "spaces are not okay in identifier names");
529       return 0;
530     }
531
532     if (isalnum(identifier[a]) == 0) {
533       strcpy(error, "one of the characters failed an isalnum() check and is not an underscore");
534       return 0;
535     }
536   }
537
538   for (a = 0; kwlist[a]; a++) {
539     if (STREQ(identifier, kwlist[a])) {
540       strcpy(error, "this keyword is reserved by python");
541       return 0;
542     }
543   }
544
545   if (property) {
546     static const char *kwlist_prop[] = {
547         /* not keywords but reserved all the same because py uses */
548         "keys",
549         "values",
550         "items",
551         "get",
552         NULL,
553     };
554
555     for (a = 0; kwlist_prop[a]; a++) {
556       if (STREQ(identifier, kwlist_prop[a])) {
557         strcpy(error, "this keyword is reserved by python");
558         return 0;
559       }
560     }
561   }
562
563   return 1;
564 }
565
566 void RNA_identifier_sanitize(char *identifier, int property)
567 {
568   int a = 0;
569
570   /*  list from http://docs.python.org/py3k/reference/lexical_analysis.html#keywords */
571   static const char *kwlist[] = {
572       /* "False", "None", "True", */
573       "and",    "as",     "assert", "break",   "class",    "continue", "def",    "del",
574       "elif",   "else",   "except", "finally", "for",      "from",     "global", "if",
575       "import", "in",     "is",     "lambda",  "nonlocal", "not",      "or",     "pass",
576       "raise",  "return", "try",    "while",   "with",     "yield",    NULL,
577   };
578
579   if (!isalpha(identifier[0])) {
580     /* first character failed isalpha() check */
581     identifier[0] = '_';
582   }
583
584   for (a = 0; identifier[a]; a++) {
585     if (DefRNA.preprocess && property) {
586       if (isalpha(identifier[a]) && isupper(identifier[a])) {
587         /* property names must contain lower case characters only */
588         identifier[a] = tolower(identifier[a]);
589       }
590     }
591
592     if (identifier[a] == '_') {
593       continue;
594     }
595
596     if (identifier[a] == ' ') {
597       /* spaces are not okay in identifier names */
598       identifier[a] = '_';
599     }
600
601     if (isalnum(identifier[a]) == 0) {
602       /* one of the characters failed an isalnum() check and is not an underscore */
603       identifier[a] = '_';
604     }
605   }
606
607   for (a = 0; kwlist[a]; a++) {
608     if (STREQ(identifier, kwlist[a])) {
609       /* this keyword is reserved by python.
610        * just replace the last character by '_' to keep it readable.
611        */
612       identifier[strlen(identifier) - 1] = '_';
613       break;
614     }
615   }
616
617   if (property) {
618     static const char *kwlist_prop[] = {
619         /* not keywords but reserved all the same because py uses */
620         "keys",
621         "values",
622         "items",
623         "get",
624         NULL,
625     };
626
627     for (a = 0; kwlist_prop[a]; a++) {
628       if (STREQ(identifier, kwlist_prop[a])) {
629         /* this keyword is reserved by python.
630          * just replace the last character by '_' to keep it readable.
631          */
632         identifier[strlen(identifier) - 1] = '_';
633         break;
634       }
635     }
636   }
637 }
638
639 /* Blender Data Definition */
640
641 BlenderRNA *RNA_create(void)
642 {
643   BlenderRNA *brna;
644
645   brna = MEM_callocN(sizeof(BlenderRNA), "BlenderRNA");
646   const char *error_message = NULL;
647
648   BLI_listbase_clear(&DefRNA.structs);
649   brna->structs_map = BLI_ghash_str_new_ex(__func__, 2048);
650
651   DefRNA.error = 0;
652   DefRNA.preprocess = 1;
653
654   DefRNA.sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, &error_message);
655   if (DefRNA.sdna == NULL) {
656     CLOG_ERROR(&LOG, "Failed to decode SDNA: %s.", error_message);
657     DefRNA.error = 1;
658   }
659
660   /* We need both alias and static (on-disk) DNA names. */
661   DNA_sdna_alias_data_ensure(DefRNA.sdna);
662
663 #ifndef RNA_RUNTIME
664   DNA_alias_maps(DNA_RENAME_STATIC_FROM_ALIAS, &g_version_data.struct_map_static_from_alias, NULL);
665 #endif
666
667   return brna;
668 }
669
670 void RNA_define_free(BlenderRNA *UNUSED(brna))
671 {
672   StructDefRNA *ds;
673   FunctionDefRNA *dfunc;
674   AllocDefRNA *alloc;
675
676   for (alloc = DefRNA.allocs.first; alloc; alloc = alloc->next) {
677     MEM_freeN(alloc->mem);
678   }
679   rna_freelistN(&DefRNA.allocs);
680
681   for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
682     for (dfunc = ds->functions.first; dfunc; dfunc = dfunc->cont.next) {
683       rna_freelistN(&dfunc->cont.properties);
684     }
685
686     rna_freelistN(&ds->cont.properties);
687     rna_freelistN(&ds->functions);
688   }
689
690   rna_freelistN(&DefRNA.structs);
691
692   if (DefRNA.sdna) {
693     DNA_sdna_free(DefRNA.sdna);
694     DefRNA.sdna = NULL;
695   }
696
697   DefRNA.error = 0;
698 }
699
700 void RNA_define_verify_sdna(bool verify)
701 {
702   DefRNA.verify = verify;
703 }
704
705 #ifndef RNA_RUNTIME
706 void RNA_define_animate_sdna(bool animate)
707 {
708   DefRNA.animate = animate;
709 }
710 #endif
711
712 void RNA_struct_free_extension(StructRNA *srna, ExtensionRNA *ext)
713 {
714 #ifdef RNA_RUNTIME
715   ext->free(ext->data);                    /* decref's the PyObject that the srna owns */
716   RNA_struct_blender_type_set(srna, NULL); /* this gets accessed again - XXX fixme */
717   RNA_struct_py_type_set(
718       srna, NULL); /* NULL the srna's value so RNA_struct_free wont complain of a leak */
719 #else
720   (void)srna;
721   (void)ext;
722 #endif
723 }
724
725 void RNA_struct_free(BlenderRNA *brna, StructRNA *srna)
726 {
727 #ifdef RNA_RUNTIME
728   FunctionRNA *func, *nextfunc;
729   PropertyRNA *prop, *nextprop;
730   PropertyRNA *parm, *nextparm;
731
732 #  if 0
733   if (srna->flag & STRUCT_RUNTIME) {
734     if (RNA_struct_py_type_get(srna)) {
735       fprintf(stderr, "%s '%s' freed while holding a python reference.", srna->identifier);
736     }
737   }
738 #  endif
739
740   for (prop = srna->cont.properties.first; prop; prop = nextprop) {
741     nextprop = prop->next;
742
743     RNA_def_property_free_pointers(prop);
744
745     if (prop->flag_internal & PROP_INTERN_RUNTIME)
746       rna_freelinkN(&srna->cont.properties, prop);
747   }
748
749   for (func = srna->functions.first; func; func = nextfunc) {
750     nextfunc = func->cont.next;
751
752     for (parm = func->cont.properties.first; parm; parm = nextparm) {
753       nextparm = parm->next;
754
755       RNA_def_property_free_pointers(parm);
756
757       if (parm->flag_internal & PROP_INTERN_RUNTIME)
758         rna_freelinkN(&func->cont.properties, parm);
759     }
760
761     RNA_def_func_free_pointers(func);
762
763     if (func->flag & FUNC_RUNTIME)
764       rna_freelinkN(&srna->functions, func);
765   }
766
767   rna_brna_structs_remove_and_free(brna, srna);
768 #else
769   UNUSED_VARS(brna, srna);
770 #endif
771 }
772
773 void RNA_free(BlenderRNA *brna)
774 {
775   StructRNA *srna, *nextsrna;
776   FunctionRNA *func;
777
778   BLI_ghash_free(brna->structs_map, NULL, NULL);
779   brna->structs_map = NULL;
780
781   if (DefRNA.preprocess) {
782     RNA_define_free(brna);
783
784     for (srna = brna->structs.first; srna; srna = srna->cont.next) {
785       for (func = srna->functions.first; func; func = func->cont.next) {
786         rna_freelistN(&func->cont.properties);
787       }
788
789       rna_freelistN(&srna->cont.properties);
790       rna_freelistN(&srna->functions);
791     }
792
793     rna_freelistN(&brna->structs);
794
795     MEM_freeN(brna);
796   }
797   else {
798     for (srna = brna->structs.first; srna; srna = nextsrna) {
799       nextsrna = srna->cont.next;
800       RNA_struct_free(brna, srna);
801     }
802   }
803
804 #ifndef RNA_RUNTIME
805   BLI_ghash_free(g_version_data.struct_map_static_from_alias, NULL, NULL);
806   g_version_data.struct_map_static_from_alias = NULL;
807 #endif
808 }
809
810 static size_t rna_property_type_sizeof(PropertyType type)
811 {
812   switch (type) {
813     case PROP_BOOLEAN:
814       return sizeof(BoolPropertyRNA);
815     case PROP_INT:
816       return sizeof(IntPropertyRNA);
817     case PROP_FLOAT:
818       return sizeof(FloatPropertyRNA);
819     case PROP_STRING:
820       return sizeof(StringPropertyRNA);
821     case PROP_ENUM:
822       return sizeof(EnumPropertyRNA);
823     case PROP_POINTER:
824       return sizeof(PointerPropertyRNA);
825     case PROP_COLLECTION:
826       return sizeof(CollectionPropertyRNA);
827     default:
828       return 0;
829   }
830 }
831
832 static StructDefRNA *rna_find_def_struct(StructRNA *srna)
833 {
834   StructDefRNA *ds;
835
836   for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
837     if (ds->srna == srna) {
838       return ds;
839     }
840   }
841
842   return NULL;
843 }
844
845 /* Struct Definition */
846 StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom)
847 {
848   StructRNA *srna;
849   StructDefRNA *ds = NULL, *dsfrom = NULL;
850   PropertyRNA *prop;
851
852   if (DefRNA.preprocess) {
853     char error[512];
854
855     if (rna_validate_identifier(identifier, error, false) == 0) {
856       CLOG_ERROR(&LOG, "struct identifier \"%s\" error - %s", identifier, error);
857       DefRNA.error = 1;
858     }
859   }
860
861   srna = MEM_callocN(sizeof(StructRNA), "StructRNA");
862   DefRNA.laststruct = srna;
863
864   if (srnafrom) {
865     /* copy from struct to derive stuff, a bit clumsy since we can't
866      * use MEM_dupallocN, data structs may not be alloced but builtin */
867     memcpy(srna, srnafrom, sizeof(StructRNA));
868     srna->cont.prophash = NULL;
869     BLI_listbase_clear(&srna->cont.properties);
870     BLI_listbase_clear(&srna->functions);
871     srna->py_type = NULL;
872
873     srna->base = srnafrom;
874
875     if (DefRNA.preprocess) {
876       dsfrom = rna_find_def_struct(srnafrom);
877     }
878     else {
879       if (srnafrom->flag & STRUCT_PUBLIC_NAMESPACE_INHERIT) {
880         srna->flag |= STRUCT_PUBLIC_NAMESPACE | STRUCT_PUBLIC_NAMESPACE_INHERIT;
881       }
882       else {
883         srna->flag &= ~(STRUCT_PUBLIC_NAMESPACE | STRUCT_PUBLIC_NAMESPACE_INHERIT);
884       }
885     }
886   }
887
888   srna->identifier = identifier;
889   srna->name = identifier; /* may be overwritten later RNA_def_struct_ui_text */
890   srna->description = "";
891   /* may be overwritten later RNA_def_struct_translation_context */
892   srna->translation_context = BLT_I18NCONTEXT_DEFAULT_BPYRNA;
893   srna->flag |= STRUCT_UNDO;
894   if (!srnafrom) {
895     srna->icon = ICON_DOT;
896   }
897
898   if (DefRNA.preprocess) {
899     srna->flag |= STRUCT_PUBLIC_NAMESPACE;
900   }
901
902   rna_brna_structs_add(brna, srna);
903
904   if (DefRNA.preprocess) {
905     ds = MEM_callocN(sizeof(StructDefRNA), "StructDefRNA");
906     ds->srna = srna;
907     rna_addtail(&DefRNA.structs, ds);
908
909     if (dsfrom) {
910       ds->dnafromname = dsfrom->dnaname;
911     }
912   }
913
914   /* in preprocess, try to find sdna */
915   if (DefRNA.preprocess) {
916     RNA_def_struct_sdna(srna, srna->identifier);
917   }
918   else {
919     srna->flag |= STRUCT_RUNTIME;
920   }
921
922   if (srnafrom) {
923     srna->nameproperty = srnafrom->nameproperty;
924     srna->iteratorproperty = srnafrom->iteratorproperty;
925   }
926   else {
927     /* define some builtin properties */
928     prop = RNA_def_property(&srna->cont, "rna_properties", PROP_COLLECTION, PROP_NONE);
929     prop->flag_internal |= PROP_INTERN_BUILTIN;
930     RNA_def_property_ui_text(prop, "Properties", "RNA property collection");
931
932     if (DefRNA.preprocess) {
933       RNA_def_property_struct_type(prop, "Property");
934       RNA_def_property_collection_funcs(prop,
935                                         "rna_builtin_properties_begin",
936                                         "rna_builtin_properties_next",
937                                         "rna_iterator_listbase_end",
938                                         "rna_builtin_properties_get",
939                                         NULL,
940                                         NULL,
941                                         "rna_builtin_properties_lookup_string",
942                                         NULL);
943     }
944     else {
945 #ifdef RNA_RUNTIME
946       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
947       cprop->begin = rna_builtin_properties_begin;
948       cprop->next = rna_builtin_properties_next;
949       cprop->get = rna_builtin_properties_get;
950       cprop->item_type = &RNA_Property;
951 #endif
952     }
953
954     prop = RNA_def_property(&srna->cont, "rna_type", PROP_POINTER, PROP_NONE);
955     RNA_def_property_flag(prop, PROP_HIDDEN);
956     RNA_def_property_ui_text(prop, "RNA", "RNA type definition");
957
958     if (DefRNA.preprocess) {
959       RNA_def_property_struct_type(prop, "Struct");
960       RNA_def_property_pointer_funcs(prop, "rna_builtin_type_get", NULL, NULL, NULL);
961     }
962     else {
963 #ifdef RNA_RUNTIME
964       PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
965       pprop->get = rna_builtin_type_get;
966       pprop->type = &RNA_Struct;
967 #endif
968     }
969   }
970
971   return srna;
972 }
973
974 StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
975 {
976   StructRNA *srnafrom = NULL;
977
978   /* only use RNA_def_struct() while pre-processing, otherwise use RNA_def_struct_ptr() */
979   BLI_assert(DefRNA.preprocess);
980
981   if (from) {
982     /* find struct to derive from */
983     /* Inline RNA_struct_find(...) because it wont link from here. */
984     srnafrom = BLI_ghash_lookup(brna->structs_map, from);
985     if (!srnafrom) {
986       CLOG_ERROR(&LOG, "struct %s not found to define %s.", from, identifier);
987       DefRNA.error = 1;
988     }
989   }
990
991   return RNA_def_struct_ptr(brna, identifier, srnafrom);
992 }
993
994 void RNA_def_struct_sdna(StructRNA *srna, const char *structname)
995 {
996   StructDefRNA *ds;
997
998   if (!DefRNA.preprocess) {
999     CLOG_ERROR(&LOG, "only during preprocessing.");
1000     return;
1001   }
1002
1003   ds = rna_find_def_struct(srna);
1004
1005   /* There are far too many structs which initialize without valid DNA struct names,
1006    * this can't be checked without adding an option to disable
1007    * (tested this and it means changes all over - Campbell) */
1008 #if 0
1009   if (DNA_struct_find_nr_wrapper(DefRNA.sdna, structname) == -1) {
1010     if (!DefRNA.silent) {
1011       CLOG_ERROR(&LOG, "%s not found.", structname);
1012       DefRNA.error = 1;
1013     }
1014     return;
1015   }
1016 #endif
1017
1018   ds->dnaname = structname;
1019 }
1020
1021 void RNA_def_struct_sdna_from(StructRNA *srna, const char *structname, const char *propname)
1022 {
1023   StructDefRNA *ds;
1024
1025   if (!DefRNA.preprocess) {
1026     CLOG_ERROR(&LOG, "only during preprocessing.");
1027     return;
1028   }
1029
1030   ds = rna_find_def_struct(srna);
1031
1032   if (!ds->dnaname) {
1033     CLOG_ERROR(&LOG, "%s base struct must know DNA already.", structname);
1034     return;
1035   }
1036
1037   if (DNA_struct_find_nr_wrapper(DefRNA.sdna, structname) == -1) {
1038     if (!DefRNA.silent) {
1039       CLOG_ERROR(&LOG, "%s not found.", structname);
1040       DefRNA.error = 1;
1041     }
1042     return;
1043   }
1044
1045   ds->dnafromprop = propname;
1046   ds->dnaname = structname;
1047 }
1048
1049 void RNA_def_struct_name_property(struct StructRNA *srna, struct PropertyRNA *prop)
1050 {
1051   if (prop->type != PROP_STRING) {
1052     CLOG_ERROR(&LOG, "\"%s.%s\", must be a string property.", srna->identifier, prop->identifier);
1053     DefRNA.error = 1;
1054   }
1055   else {
1056     srna->nameproperty = prop;
1057   }
1058 }
1059
1060 void RNA_def_struct_nested(BlenderRNA *brna, StructRNA *srna, const char *structname)
1061 {
1062   StructRNA *srnafrom;
1063
1064   /* find struct to derive from */
1065   srnafrom = BLI_ghash_lookup(brna->structs_map, structname);
1066   if (!srnafrom) {
1067     CLOG_ERROR(&LOG, "struct %s not found for %s.", structname, srna->identifier);
1068     DefRNA.error = 1;
1069   }
1070
1071   srna->nested = srnafrom;
1072 }
1073
1074 void RNA_def_struct_flag(StructRNA *srna, int flag)
1075 {
1076   srna->flag |= flag;
1077 }
1078
1079 void RNA_def_struct_clear_flag(StructRNA *srna, int flag)
1080 {
1081   srna->flag &= ~flag;
1082 }
1083
1084 void RNA_def_struct_property_tags(StructRNA *srna, const EnumPropertyItem *prop_tag_defines)
1085 {
1086   srna->prop_tag_defines = prop_tag_defines;
1087 }
1088
1089 void RNA_def_struct_refine_func(StructRNA *srna, const char *refine)
1090 {
1091   if (!DefRNA.preprocess) {
1092     CLOG_ERROR(&LOG, "only during preprocessing.");
1093     return;
1094   }
1095
1096   if (refine) {
1097     srna->refine = (StructRefineFunc)refine;
1098   }
1099 }
1100
1101 void RNA_def_struct_idprops_func(StructRNA *srna, const char *idproperties)
1102 {
1103   if (!DefRNA.preprocess) {
1104     CLOG_ERROR(&LOG, "only during preprocessing.");
1105     return;
1106   }
1107
1108   if (idproperties) {
1109     srna->idproperties = (IDPropertiesFunc)idproperties;
1110   }
1111 }
1112
1113 void RNA_def_struct_register_funcs(StructRNA *srna,
1114                                    const char *reg,
1115                                    const char *unreg,
1116                                    const char *instance)
1117 {
1118   if (!DefRNA.preprocess) {
1119     CLOG_ERROR(&LOG, "only during preprocessing.");
1120     return;
1121   }
1122
1123   if (reg) {
1124     srna->reg = (StructRegisterFunc)reg;
1125   }
1126   if (unreg) {
1127     srna->unreg = (StructUnregisterFunc)unreg;
1128   }
1129   if (instance) {
1130     srna->instance = (StructInstanceFunc)instance;
1131   }
1132 }
1133
1134 void RNA_def_struct_path_func(StructRNA *srna, const char *path)
1135 {
1136   if (!DefRNA.preprocess) {
1137     CLOG_ERROR(&LOG, "only during preprocessing.");
1138     return;
1139   }
1140
1141   if (path) {
1142     srna->path = (StructPathFunc)path;
1143   }
1144 }
1145
1146 void RNA_def_struct_identifier(BlenderRNA *brna, StructRNA *srna, const char *identifier)
1147 {
1148   if (DefRNA.preprocess) {
1149     CLOG_ERROR(&LOG, "only at runtime.");
1150     return;
1151   }
1152
1153   /* Operator registration may set twice, see: operator_properties_init */
1154   if (srna->flag & STRUCT_PUBLIC_NAMESPACE) {
1155     if (identifier != srna->identifier) {
1156       if (srna->identifier[0] != '\0') {
1157         BLI_ghash_remove(brna->structs_map, (void *)srna->identifier, NULL, NULL);
1158       }
1159       if (identifier[0] != '\0') {
1160         BLI_ghash_insert(brna->structs_map, (void *)identifier, srna);
1161       }
1162     }
1163   }
1164
1165   srna->identifier = identifier;
1166 }
1167
1168 /**
1169  * Only used in one case when we name the struct for the purpose of useful error messages.
1170  */
1171 void RNA_def_struct_identifier_no_struct_map(StructRNA *srna, const char *identifier)
1172 {
1173   if (DefRNA.preprocess) {
1174     CLOG_ERROR(&LOG, "only at runtime.");
1175     return;
1176   }
1177
1178   srna->identifier = identifier;
1179 }
1180
1181 void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description)
1182 {
1183   DESCR_CHECK(description, srna->identifier, NULL);
1184
1185   srna->name = name;
1186   srna->description = description;
1187 }
1188
1189 void RNA_def_struct_ui_icon(StructRNA *srna, int icon)
1190 {
1191   srna->icon = icon;
1192 }
1193
1194 void RNA_def_struct_translation_context(StructRNA *srna, const char *context)
1195 {
1196   srna->translation_context = context ? context : BLT_I18NCONTEXT_DEFAULT_BPYRNA;
1197 }
1198
1199 /* Property Definition */
1200
1201 PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_,
1202                               const char *identifier,
1203                               int type,
1204                               int subtype)
1205 {
1206   /*StructRNA *srna = DefRNA.laststruct;*/ /* invalid for python defined props */
1207   ContainerRNA *cont = cont_;
1208   ContainerDefRNA *dcont;
1209   PropertyDefRNA *dprop = NULL;
1210   PropertyRNA *prop;
1211
1212   if (DefRNA.preprocess) {
1213     char error[512];
1214
1215     if (rna_validate_identifier(identifier, error, true) == 0) {
1216       CLOG_ERROR(
1217           &LOG, "property identifier \"%s.%s\" - %s", CONTAINER_RNA_ID(cont), identifier, error);
1218       DefRNA.error = 1;
1219     }
1220
1221     dcont = rna_find_container_def(cont);
1222
1223     /* XXX - toto, detect supertype collisions */
1224     if (rna_findlink(&dcont->properties, identifier)) {
1225       CLOG_ERROR(&LOG, "duplicate identifier \"%s.%s\"", CONTAINER_RNA_ID(cont), identifier);
1226       DefRNA.error = 1;
1227     }
1228
1229     dprop = MEM_callocN(sizeof(PropertyDefRNA), "PropertyDefRNA");
1230     rna_addtail(&dcont->properties, dprop);
1231   }
1232   else {
1233 #ifdef DEBUG
1234     char error[512];
1235     if (rna_validate_identifier(identifier, error, true) == 0) {
1236       CLOG_ERROR(&LOG,
1237                  "runtime property identifier \"%s.%s\" - %s",
1238                  CONTAINER_RNA_ID(cont),
1239                  identifier,
1240                  error);
1241       DefRNA.error = 1;
1242     }
1243 #endif
1244   }
1245
1246   prop = MEM_callocN(rna_property_type_sizeof(type), "PropertyRNA");
1247
1248   switch (type) {
1249     case PROP_BOOLEAN:
1250       if (DefRNA.preprocess) {
1251         if ((subtype & ~(PROP_LAYER_MEMBER)) != PROP_NONE) {
1252           CLOG_ERROR(&LOG,
1253                      "subtype does not apply to 'PROP_BOOLEAN' \"%s.%s\"",
1254                      CONTAINER_RNA_ID(cont),
1255                      identifier);
1256           DefRNA.error = 1;
1257         }
1258       }
1259       break;
1260     case PROP_INT: {
1261       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1262
1263 #ifndef RNA_RUNTIME
1264       if (subtype == PROP_DISTANCE) {
1265         CLOG_ERROR(&LOG,
1266                    "subtype does not apply to 'PROP_INT' \"%s.%s\"",
1267                    CONTAINER_RNA_ID(cont),
1268                    identifier);
1269         DefRNA.error = 1;
1270       }
1271 #endif
1272
1273       iprop->hardmin = (subtype == PROP_UNSIGNED) ? 0 : INT_MIN;
1274       iprop->hardmax = INT_MAX;
1275
1276       iprop->softmin = (subtype == PROP_UNSIGNED) ? 0 : -10000; /* rather arbitrary .. */
1277       iprop->softmax = 10000;
1278       iprop->step = 1;
1279       break;
1280     }
1281     case PROP_FLOAT: {
1282       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
1283
1284       fprop->hardmin = (subtype == PROP_UNSIGNED) ? 0.0f : -FLT_MAX;
1285       fprop->hardmax = FLT_MAX;
1286
1287       if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
1288         fprop->softmin = fprop->hardmin = 0.0f;
1289         fprop->softmax = 1.0f;
1290       }
1291       else if (subtype == PROP_FACTOR) {
1292         fprop->softmin = fprop->hardmin = 0.0f;
1293         fprop->softmax = fprop->hardmax = 1.0f;
1294       }
1295       else {
1296         fprop->softmin = (subtype == PROP_UNSIGNED) ? 0.0f : -10000.0f; /* rather arbitrary .. */
1297         fprop->softmax = 10000.0f;
1298       }
1299       fprop->step = 10;
1300       fprop->precision = 3;
1301       break;
1302     }
1303     case PROP_STRING: {
1304       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
1305       /* By default don't allow NULL string args, callers may clear. */
1306       RNA_def_property_flag(prop, PROP_NEVER_NULL);
1307       sprop->defaultvalue = "";
1308       break;
1309     }
1310     case PROP_POINTER:
1311       prop->flag |= PROP_THICK_WRAP; /* needed for default behavior when PARM_RNAPTR is set */
1312       break;
1313     case PROP_ENUM:
1314     case PROP_COLLECTION:
1315       break;
1316     default:
1317       CLOG_ERROR(&LOG, "\"%s.%s\", invalid property type.", CONTAINER_RNA_ID(cont), identifier);
1318       DefRNA.error = 1;
1319       return NULL;
1320   }
1321
1322   if (DefRNA.preprocess) {
1323     dprop->cont = cont;
1324     dprop->prop = prop;
1325   }
1326
1327   prop->magic = RNA_MAGIC;
1328   prop->identifier = identifier;
1329   prop->type = type;
1330   prop->subtype = subtype;
1331   prop->name = identifier;
1332   prop->description = "";
1333   prop->translation_context = BLT_I18NCONTEXT_DEFAULT_BPYRNA;
1334   /* a priori not raw editable */
1335   prop->rawtype = -1;
1336
1337   if (type != PROP_COLLECTION && type != PROP_POINTER) {
1338     prop->flag = PROP_EDITABLE;
1339
1340     if (type != PROP_STRING) {
1341 #ifdef RNA_RUNTIME
1342       prop->flag |= PROP_ANIMATABLE;
1343 #else
1344       if (DefRNA.animate) {
1345         prop->flag |= PROP_ANIMATABLE;
1346       }
1347 #endif
1348     }
1349   }
1350
1351   if (type == PROP_STRING) {
1352     /* used so generated 'get/length/set' functions skip a NULL check
1353      * in some cases we want it */
1354     RNA_def_property_flag(prop, PROP_NEVER_NULL);
1355   }
1356
1357   if (DefRNA.preprocess) {
1358     switch (type) {
1359       case PROP_BOOLEAN:
1360         DefRNA.silent = 1;
1361         RNA_def_property_boolean_sdna(prop, NULL, identifier, 0);
1362         DefRNA.silent = 0;
1363         break;
1364       case PROP_INT: {
1365         DefRNA.silent = 1;
1366         RNA_def_property_int_sdna(prop, NULL, identifier);
1367         DefRNA.silent = 0;
1368         break;
1369       }
1370       case PROP_FLOAT: {
1371         DefRNA.silent = 1;
1372         RNA_def_property_float_sdna(prop, NULL, identifier);
1373         DefRNA.silent = 0;
1374         break;
1375       }
1376       case PROP_STRING: {
1377         DefRNA.silent = 1;
1378         RNA_def_property_string_sdna(prop, NULL, identifier);
1379         DefRNA.silent = 0;
1380         break;
1381       }
1382       case PROP_ENUM:
1383         DefRNA.silent = 1;
1384         RNA_def_property_enum_sdna(prop, NULL, identifier);
1385         DefRNA.silent = 0;
1386         break;
1387       case PROP_POINTER:
1388         DefRNA.silent = 1;
1389         RNA_def_property_pointer_sdna(prop, NULL, identifier);
1390         DefRNA.silent = 0;
1391         break;
1392       case PROP_COLLECTION:
1393         DefRNA.silent = 1;
1394         RNA_def_property_collection_sdna(prop, NULL, identifier, NULL);
1395         DefRNA.silent = 0;
1396         break;
1397     }
1398   }
1399   else {
1400     prop->flag |= PROP_IDPROPERTY;
1401     prop->flag_internal |= PROP_INTERN_RUNTIME;
1402 #ifdef RNA_RUNTIME
1403     if (cont->prophash)
1404       BLI_ghash_insert(cont->prophash, (void *)prop->identifier, prop);
1405 #endif
1406   }
1407
1408   /* Override handling. */
1409   if (DefRNA.preprocess) {
1410     prop->override_diff = (RNAPropOverrideDiff) "rna_property_override_diff_default";
1411     prop->override_store = (RNAPropOverrideStore) "rna_property_override_store_default";
1412     prop->override_apply = (RNAPropOverrideApply) "rna_property_override_apply_default";
1413   }
1414   /* TODO: do we want that for runtime-defined stuff too? I’d say no, but... maybe yes :/ */
1415
1416   rna_addtail(&cont->properties, prop);
1417
1418   return prop;
1419 }
1420
1421 void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
1422 {
1423   prop->flag |= flag;
1424 }
1425
1426 void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag)
1427 {
1428   prop->flag &= ~flag;
1429 }
1430
1431 void RNA_def_property_override_flag(PropertyRNA *prop, PropertyOverrideFlag flag)
1432 {
1433   prop->flag_override |= flag;
1434 }
1435
1436 void RNA_def_property_override_clear_flag(PropertyRNA *prop, PropertyOverrideFlag flag)
1437 {
1438   prop->flag_override &= ~flag;
1439 }
1440
1441 /**
1442  * Add the property-tags passed as \a tags to \a prop (if valid).
1443  *
1444  * \note Multiple tags can be set by passing them within \a tags (using bitflags).
1445  * \note Doesn't do any type-checking with the tags defined in the parent StructRNA
1446  *       of \a prop. This should be done before (e.g. see #WM_operatortype_prop_tag).
1447  */
1448 void RNA_def_property_tags(PropertyRNA *prop, int tags)
1449 {
1450   prop->tags |= tags;
1451 }
1452
1453 void RNA_def_parameter_flags(PropertyRNA *prop,
1454                              PropertyFlag flag_property,
1455                              ParameterFlag flag_parameter)
1456 {
1457   prop->flag |= flag_property;
1458   prop->flag_parameter |= flag_parameter;
1459 }
1460
1461 void RNA_def_parameter_clear_flags(PropertyRNA *prop,
1462                                    PropertyFlag flag_property,
1463                                    ParameterFlag flag_parameter)
1464 {
1465   prop->flag &= ~flag_property;
1466   prop->flag_parameter &= ~flag_parameter;
1467 }
1468
1469 void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype)
1470 {
1471   prop->subtype = subtype;
1472 }
1473
1474 void RNA_def_property_array(PropertyRNA *prop, int length)
1475 {
1476   StructRNA *srna = DefRNA.laststruct;
1477
1478   if (length < 0) {
1479     CLOG_ERROR(&LOG,
1480                "\"%s.%s\", array length must be zero of greater.",
1481                srna->identifier,
1482                prop->identifier);
1483     DefRNA.error = 1;
1484     return;
1485   }
1486
1487   if (length > RNA_MAX_ARRAY_LENGTH) {
1488     CLOG_ERROR(&LOG,
1489                "\"%s.%s\", array length must be smaller than %d.",
1490                srna->identifier,
1491                prop->identifier,
1492                RNA_MAX_ARRAY_LENGTH);
1493     DefRNA.error = 1;
1494     return;
1495   }
1496
1497   if (prop->arraydimension > 1) {
1498     CLOG_ERROR(&LOG,
1499                "\"%s.%s\", array dimensions has been set to %u but would be overwritten as 1.",
1500                srna->identifier,
1501                prop->identifier,
1502                prop->arraydimension);
1503     DefRNA.error = 1;
1504     return;
1505   }
1506
1507   switch (prop->type) {
1508     case PROP_BOOLEAN:
1509     case PROP_INT:
1510     case PROP_FLOAT:
1511       prop->arraylength[0] = length;
1512       prop->totarraylength = length;
1513       prop->arraydimension = 1;
1514       break;
1515     default:
1516       CLOG_ERROR(&LOG,
1517                  "\"%s.%s\", only boolean/int/float can be array.",
1518                  srna->identifier,
1519                  prop->identifier);
1520       DefRNA.error = 1;
1521       break;
1522   }
1523 }
1524
1525 /* common args for defaults. */
1526 const float rna_default_quaternion[4] = {1, 0, 0, 0};
1527 const float rna_default_axis_angle[4] = {0, 0, 1, 0};
1528 const float rna_default_scale_3d[3] = {1, 1, 1};
1529
1530 /* common args for length */
1531 const int rna_matrix_dimsize_3x3[] = {3, 3};
1532 const int rna_matrix_dimsize_4x4[] = {4, 4};
1533 const int rna_matrix_dimsize_4x2[] = {4, 2};
1534
1535 void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, const int length[])
1536 {
1537   StructRNA *srna = DefRNA.laststruct;
1538   int i;
1539
1540   if (dimension < 1 || dimension > RNA_MAX_ARRAY_DIMENSION) {
1541     CLOG_ERROR(&LOG,
1542                "\"%s.%s\", array dimension must be between 1 and %d.",
1543                srna->identifier,
1544                prop->identifier,
1545                RNA_MAX_ARRAY_DIMENSION);
1546     DefRNA.error = 1;
1547     return;
1548   }
1549
1550   switch (prop->type) {
1551     case PROP_BOOLEAN:
1552     case PROP_INT:
1553     case PROP_FLOAT:
1554       break;
1555     default:
1556       CLOG_ERROR(&LOG,
1557                  "\"%s.%s\", only boolean/int/float can be array.",
1558                  srna->identifier,
1559                  prop->identifier);
1560       DefRNA.error = 1;
1561       break;
1562   }
1563
1564   prop->arraydimension = dimension;
1565   prop->totarraylength = 0;
1566
1567   if (length) {
1568     memcpy(prop->arraylength, length, sizeof(int) * dimension);
1569
1570     prop->totarraylength = length[0];
1571     for (i = 1; i < dimension; i++) {
1572       prop->totarraylength *= length[i];
1573     }
1574   }
1575   else {
1576     memset(prop->arraylength, 0, sizeof(prop->arraylength));
1577   }
1578
1579   /* TODO make sure arraylength values are sane  */
1580 }
1581
1582 void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
1583 {
1584   DESCR_CHECK(description, prop->identifier, NULL);
1585
1586   prop->name = name;
1587   prop->description = description;
1588 }
1589
1590 void RNA_def_property_ui_icon(PropertyRNA *prop, int icon, int consecutive)
1591 {
1592   prop->icon = icon;
1593   if (consecutive != 0) {
1594     prop->flag |= PROP_ICONS_CONSECUTIVE;
1595   }
1596   if (consecutive < 0) {
1597     prop->flag |= PROP_ICONS_REVERSE;
1598   }
1599 }
1600
1601 /**
1602  * The values hare are a little confusing:
1603  *
1604  * \param step: Used as the value to increase/decrease when clicking on number buttons,
1605  * as well as scaling mouse input for click-dragging number buttons.
1606  * For floats this is (step * UI_PRECISION_FLOAT_SCALE), why? - nobody knows.
1607  * For ints, whole values are used.
1608  *
1609  * \param precision: The number of zeros to show
1610  * (as a whole number - common range is 1 - 6), see UI_PRECISION_FLOAT_MAX
1611  */
1612 void RNA_def_property_ui_range(
1613     PropertyRNA *prop, double min, double max, double step, int precision)
1614 {
1615   StructRNA *srna = DefRNA.laststruct;
1616
1617 #ifndef NDEBUG
1618   if (min > max) {
1619     CLOG_ERROR(&LOG, "\"%s.%s\", min > max.", srna->identifier, prop->identifier);
1620     DefRNA.error = 1;
1621   }
1622
1623   if (step < 0 || step > 100) {
1624     CLOG_ERROR(&LOG, "\"%s.%s\", step outside range.", srna->identifier, prop->identifier);
1625     DefRNA.error = 1;
1626   }
1627
1628   if (precision < -1 || precision > UI_PRECISION_FLOAT_MAX) {
1629     CLOG_ERROR(&LOG, "\"%s.%s\", precision outside range.", srna->identifier, prop->identifier);
1630     DefRNA.error = 1;
1631   }
1632 #endif
1633
1634   switch (prop->type) {
1635     case PROP_INT: {
1636       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1637       iprop->softmin = (int)min;
1638       iprop->softmax = (int)max;
1639       iprop->step = (int)step;
1640       break;
1641     }
1642     case PROP_FLOAT: {
1643       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
1644       fprop->softmin = (float)min;
1645       fprop->softmax = (float)max;
1646       fprop->step = (float)step;
1647       fprop->precision = (int)precision;
1648       break;
1649     }
1650     default:
1651       CLOG_ERROR(
1652           &LOG, "\"%s.%s\", invalid type for ui range.", srna->identifier, prop->identifier);
1653       DefRNA.error = 1;
1654       break;
1655   }
1656 }
1657
1658 void RNA_def_property_range(PropertyRNA *prop, double min, double max)
1659 {
1660   StructRNA *srna = DefRNA.laststruct;
1661
1662 #ifdef DEBUG
1663   if (min > max) {
1664     CLOG_ERROR(&LOG, "\"%s.%s\", min > max.", srna->identifier, prop->identifier);
1665     DefRNA.error = 1;
1666   }
1667 #endif
1668
1669   switch (prop->type) {
1670     case PROP_INT: {
1671       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1672       iprop->hardmin = (int)min;
1673       iprop->hardmax = (int)max;
1674       iprop->softmin = MAX2((int)min, iprop->hardmin);
1675       iprop->softmax = MIN2((int)max, iprop->hardmax);
1676       break;
1677     }
1678     case PROP_FLOAT: {
1679       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
1680       fprop->hardmin = (float)min;
1681       fprop->hardmax = (float)max;
1682       fprop->softmin = MAX2((float)min, fprop->hardmin);
1683       fprop->softmax = MIN2((float)max, fprop->hardmax);
1684       break;
1685     }
1686     default:
1687       CLOG_ERROR(&LOG, "\"%s.%s\", invalid type for range.", srna->identifier, prop->identifier);
1688       DefRNA.error = 1;
1689       break;
1690   }
1691 }
1692
1693 void RNA_def_property_struct_type(PropertyRNA *prop, const char *type)
1694 {
1695   StructRNA *srna = DefRNA.laststruct;
1696
1697   if (!DefRNA.preprocess) {
1698     fprintf(stderr, "\"%s.%s\": only during preprocessing.", srna->identifier, prop->identifier);
1699     return;
1700   }
1701
1702   switch (prop->type) {
1703     case PROP_POINTER: {
1704       PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1705       pprop->type = (StructRNA *)type;
1706       break;
1707     }
1708     case PROP_COLLECTION: {
1709       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
1710       cprop->item_type = (StructRNA *)type;
1711       break;
1712     }
1713     default:
1714       CLOG_ERROR(
1715           &LOG, "\"%s.%s\", invalid type for struct type.", srna->identifier, prop->identifier);
1716       DefRNA.error = 1;
1717       break;
1718   }
1719 }
1720
1721 void RNA_def_property_struct_runtime(PropertyRNA *prop, StructRNA *type)
1722 {
1723   StructRNA *srna = DefRNA.laststruct;
1724
1725   if (DefRNA.preprocess) {
1726     CLOG_ERROR(&LOG, "only at runtime.");
1727     return;
1728   }
1729
1730   switch (prop->type) {
1731     case PROP_POINTER: {
1732       PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
1733       pprop->type = type;
1734
1735       if (type && (type->flag & STRUCT_ID_REFCOUNT)) {
1736         prop->flag |= PROP_ID_REFCOUNT;
1737       }
1738
1739       break;
1740     }
1741     case PROP_COLLECTION: {
1742       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
1743       cprop->item_type = type;
1744       break;
1745     }
1746     default:
1747       CLOG_ERROR(
1748           &LOG, "\"%s.%s\", invalid type for struct type.", srna->identifier, prop->identifier);
1749       DefRNA.error = 1;
1750       break;
1751   }
1752 }
1753
1754 void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item)
1755 {
1756   StructRNA *srna = DefRNA.laststruct;
1757   int i, defaultfound = 0;
1758
1759   switch (prop->type) {
1760     case PROP_ENUM: {
1761       EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
1762       eprop->item = (EnumPropertyItem *)item;
1763       eprop->totitem = 0;
1764       for (i = 0; item[i].identifier; i++) {
1765         eprop->totitem++;
1766
1767         if (item[i].identifier[0] && item[i].value == eprop->defaultvalue) {
1768           defaultfound = 1;
1769         }
1770       }
1771
1772       if (!defaultfound) {
1773         for (i = 0; item[i].identifier; i++) {
1774           if (item[i].identifier[0]) {
1775             eprop->defaultvalue = item[i].value;
1776             break;
1777           }
1778         }
1779       }
1780
1781       break;
1782     }
1783     default:
1784       CLOG_ERROR(
1785           &LOG, "\"%s.%s\", invalid type for struct type.", srna->identifier, prop->identifier);
1786       DefRNA.error = 1;
1787       break;
1788   }
1789 }
1790
1791 void RNA_def_property_string_maxlength(PropertyRNA *prop, int maxlength)
1792 {
1793   StructRNA *srna = DefRNA.laststruct;
1794
1795   switch (prop->type) {
1796     case PROP_STRING: {
1797       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
1798       sprop->maxlength = maxlength;
1799       break;
1800     }
1801     default:
1802       CLOG_ERROR(&LOG, "\"%s.%s\", type is not string.", srna->identifier, prop->identifier);
1803       DefRNA.error = 1;
1804       break;
1805   }
1806 }
1807
1808 void RNA_def_property_boolean_default(PropertyRNA *prop, bool value)
1809 {
1810   StructRNA *srna = DefRNA.laststruct;
1811
1812   switch (prop->type) {
1813     case PROP_BOOLEAN: {
1814       BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1815       BLI_assert(ELEM(value, false, true));
1816       bprop->defaultvalue = value;
1817       break;
1818     }
1819     default:
1820       CLOG_ERROR(&LOG, "\"%s.%s\", type is not boolean.", srna->identifier, prop->identifier);
1821       DefRNA.error = 1;
1822       break;
1823   }
1824 }
1825
1826 void RNA_def_property_boolean_array_default(PropertyRNA *prop, const bool *array)
1827 {
1828   StructRNA *srna = DefRNA.laststruct;
1829
1830   switch (prop->type) {
1831     case PROP_BOOLEAN: {
1832       BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
1833       bprop->defaultarray = array;
1834       break;
1835     }
1836     default:
1837       CLOG_ERROR(&LOG, "\"%s.%s\", type is not boolean.", srna->identifier, prop->identifier);
1838       DefRNA.error = 1;
1839       break;
1840   }
1841 }
1842
1843 void RNA_def_property_int_default(PropertyRNA *prop, int value)
1844 {
1845   StructRNA *srna = DefRNA.laststruct;
1846
1847   switch (prop->type) {
1848     case PROP_INT: {
1849       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1850       iprop->defaultvalue = value;
1851       break;
1852     }
1853     default:
1854       CLOG_ERROR(&LOG, "\"%s.%s\", type is not int.", srna->identifier, prop->identifier);
1855       DefRNA.error = 1;
1856       break;
1857   }
1858 }
1859
1860 void RNA_def_property_int_array_default(PropertyRNA *prop, const int *array)
1861 {
1862   StructRNA *srna = DefRNA.laststruct;
1863
1864   switch (prop->type) {
1865     case PROP_INT: {
1866       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
1867       iprop->defaultarray = array;
1868       break;
1869     }
1870     default:
1871       CLOG_ERROR(&LOG, "\"%s.%s\", type is not int.", srna->identifier, prop->identifier);
1872       DefRNA.error = 1;
1873       break;
1874   }
1875 }
1876
1877 void RNA_def_property_float_default(PropertyRNA *prop, float value)
1878 {
1879   StructRNA *srna = DefRNA.laststruct;
1880
1881   switch (prop->type) {
1882     case PROP_FLOAT: {
1883       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
1884       fprop->defaultvalue = value;
1885       break;
1886     }
1887     default:
1888       CLOG_ERROR(&LOG, "\"%s.%s\", type is not float.", srna->identifier, prop->identifier);
1889       DefRNA.error = 1;
1890       break;
1891   }
1892 }
1893 /* array must remain valid after this function finishes */
1894 void RNA_def_property_float_array_default(PropertyRNA *prop, const float *array)
1895 {
1896   StructRNA *srna = DefRNA.laststruct;
1897
1898   switch (prop->type) {
1899     case PROP_FLOAT: {
1900       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
1901       fprop->defaultarray = array; /* WARNING, this array must not come from the stack and lost */
1902       break;
1903     }
1904     default:
1905       CLOG_ERROR(&LOG, "\"%s.%s\", type is not float.", srna->identifier, prop->identifier);
1906       DefRNA.error = 1;
1907       break;
1908   }
1909 }
1910
1911 void RNA_def_property_string_default(PropertyRNA *prop, const char *value)
1912 {
1913   StructRNA *srna = DefRNA.laststruct;
1914
1915   switch (prop->type) {
1916     case PROP_STRING: {
1917       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
1918
1919       if (value == NULL) {
1920         CLOG_ERROR(&LOG,
1921                    "\"%s.%s\", NULL string passed (dont call in this case).",
1922                    srna->identifier,
1923                    prop->identifier);
1924         DefRNA.error = 1;
1925         break;
1926       }
1927
1928       if (!value[0]) {
1929         CLOG_ERROR(&LOG,
1930                    "\"%s.%s\", empty string passed (dont call in this case).",
1931                    srna->identifier,
1932                    prop->identifier);
1933         DefRNA.error = 1;
1934         // BLI_assert(0);
1935         break;
1936       }
1937
1938       sprop->defaultvalue = value;
1939       break;
1940     }
1941     default:
1942       CLOG_ERROR(&LOG, "\"%s.%s\", type is not string.", srna->identifier, prop->identifier);
1943       DefRNA.error = 1;
1944       break;
1945   }
1946 }
1947
1948 void RNA_def_property_enum_default(PropertyRNA *prop, int value)
1949 {
1950   StructRNA *srna = DefRNA.laststruct;
1951   int i, defaultfound = 0;
1952
1953   switch (prop->type) {
1954     case PROP_ENUM: {
1955       EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
1956       eprop->defaultvalue = value;
1957
1958       if (prop->flag & PROP_ENUM_FLAG) {
1959         /* check all bits are accounted for */
1960         int totflag = 0;
1961         for (i = 0; i < eprop->totitem; i++) {
1962           if (eprop->item[i].identifier[0]) {
1963             totflag |= eprop->item[i].value;
1964           }
1965         }
1966
1967         if (eprop->defaultvalue & ~totflag) {
1968           CLOG_ERROR(&LOG,
1969                      "\"%s.%s\", default includes unused bits (%d).",
1970                      srna->identifier,
1971                      prop->identifier,
1972                      eprop->defaultvalue & ~totflag);
1973           DefRNA.error = 1;
1974         }
1975       }
1976       else {
1977         for (i = 0; i < eprop->totitem; i++) {
1978           if (eprop->item[i].identifier[0] && eprop->item[i].value == eprop->defaultvalue) {
1979             defaultfound = 1;
1980           }
1981         }
1982
1983         if (!defaultfound && eprop->totitem) {
1984           if (value == 0) {
1985             eprop->defaultvalue = eprop->item[0].value;
1986           }
1987           else {
1988             CLOG_ERROR(
1989                 &LOG, "\"%s.%s\", default is not in items.", srna->identifier, prop->identifier);
1990             DefRNA.error = 1;
1991           }
1992         }
1993       }
1994
1995       break;
1996     }
1997     default:
1998       CLOG_ERROR(&LOG, "\"%s.%s\", type is not enum.", srna->identifier, prop->identifier);
1999       DefRNA.error = 1;
2000       break;
2001   }
2002 }
2003
2004 /* SDNA */
2005
2006 static PropertyDefRNA *rna_def_property_sdna(PropertyRNA *prop,
2007                                              const char *structname,
2008                                              const char *propname)
2009 {
2010   DNAStructMember smember;
2011   StructDefRNA *ds;
2012   PropertyDefRNA *dp;
2013
2014   dp = rna_find_struct_property_def(DefRNA.laststruct, prop);
2015   if (dp == NULL) {
2016     return NULL;
2017   }
2018
2019   ds = rna_find_struct_def((StructRNA *)dp->cont);
2020
2021   if (!structname) {
2022     structname = ds->dnaname;
2023   }
2024   if (!propname) {
2025     propname = prop->identifier;
2026   }
2027
2028   if (!rna_find_sdna_member(DefRNA.sdna, structname, propname, &smember)) {
2029     if (DefRNA.silent) {
2030       return NULL;
2031     }
2032     else if (!DefRNA.verify) {
2033       /* some basic values to survive even with sdna info */
2034       dp->dnastructname = structname;
2035       dp->dnaname = propname;
2036       if (prop->type == PROP_BOOLEAN) {
2037         dp->dnaarraylength = 1;
2038       }
2039       if (prop->type == PROP_POINTER) {
2040         dp->dnapointerlevel = 1;
2041       }
2042       return dp;
2043     }
2044     else {
2045       CLOG_ERROR(&LOG,
2046                  "\"%s.%s\" (identifier \"%s\") not found. Struct must be in DNA.",
2047                  structname,
2048                  propname,
2049                  prop->identifier);
2050       DefRNA.error = 1;
2051       return NULL;
2052     }
2053   }
2054
2055   if (smember.arraylength > 1) {
2056     prop->arraylength[0] = smember.arraylength;
2057     prop->totarraylength = smember.arraylength;
2058     prop->arraydimension = 1;
2059   }
2060   else {
2061     prop->arraydimension = 0;
2062     prop->totarraylength = 0;
2063   }
2064
2065   dp->dnastructname = structname;
2066   dp->dnastructfromname = ds->dnafromname;
2067   dp->dnastructfromprop = ds->dnafromprop;
2068   dp->dnaname = propname;
2069   dp->dnatype = smember.type;
2070   dp->dnaarraylength = smember.arraylength;
2071   dp->dnapointerlevel = smember.pointerlevel;
2072
2073   return dp;
2074 }
2075
2076 void RNA_def_property_boolean_sdna(PropertyRNA *prop,
2077                                    const char *structname,
2078                                    const char *propname,
2079                                    int bit)
2080 {
2081   PropertyDefRNA *dp;
2082   StructRNA *srna = DefRNA.laststruct;
2083
2084   if (!DefRNA.preprocess) {
2085     CLOG_ERROR(&LOG, "only during preprocessing.");
2086     return;
2087   }
2088
2089   if (prop->type != PROP_BOOLEAN) {
2090     CLOG_ERROR(&LOG, "\"%s.%s\", type is not boolean.", srna->identifier, prop->identifier);
2091     DefRNA.error = 1;
2092     return;
2093   }
2094
2095   if ((dp = rna_def_property_sdna(prop, structname, propname))) {
2096
2097     if (DefRNA.silent == 0) {
2098       /* error check to ensure floats are not wrapped as ints/bools */
2099       if (dp->dnatype && *dp->dnatype && IS_DNATYPE_INT_COMPAT(dp->dnatype) == 0) {
2100         CLOG_ERROR(&LOG,
2101                    "%s.%s is a '%s' but wrapped as type '%s'.",
2102                    srna->identifier,
2103                    prop->identifier,
2104                    dp->dnatype,
2105                    RNA_property_typename(prop->type));
2106         DefRNA.error = 1;
2107         return;
2108       }
2109     }
2110
2111     dp->booleanbit = bit;
2112   }
2113 }
2114
2115 void RNA_def_property_boolean_negative_sdna(PropertyRNA *prop,
2116                                             const char *structname,
2117                                             const char *propname,
2118                                             int booleanbit)
2119 {
2120   PropertyDefRNA *dp;
2121
2122   RNA_def_property_boolean_sdna(prop, structname, propname, booleanbit);
2123
2124   dp = rna_find_struct_property_def(DefRNA.laststruct, prop);
2125
2126   if (dp) {
2127     dp->booleannegative = 1;
2128   }
2129 }
2130
2131 void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const char *propname)
2132 {
2133   PropertyDefRNA *dp;
2134   IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2135   StructRNA *srna = DefRNA.laststruct;
2136
2137   if (!DefRNA.preprocess) {
2138     CLOG_ERROR(&LOG, "only during preprocessing.");
2139     return;
2140   }
2141
2142   if (prop->type != PROP_INT) {
2143     CLOG_ERROR(&LOG, "\"%s.%s\", type is not int.", srna->identifier, prop->identifier);
2144     DefRNA.error = 1;
2145     return;
2146   }
2147
2148   if ((dp = rna_def_property_sdna(prop, structname, propname))) {
2149
2150     /* error check to ensure floats are not wrapped as ints/bools */
2151     if (DefRNA.silent == 0) {
2152       if (dp->dnatype && *dp->dnatype && IS_DNATYPE_INT_COMPAT(dp->dnatype) == 0) {
2153         CLOG_ERROR(&LOG,
2154                    "%s.%s is a '%s' but wrapped as type '%s'.",
2155                    srna->identifier,
2156                    prop->identifier,
2157                    dp->dnatype,
2158                    RNA_property_typename(prop->type));
2159         DefRNA.error = 1;
2160         return;
2161       }
2162     }
2163
2164     /* SDNA doesn't pass us unsigned unfortunately .. */
2165     if (dp->dnatype && STREQ(dp->dnatype, "char")) {
2166       iprop->hardmin = iprop->softmin = CHAR_MIN;
2167       iprop->hardmax = iprop->softmax = CHAR_MAX;
2168     }
2169     else if (dp->dnatype && STREQ(dp->dnatype, "short")) {
2170       iprop->hardmin = iprop->softmin = SHRT_MIN;
2171       iprop->hardmax = iprop->softmax = SHRT_MAX;
2172     }
2173     else if (dp->dnatype && STREQ(dp->dnatype, "int")) {
2174       iprop->hardmin = INT_MIN;
2175       iprop->hardmax = INT_MAX;
2176
2177       iprop->softmin = -10000; /* rather arbitrary .. */
2178       iprop->softmax = 10000;
2179     }
2180
2181     if (prop->subtype == PROP_UNSIGNED || prop->subtype == PROP_PERCENTAGE ||
2182         prop->subtype == PROP_FACTOR) {
2183       iprop->hardmin = iprop->softmin = 0;
2184     }
2185   }
2186 }
2187
2188 void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, const char *propname)
2189 {
2190   PropertyDefRNA *dp;
2191   FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2192   StructRNA *srna = DefRNA.laststruct;
2193
2194   if (!DefRNA.preprocess) {
2195     CLOG_ERROR(&LOG, "only during preprocessing.");
2196     return;
2197   }
2198
2199   if (prop->type != PROP_FLOAT) {
2200     CLOG_ERROR(&LOG, "\"%s.%s\", type is not float.", srna->identifier, prop->identifier);
2201     DefRNA.error = 1;
2202     return;
2203   }
2204
2205   if ((dp = rna_def_property_sdna(prop, structname, propname))) {
2206     /* silent is for internal use */
2207     if (DefRNA.silent == 0) {
2208       if (dp->dnatype && *dp->dnatype && IS_DNATYPE_FLOAT_COMPAT(dp->dnatype) == 0) {
2209         if (prop->subtype !=
2210             PROP_COLOR_GAMMA) { /* colors are an exception. these get translated */
2211           CLOG_ERROR(&LOG,
2212                      "%s.%s is a '%s' but wrapped as type '%s'.",
2213                      srna->identifier,
2214                      prop->identifier,
2215                      dp->dnatype,
2216                      RNA_property_typename(prop->type));
2217           DefRNA.error = 1;
2218           return;
2219         }
2220       }
2221     }
2222
2223     if (dp->dnatype && STREQ(dp->dnatype, "char")) {
2224       fprop->hardmin = fprop->softmin = 0.0f;
2225       fprop->hardmax = fprop->softmax = 1.0f;
2226     }
2227   }
2228
2229   rna_def_property_sdna(prop, structname, propname);
2230 }
2231
2232 void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const char *propname)
2233 {
2234   /* PropertyDefRNA *dp; */
2235   StructRNA *srna = DefRNA.laststruct;
2236
2237   if (!DefRNA.preprocess) {
2238     CLOG_ERROR(&LOG, "only during preprocessing.");
2239     return;
2240   }
2241
2242   if (prop->type != PROP_ENUM) {
2243     CLOG_ERROR(&LOG, "\"%s.%s\", type is not enum.", srna->identifier, prop->identifier);
2244     DefRNA.error = 1;
2245     return;
2246   }
2247
2248   if ((/* dp= */ rna_def_property_sdna(prop, structname, propname))) {
2249     if (prop->arraydimension) {
2250       prop->arraydimension = 0;
2251       prop->totarraylength = 0;
2252
2253       if (!DefRNA.silent) {
2254         CLOG_ERROR(&LOG, "\"%s.%s\", array not supported for enum type.", structname, propname);
2255         DefRNA.error = 1;
2256       }
2257     }
2258   }
2259 }
2260
2261 void RNA_def_property_enum_bitflag_sdna(PropertyRNA *prop,
2262                                         const char *structname,
2263                                         const char *propname)
2264 {
2265   PropertyDefRNA *dp;
2266
2267   RNA_def_property_enum_sdna(prop, structname, propname);
2268
2269   dp = rna_find_struct_property_def(DefRNA.laststruct, prop);
2270
2271   if (dp) {
2272     dp->enumbitflags = 1;
2273   }
2274 }
2275
2276 void RNA_def_property_string_sdna(PropertyRNA *prop, const char *structname, const char *propname)
2277 {
2278   /* PropertyDefRNA *dp; */
2279   StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2280   StructRNA *srna = DefRNA.laststruct;
2281
2282   if (!DefRNA.preprocess) {
2283     CLOG_ERROR(&LOG, "only during preprocessing.");
2284     return;
2285   }
2286
2287   if (prop->type != PROP_STRING) {
2288     CLOG_ERROR(&LOG, "\"%s.%s\", type is not string.", srna->identifier, prop->identifier);
2289     DefRNA.error = 1;
2290     return;
2291   }
2292
2293   if ((/* dp= */ rna_def_property_sdna(prop, structname, propname))) {
2294     if (prop->arraydimension) {
2295       sprop->maxlength = prop->totarraylength;
2296       prop->arraydimension = 0;
2297       prop->totarraylength = 0;
2298     }
2299   }
2300 }
2301
2302 void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, const char *propname)
2303 {
2304   /* PropertyDefRNA *dp; */
2305   StructRNA *srna = DefRNA.laststruct;
2306
2307   if (!DefRNA.preprocess) {
2308     CLOG_ERROR(&LOG, "only during preprocessing.");
2309     return;
2310   }
2311
2312   if (prop->type != PROP_POINTER) {
2313     CLOG_ERROR(&LOG, "\"%s.%s\", type is not pointer.", srna->identifier, prop->identifier);
2314     DefRNA.error = 1;
2315     return;
2316   }
2317
2318   if ((/* dp= */ rna_def_property_sdna(prop, structname, propname))) {
2319     if (prop->arraydimension) {
2320       prop->arraydimension = 0;
2321       prop->totarraylength = 0;
2322
2323       if (!DefRNA.silent) {
2324         CLOG_ERROR(&LOG, "\"%s.%s\", array not supported for pointer type.", structname, propname);
2325         DefRNA.error = 1;
2326       }
2327     }
2328   }
2329 }
2330
2331 void RNA_def_property_collection_sdna(PropertyRNA *prop,
2332                                       const char *structname,
2333                                       const char *propname,
2334                                       const char *lengthpropname)
2335 {
2336   PropertyDefRNA *dp;
2337   CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
2338   StructRNA *srna = DefRNA.laststruct;
2339
2340   if (!DefRNA.preprocess) {
2341     CLOG_ERROR(&LOG, "only during preprocessing.");
2342     return;
2343   }
2344
2345   if (prop->type != PROP_COLLECTION) {
2346     CLOG_ERROR(&LOG, "\"%s.%s\", type is not collection.", srna->identifier, prop->identifier);
2347     DefRNA.error = 1;
2348     return;
2349   }
2350
2351   if ((dp = rna_def_property_sdna(prop, structname, propname))) {
2352     if (prop->arraydimension && !lengthpropname) {
2353       prop->arraydimension = 0;
2354       prop->totarraylength = 0;
2355
2356       if (!DefRNA.silent) {
2357         CLOG_ERROR(&LOG, "\"%s.%s\", array of collections not supported.", structname, propname);
2358         DefRNA.error = 1;
2359       }
2360     }
2361
2362     if (dp->dnatype && STREQ(dp->dnatype, "ListBase")) {
2363       cprop->next = (PropCollectionNextFunc) "rna_iterator_listbase_next";
2364       cprop->get = (PropCollectionGetFunc) "rna_iterator_listbase_get";
2365       cprop->end = (PropCollectionEndFunc) "rna_iterator_listbase_end";
2366     }
2367   }
2368
2369   if (dp && lengthpropname) {
2370     DNAStructMember smember;
2371     StructDefRNA *ds = rna_find_struct_def((StructRNA *)dp->cont);
2372
2373     if (!structname) {
2374       structname = ds->dnaname;
2375     }
2376
2377     if (lengthpropname[0] == 0 ||
2378         rna_find_sdna_member(DefRNA.sdna, structname, lengthpropname, &smember)) {
2379       if (lengthpropname[0] == 0) {
2380         dp->dnalengthfixed = prop->totarraylength;
2381         prop->arraydimension = 0;
2382         prop->totarraylength = 0;
2383       }
2384       else {
2385         dp->dnalengthstructname = structname;
2386         dp->dnalengthname = lengthpropname;
2387         prop->totarraylength = 0;
2388       }
2389
2390       cprop->next = (PropCollectionNextFunc) "rna_iterator_array_next";
2391       cprop->end = (PropCollectionEndFunc) "rna_iterator_array_end";
2392
2393       if (dp->dnapointerlevel >= 2) {
2394         cprop->get = (PropCollectionGetFunc) "rna_iterator_array_dereference_get";
2395       }
2396       else {
2397         cprop->get = (PropCollectionGetFunc) "rna_iterator_array_get";
2398       }
2399     }
2400     else {
2401       if (!DefRNA.silent) {
2402         CLOG_ERROR(&LOG, "\"%s.%s\" not found.", structname, lengthpropname);
2403         DefRNA.error = 1;
2404       }
2405     }
2406   }
2407 }
2408
2409 void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
2410 {
2411   prop->translation_context = context ? context : BLT_I18NCONTEXT_DEFAULT_BPYRNA;
2412 }
2413
2414 /* Functions */
2415
2416 void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable)
2417 {
2418   if (!DefRNA.preprocess) {
2419     CLOG_ERROR(&LOG, "only during preprocessing.");
2420     return;
2421   }
2422
2423   if (editable) {
2424     prop->editable = (EditableFunc)editable;
2425   }
2426 }
2427
2428 void RNA_def_property_editable_array_func(PropertyRNA *prop, const char *editable)
2429 {
2430   if (!DefRNA.preprocess) {
2431     CLOG_ERROR(&LOG, "only during preprocessing.");
2432     return;
2433   }
2434
2435   if (editable) {
2436     prop->itemeditable = (ItemEditableFunc)editable;
2437   }
2438 }
2439
2440 /**
2441  * Set custom callbacks for override operations handling.
2442  *
2443  * \note \a diff callback will also be used by RNA comparison/equality functions.
2444  */
2445 void RNA_def_property_override_funcs(PropertyRNA *prop,
2446                                      const char *diff,
2447                                      const char *store,
2448                                      const char *apply)
2449 {
2450   if (!DefRNA.preprocess) {
2451     CLOG_ERROR(&LOG, "only during preprocessing.");
2452     return;
2453   }
2454
2455   if (diff) {
2456     prop->override_diff = (RNAPropOverrideDiff)diff;
2457   }
2458   if (store) {
2459     prop->override_store = (RNAPropOverrideStore)store;
2460   }
2461   if (apply) {
2462     prop->override_apply = (RNAPropOverrideApply)apply;
2463   }
2464 }
2465
2466 void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *func)
2467 {
2468   if (!DefRNA.preprocess) {
2469     CLOG_ERROR(&LOG, "only during preprocessing.");
2470     return;
2471   }
2472
2473   prop->noteflag = noteflag;
2474   prop->update = (UpdateFunc)func;
2475 }
2476
2477 void RNA_def_property_update_runtime(PropertyRNA *prop, const void *func)
2478 {
2479   prop->update = (void *)func;
2480 }
2481
2482 void RNA_def_property_poll_runtime(PropertyRNA *prop, const void *func)
2483 {
2484   if (prop->type == PROP_POINTER) {
2485     ((PointerPropertyRNA *)prop)->poll = (void *)func;
2486   }
2487   else {
2488     CLOG_ERROR(&LOG, "%s is not a Pointer Property.", prop->identifier);
2489   }
2490 }
2491
2492 void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength)
2493 {
2494   if (!DefRNA.preprocess) {
2495     CLOG_ERROR(&LOG, "only during preprocessing.");
2496     return;
2497   }
2498
2499   if (!(prop->flag & PROP_DYNAMIC)) {
2500     CLOG_ERROR(&LOG, "property is a not dynamic array.");
2501     DefRNA.error = 1;
2502     return;
2503   }
2504
2505   if (getlength) {
2506     prop->getlength = (PropArrayLengthGetFunc)getlength;
2507   }
2508 }
2509
2510 void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set)
2511 {
2512   StructRNA *srna = DefRNA.laststruct;
2513
2514   if (!DefRNA.preprocess) {
2515     CLOG_ERROR(&LOG, "only during preprocessing.");
2516     return;
2517   }
2518
2519   switch (prop->type) {
2520     case PROP_BOOLEAN: {
2521       BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2522
2523       if (prop->arraydimension) {
2524         if (get) {
2525           bprop->getarray = (PropBooleanArrayGetFunc)get;
2526         }
2527         if (set) {
2528           bprop->setarray = (PropBooleanArraySetFunc)set;
2529         }
2530       }
2531       else {
2532         if (get) {
2533           bprop->get = (PropBooleanGetFunc)get;
2534         }
2535         if (set) {
2536           bprop->set = (PropBooleanSetFunc)set;
2537         }
2538       }
2539       break;
2540     }
2541     default:
2542       CLOG_ERROR(&LOG, "\"%s.%s\", type is not boolean.", srna->identifier, prop->identifier);
2543       DefRNA.error = 1;
2544       break;
2545   }
2546 }
2547
2548 void RNA_def_property_boolean_funcs_runtime(PropertyRNA *prop,
2549                                             BooleanPropertyGetFunc getfunc,
2550                                             BooleanPropertySetFunc setfunc)
2551 {
2552   BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2553
2554   if (getfunc) {
2555     bprop->get_ex = getfunc;
2556   }
2557   if (setfunc) {
2558     bprop->set_ex = setfunc;
2559   }
2560
2561   if (getfunc || setfunc) {
2562     /* don't save in id properties */
2563     prop->flag &= ~PROP_IDPROPERTY;
2564
2565     if (!setfunc) {
2566       prop->flag &= ~PROP_EDITABLE;
2567     }
2568   }
2569 }
2570
2571 void RNA_def_property_boolean_array_funcs_runtime(PropertyRNA *prop,
2572                                                   BooleanArrayPropertyGetFunc getfunc,
2573                                                   BooleanArrayPropertySetFunc setfunc)
2574 {
2575   BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
2576
2577   if (getfunc) {
2578     bprop->getarray_ex = getfunc;
2579   }
2580   if (setfunc) {
2581     bprop->setarray_ex = setfunc;
2582   }
2583
2584   if (getfunc || setfunc) {
2585     /* don't save in id properties */
2586     prop->flag &= ~PROP_IDPROPERTY;
2587
2588     if (!setfunc) {
2589       prop->flag &= ~PROP_EDITABLE;
2590     }
2591   }
2592 }
2593
2594 void RNA_def_property_int_funcs(PropertyRNA *prop,
2595                                 const char *get,
2596                                 const char *set,
2597                                 const char *range)
2598 {
2599   StructRNA *srna = DefRNA.laststruct;
2600
2601   if (!DefRNA.preprocess) {
2602     CLOG_ERROR(&LOG, "only during preprocessing.");
2603     return;
2604   }
2605
2606   switch (prop->type) {
2607     case PROP_INT: {
2608       IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2609
2610       if (prop->arraydimension) {
2611         if (get) {
2612           iprop->getarray = (PropIntArrayGetFunc)get;
2613         }
2614         if (set) {
2615           iprop->setarray = (PropIntArraySetFunc)set;
2616         }
2617       }
2618       else {
2619         if (get) {
2620           iprop->get = (PropIntGetFunc)get;
2621         }
2622         if (set) {
2623           iprop->set = (PropIntSetFunc)set;
2624         }
2625       }
2626       if (range) {
2627         iprop->range = (PropIntRangeFunc)range;
2628       }
2629       break;
2630     }
2631     default:
2632       CLOG_ERROR(&LOG, "\"%s.%s\", type is not int.", srna->identifier, prop->identifier);
2633       DefRNA.error = 1;
2634       break;
2635   }
2636 }
2637
2638 void RNA_def_property_int_funcs_runtime(PropertyRNA *prop,
2639                                         IntPropertyGetFunc getfunc,
2640                                         IntPropertySetFunc setfunc,
2641                                         IntPropertyRangeFunc rangefunc)
2642 {
2643   IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2644
2645   if (getfunc) {
2646     iprop->get_ex = getfunc;
2647   }
2648   if (setfunc) {
2649     iprop->set_ex = setfunc;
2650   }
2651   if (rangefunc) {
2652     iprop->range_ex = rangefunc;
2653   }
2654
2655   if (getfunc || setfunc) {
2656     /* don't save in id properties */
2657     prop->flag &= ~PROP_IDPROPERTY;
2658
2659     if (!setfunc) {
2660       prop->flag &= ~PROP_EDITABLE;
2661     }
2662   }
2663 }
2664
2665 void RNA_def_property_int_array_funcs_runtime(PropertyRNA *prop,
2666                                               IntArrayPropertyGetFunc getfunc,
2667                                               IntArrayPropertySetFunc setfunc,
2668                                               IntPropertyRangeFunc rangefunc)
2669 {
2670   IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
2671
2672   if (getfunc) {
2673     iprop->getarray_ex = getfunc;
2674   }
2675   if (setfunc) {
2676     iprop->setarray_ex = setfunc;
2677   }
2678   if (rangefunc) {
2679     iprop->range_ex = rangefunc;
2680   }
2681
2682   if (getfunc || setfunc) {
2683     /* don't save in id properties */
2684     prop->flag &= ~PROP_IDPROPERTY;
2685
2686     if (!setfunc) {
2687       prop->flag &= ~PROP_EDITABLE;
2688     }
2689   }
2690 }
2691
2692 void RNA_def_property_float_funcs(PropertyRNA *prop,
2693                                   const char *get,
2694                                   const char *set,
2695                                   const char *range)
2696 {
2697   StructRNA *srna = DefRNA.laststruct;
2698
2699   if (!DefRNA.preprocess) {
2700     CLOG_ERROR(&LOG, "only during preprocessing.");
2701     return;
2702   }
2703
2704   switch (prop->type) {
2705     case PROP_FLOAT: {
2706       FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2707
2708       if (prop->arraydimension) {
2709         if (get) {
2710           fprop->getarray = (PropFloatArrayGetFunc)get;
2711         }
2712         if (set) {
2713           fprop->setarray = (PropFloatArraySetFunc)set;
2714         }
2715       }
2716       else {
2717         if (get) {
2718           fprop->get = (PropFloatGetFunc)get;
2719         }
2720         if (set) {
2721           fprop->set = (PropFloatSetFunc)set;
2722         }
2723       }
2724       if (range) {
2725         fprop->range = (PropFloatRangeFunc)range;
2726       }
2727       break;
2728     }
2729     default:
2730       CLOG_ERROR(&LOG, "\"%s.%s\", type is not float.", srna->identifier, prop->identifier);
2731       DefRNA.error = 1;
2732       break;
2733   }
2734 }
2735
2736 void RNA_def_property_float_funcs_runtime(PropertyRNA *prop,
2737                                           FloatPropertyGetFunc getfunc,
2738                                           FloatPropertySetFunc setfunc,
2739                                           FloatPropertyRangeFunc rangefunc)
2740 {
2741   FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2742
2743   if (getfunc) {
2744     fprop->get_ex = getfunc;
2745   }
2746   if (setfunc) {
2747     fprop->set_ex = setfunc;
2748   }
2749   if (rangefunc) {
2750     fprop->range_ex = rangefunc;
2751   }
2752
2753   if (getfunc || setfunc) {
2754     /* don't save in id properties */
2755     prop->flag &= ~PROP_IDPROPERTY;
2756
2757     if (!setfunc) {
2758       prop->flag &= ~PROP_EDITABLE;
2759     }
2760   }
2761 }
2762
2763 void RNA_def_property_float_array_funcs_runtime(PropertyRNA *prop,
2764                                                 FloatArrayPropertyGetFunc getfunc,
2765                                                 FloatArrayPropertySetFunc setfunc,
2766                                                 FloatPropertyRangeFunc rangefunc)
2767 {
2768   FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
2769
2770   if (getfunc) {
2771     fprop->getarray_ex = getfunc;
2772   }
2773   if (setfunc) {
2774     fprop->setarray_ex = setfunc;
2775   }
2776   if (rangefunc) {
2777     fprop->range_ex = rangefunc;
2778   }
2779
2780   if (getfunc || setfunc) {
2781     /* don't save in id properties */
2782     prop->flag &= ~PROP_IDPROPERTY;
2783
2784     if (!setfunc) {
2785       prop->flag &= ~PROP_EDITABLE;
2786     }
2787   }
2788 }
2789
2790 void RNA_def_property_enum_funcs(PropertyRNA *prop,
2791                                  const char *get,
2792                                  const char *set,
2793                                  const char *item)
2794 {
2795   StructRNA *srna = DefRNA.laststruct;
2796
2797   if (!DefRNA.preprocess) {
2798     CLOG_ERROR(&LOG, "only during preprocessing.");
2799     return;
2800   }
2801
2802   switch (prop->type) {
2803     case PROP_ENUM: {
2804       EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2805
2806       if (get) {
2807         eprop->get = (PropEnumGetFunc)get;
2808       }
2809       if (set) {
2810         eprop->set = (PropEnumSetFunc)set;
2811       }
2812       if (item) {
2813         eprop->itemf = (PropEnumItemFunc)item;
2814       }
2815       break;
2816     }
2817     default:
2818       CLOG_ERROR(&LOG, "\"%s.%s\", type is not enum.", srna->identifier, prop->identifier);
2819       DefRNA.error = 1;
2820       break;
2821   }
2822 }
2823
2824 void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop,
2825                                          EnumPropertyGetFunc getfunc,
2826                                          EnumPropertySetFunc setfunc,
2827                                          EnumPropertyItemFunc itemfunc)
2828 {
2829   EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2830
2831   if (getfunc) {
2832     eprop->get_ex = getfunc;
2833   }
2834   if (setfunc) {
2835     eprop->set_ex = setfunc;
2836   }
2837   if (itemfunc) {
2838     eprop->itemf = itemfunc;
2839   }
2840
2841   if (getfunc || setfunc) {
2842     /* don't save in id properties */
2843     prop->flag &= ~PROP_IDPROPERTY;
2844
2845     if (!setfunc) {
2846       prop->flag &= ~PROP_EDITABLE;
2847     }
2848   }
2849 }
2850
2851 void RNA_def_property_enum_py_data(PropertyRNA *prop, void *py_data)
2852 {
2853   EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
2854   eprop->py_data = py_data;
2855 }
2856
2857 void RNA_def_property_string_funcs(PropertyRNA *prop,
2858                                    const char *get,
2859                                    const char *length,
2860                                    const char *set)
2861 {
2862   StructRNA *srna = DefRNA.laststruct;
2863
2864   if (!DefRNA.preprocess) {
2865     CLOG_ERROR(&LOG, "only during preprocessing.");
2866     return;
2867   }
2868
2869   switch (prop->type) {
2870     case PROP_STRING: {
2871       StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2872
2873       if (get) {
2874         sprop->get = (PropStringGetFunc)get;
2875       }
2876       if (length) {
2877         sprop->length = (PropStringLengthFunc)length;
2878       }
2879       if (set) {
2880         sprop->set = (PropStringSetFunc)set;
2881       }
2882       break;
2883     }
2884     default:
2885       CLOG_ERROR(&LOG, "\"%s.%s\", type is not string.", srna->identifier, prop->identifier);
2886       DefRNA.error = 1;
2887       break;
2888   }
2889 }
2890
2891 void RNA_def_property_string_funcs_runtime(PropertyRNA *prop,
2892                                            StringPropertyGetFunc getfunc,
2893                                            StringPropertyLengthFunc lengthfunc,
2894                                            StringPropertySetFunc setfunc)
2895 {
2896   StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
2897
2898   if (getfunc) {
2899     sprop->get_ex = getfunc;
2900   }
2901   if (lengthfunc) {
2902     sprop->length_ex = lengthfunc;
2903   }
2904   if (setfunc) {
2905     sprop->set_ex = setfunc;
2906   }
2907
2908   if (getfunc || setfunc) {
2909     /* don't save in id properties */
2910     prop->flag &= ~PROP_IDPROPERTY;
2911
2912     if (!setfunc) {
2913       prop->flag &= ~PROP_EDITABLE;
2914     }
2915   }
2916 }
2917
2918 void RNA_def_property_pointer_funcs(
2919     PropertyRNA *prop, const char *get, const char *set, const char *typef, const char *poll)
2920 {
2921   StructRNA *srna = DefRNA.laststruct;
2922
2923   if (!DefRNA.preprocess) {
2924     CLOG_ERROR(&LOG, "only during preprocessing.");
2925     return;
2926   }
2927
2928   switch (prop->type) {
2929     case PROP_POINTER: {
2930       PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
2931
2932       if (get) {
2933         pprop->get = (PropPointerGetFunc)get;
2934       }
2935       if (set) {
2936         pprop->set = (PropPointerSetFunc)set;
2937       }
2938       if (typef) {
2939         pprop->typef = (PropPointerTypeFunc)typef;
2940       }
2941       if (poll) {
2942         pprop->poll = (PropPointerPollFunc)poll;
2943       }
2944       break;
2945     }
2946     default:
2947       CLOG_ERROR(&LOG, "\"%s.%s\", type is not pointer.", srna->identifier, prop->identifier);
2948       DefRNA.error = 1;
2949       break;
2950   }
2951 }
2952
2953 void RNA_def_property_collection_funcs(PropertyRNA *prop,
2954                                        const char *begin,
2955                                        const char *next,
2956                                        const char *end,
2957                                        const char *get,
2958                                        const char *length,
2959                                        const char *lookupint,
2960                                        const char *lookupstring,
2961                                        const char *assignint)
2962 {
2963   StructRNA *srna = DefRNA.laststruct;
2964
2965   if (!DefRNA.preprocess) {
2966     CLOG_ERROR(&LOG, "only during preprocessing.");
2967     return;
2968   }
2969
2970   switch (prop->type) {
2971     case PROP_COLLECTION: {
2972       CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop;
2973
2974       if (begin) {
2975         cprop->begin = (PropCollectionBeginFunc)begin;
2976       }
2977       if (next) {
2978         cprop->next = (PropCollectionNextFunc)next;
2979       }
2980       if (end) {
2981         cprop->end = (PropCollectionEndFunc)end;
2982       }
2983       if (get) {
2984         cprop->get = (PropCollectionGetFunc)get;
2985       }
2986       if (length) {
2987         cprop->length = (PropCollectionLengthFunc)length;
2988       }
2989       if (lookupint) {
2990         cprop->lookupint = (PropCollectionLookupIntFunc)lookupint;
2991       }
2992       if (lookupstring) {
2993         cprop->lookupstring = (PropCollectionLookupStringFunc)lookupstring;
2994       }
2995       if (assignint) {
2996         cprop->assignint = (PropCollectionAssignIntFunc)assignint;
2997       }
2998       break;
2999     }
3000     default:
3001       CLOG_ERROR(&LOG, "\"%s.%s\", type is not collection.", srna->identifier, prop->identifier);
3002       DefRNA.error = 1;
3003       break;
3004   }
3005 }
3006
3007 void RNA_def_property_srna(PropertyRNA *prop, const char *type)
3008 {
3009   prop->srna = (StructRNA *)type;
3010 }
3011
3012 void RNA_def_py_data(PropertyRNA *prop, void *py_data)
3013 {
3014   prop->py_data = py_data;
3015 }
3016
3017 /* Compact definitions */
3018
3019 PropertyRNA *RNA_def_boolean(StructOrFunctionRNA *cont_,
3020                              const char *identifier,
3021                              bool default_value,
3022                              const char *ui_name,
3023                              const char *ui_description)
3024 {
3025   ContainerRNA *cont = cont_;
3026   PropertyRNA *prop;
3027
3028   prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_NONE);
3029   RNA_def_property_boolean_default(prop, default_value);
3030   RNA_def_property_ui_text(prop, ui_name, ui_description);
3031
3032   return prop;
3033 }
3034
3035 PropertyRNA *RNA_def_boolean_array(StructOrFunctionRNA *cont_,
3036                                    const char *identifier,
3037                                    int len,
3038                                    bool *default_value,
3039                                    const char *ui_name,
3040                                    const char *ui_description)
3041 {
3042   ContainerRNA *cont = cont_;
3043   PropertyRNA *prop;
3044
3045   prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_NONE);
3046   if (len != 0) {
3047     RNA_def_property_array(prop, len);
3048   }
3049   if (default_value) {
3050     RNA_def_property_boolean_array_default(prop, default_value);
3051   }
3052   RNA_def_property_ui_text(prop, ui_name, ui_description);
3053
3054   return prop;
3055 }
3056
3057 PropertyRNA *RNA_def_boolean_layer(StructOrFunctionRNA *cont_,
3058                                    const char *identifier,
3059                                    int len,
3060                                    bool *default_value,
3061                                    const char *ui_name,
3062                                    const char *ui_description)
3063 {
3064   ContainerRNA *cont = cont_;
3065   PropertyRNA *prop;
3066
3067   prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_LAYER);
3068   if (len != 0) {
3069     RNA_def_property_array(prop, len);
3070   }
3071   if (default_value) {
3072     RNA_def_property_boolean_array_default(prop, default_value);
3073   }
3074   RNA_def_property_ui_text(prop, ui_name, ui_description);
3075
3076   return prop;
3077 }
3078
3079 PropertyRNA *RNA_def_boolean_layer_member(StructOrFunctionRNA *cont_,
3080                                           const char *identifier,
3081                                           int len,
3082                                           bool *default_value,
3083                                           const char *ui_name,
3084                                           const char *ui_description)
3085 {
3086   ContainerRNA *cont = cont_;
3087   PropertyRNA *prop;
3088
3089   prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_LAYER_MEMBER);
3090   if (len != 0) {
3091     RNA_def_property_array(prop, len);
3092   }
3093   if (default_value) {
3094     RNA_def_property_boolean_array_default(prop, default_value);
3095   }
3096   RNA_def_property_ui_text(prop, ui_name, ui_description);
3097
3098   return prop;
3099 }
3100
3101 PropertyRNA *RNA_def_boolean_vector(StructOrFunctionRNA *cont_,
3102                                     const char *identifier,
3103                                     int len,
3104                                     bool *default_value,
3105                                     const char *ui_name,
3106                                     const char *ui_description)
3107 {
3108   ContainerRNA *cont = cont_;
3109   PropertyRNA *prop;
3110
3111   prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_XYZ); /* XXX */
3112   if (len != 0) {
3113     RNA_def_property_array(prop, len);
3114   }
3115   if (default_value) {
3116     RNA_def_property_boolean_array_default(prop, default_value);
3117   }
3118   RNA_def_property_ui_text(prop, ui_name, ui_description);
3119
3120   return prop;
3121 }
3122
3123 PropertyRNA *RNA_def_int(StructOrFunctionRNA *cont_,
3124                          const char *identifier,
3125                          int default_value,
3126                          int hardmin,
3127                          int hardmax,
3128                          const char *ui_name,
3129                          const char *ui_description,
3130                          int softmin,
3131                          int softmax)
3132 {
3133   ContainerRNA *cont = cont_;
3134   PropertyRNA *prop;
3135
3136   ASSERT_SOFT_HARD_LIMITS;
3137
3138   prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE);
3139   RNA_def_property_int_default(prop, default_value);
3140   if (hardmin != hardmax) {
3141     RNA_def_property_range(prop, hardmin, hardmax);
3142   }
3143   RNA_def_property_ui_text(prop, ui_name, ui_description);
3144   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3145
3146   return prop;
3147 }
3148
3149 PropertyRNA *RNA_def_int_vector(StructOrFunctionRNA *cont_,
3150                                 const char *identifier,
3151                                 int len,
3152                                 const int *default_value,
3153                                 int hardmin,
3154                                 int hardmax,
3155                                 const char *ui_name,
3156                                 const char *ui_description,
3157                                 int softmin,
3158                                 int softmax)
3159 {
3160   ContainerRNA *cont = cont_;
3161   PropertyRNA *prop;
3162
3163   ASSERT_SOFT_HARD_LIMITS;
3164
3165   prop = RNA_def_property(cont, identifier, PROP_INT, PROP_XYZ); /* XXX */
3166   if (len != 0) {
3167     RNA_def_property_array(prop, len);
3168   }
3169   if (default_value) {
3170     RNA_def_property_int_array_default(prop, default_value);
3171   }
3172   if (hardmin != hardmax) {
3173     RNA_def_property_range(prop, hardmin, hardmax);
3174   }
3175   RNA_def_property_ui_text(prop, ui_name, ui_description);
3176   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3177
3178   return prop;
3179 }
3180
3181 PropertyRNA *RNA_def_int_array(StructOrFunctionRNA *cont_,
3182                                const char *identifier,
3183                                int len,
3184                                const int *default_value,
3185                                int hardmin,
3186                                int hardmax,
3187                                const char *ui_name,
3188                                const char *ui_description,
3189                                int softmin,
3190                                int softmax)
3191 {
3192   ContainerRNA *cont = cont_;
3193   PropertyRNA *prop;
3194
3195   ASSERT_SOFT_HARD_LIMITS;
3196
3197   prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE);
3198   if (len != 0) {
3199     RNA_def_property_array(prop, len);
3200   }
3201   if (default_value) {
3202     RNA_def_property_int_array_default(prop, default_value);
3203   }
3204   if (hardmin != hardmax) {
3205     RNA_def_property_range(prop, hardmin, hardmax);
3206   }
3207   RNA_def_property_ui_text(prop, ui_name, ui_description);
3208   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3209
3210   return prop;
3211 }
3212
3213 PropertyRNA *RNA_def_string(StructOrFunctionRNA *cont_,
3214                             const char *identifier,
3215                             const char *default_value,
3216                             int maxlen,
3217                             const char *ui_name,
3218                             const char *ui_description)
3219 {
3220   ContainerRNA *cont = cont_;
3221   PropertyRNA *prop;
3222
3223   BLI_assert(default_value == NULL || default_value[0]);
3224
3225   prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_NONE);
3226   if (maxlen != 0) {
3227     RNA_def_property_string_maxlength(prop, maxlen);
3228   }
3229   if (default_value) {
3230     RNA_def_property_string_default(prop, default_value);
3231   }
3232   RNA_def_property_ui_text(prop, ui_name, ui_description);
3233
3234   return prop;
3235 }
3236
3237 PropertyRNA *RNA_def_string_file_path(StructOrFunctionRNA *cont_,
3238                                       const char *identifier,
3239                                       const char *default_value,
3240                                       int maxlen,
3241                                       const char *ui_name,
3242                                       const char *ui_description)
3243 {
3244   ContainerRNA *cont = cont_;
3245   PropertyRNA *prop;
3246
3247   BLI_assert(default_value == NULL || default_value[0]);
3248
3249   prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_FILEPATH);
3250   if (maxlen != 0) {
3251     RNA_def_property_string_maxlength(prop, maxlen);
3252   }
3253   if (default_value) {
3254     RNA_def_property_string_default(prop, default_value);
3255   }
3256   RNA_def_property_ui_text(prop, ui_name, ui_description);
3257
3258   return prop;
3259 }
3260
3261 PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont_,
3262                                      const char *identifier,
3263                                      const char *default_value,
3264                                      int maxlen,
3265                                      const char *ui_name,
3266                                      const char *ui_description)
3267 {
3268   ContainerRNA *cont = cont_;
3269   PropertyRNA *prop;
3270
3271   BLI_assert(default_value == NULL || default_value[0]);
3272
3273   prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_DIRPATH);
3274   if (maxlen != 0) {
3275     RNA_def_property_string_maxlength(prop, maxlen);
3276   }
3277   if (default_value) {
3278     RNA_def_property_string_default(prop, default_value);
3279   }
3280   RNA_def_property_ui_text(prop, ui_name, ui_description);
3281
3282   return prop;
3283 }
3284
3285 PropertyRNA *RNA_def_string_file_name(StructOrFunctionRNA *cont_,
3286                                       const char *identifier,
3287                                       const char *default_value,
3288                                       int maxlen,
3289                                       const char *ui_name,
3290                                       const char *ui_description)
3291 {
3292   ContainerRNA *cont = cont_;
3293   PropertyRNA *prop;
3294
3295   BLI_assert(default_value == NULL || default_value[0]);
3296
3297   prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_FILENAME);
3298   if (maxlen != 0) {
3299     RNA_def_property_string_maxlength(prop, maxlen);
3300   }
3301   if (default_value) {
3302     RNA_def_property_string_default(prop, default_value);
3303   }
3304   RNA_def_property_ui_text(prop, ui_name, ui_description);
3305
3306   return prop;
3307 }
3308
3309 PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_,
3310                           const char *identifier,
3311                           const EnumPropertyItem *items,
3312                           int default_value,
3313                           const char *ui_name,
3314                           const char *ui_description)
3315 {
3316   ContainerRNA *cont = cont_;
3317   PropertyRNA *prop;
3318
3319   if (!items) {
3320     CLOG_ERROR(&LOG, "items not allowed to be NULL.");
3321     return NULL;
3322   }
3323
3324   prop = RNA_def_property(cont, identifier, PROP_ENUM, PROP_NONE);
3325   if (items) {
3326     RNA_def_property_enum_items(prop, items);
3327   }
3328   RNA_def_property_enum_default(prop, default_value);
3329   RNA_def_property_ui_text(prop, ui_name, ui_description);
3330
3331   return prop;
3332 }
3333
3334 /* same as above but sets 'PROP_ENUM_FLAG' before setting the default value */
3335 PropertyRNA *RNA_def_enum_flag(StructOrFunctionRNA *cont_,
3336                                const char *identifier,
3337                                const EnumPropertyItem *items,
3338                                int default_value,
3339                                const char *ui_name,
3340                                const char *ui_description)
3341 {
3342   ContainerRNA *cont = cont_;
3343   PropertyRNA *prop;
3344
3345   if (!items) {
3346     CLOG_ERROR(&LOG, "items not allowed to be NULL.");
3347     return NULL;
3348   }
3349
3350   prop = RNA_def_property(cont, identifier, PROP_ENUM, PROP_NONE);
3351   RNA_def_property_flag(prop, PROP_ENUM_FLAG); /* important to run before default set */
3352   if (items) {
3353     RNA_def_property_enum_items(prop, items);
3354   }
3355   RNA_def_property_enum_default(prop, default_value);
3356   RNA_def_property_ui_text(prop, ui_name, ui_description);
3357
3358   return prop;
3359 }
3360
3361 void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
3362 {
3363   EnumPropertyRNA *eprop = (EnumPropertyRNA *)prop;
3364   eprop->itemf = itemfunc;
3365 }
3366
3367 PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont_,
3368                            const char *identifier,
3369                            float default_value,
3370                            float hardmin,
3371                            float hardmax,
3372                            const char *ui_name,
3373                            const char *ui_description,
3374                            float softmin,
3375                            float softmax)
3376 {
3377   ContainerRNA *cont = cont_;
3378   PropertyRNA *prop;
3379
3380   ASSERT_SOFT_HARD_LIMITS;
3381
3382   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE);
3383   RNA_def_property_float_default(prop, default_value);
3384   if (hardmin != hardmax) {
3385     RNA_def_property_range(prop, hardmin, hardmax);
3386   }
3387   RNA_def_property_ui_text(prop, ui_name, ui_description);
3388   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3389
3390   return prop;
3391 }
3392
3393 PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont_,
3394                                   const char *identifier,
3395                                   int len,
3396                                   const float *default_value,
3397                                   float hardmin,
3398                                   float hardmax,
3399                                   const char *ui_name,
3400                                   const char *ui_description,
3401                                   float softmin,
3402                                   float softmax)
3403 {
3404   ContainerRNA *cont = cont_;
3405   PropertyRNA *prop;
3406
3407   ASSERT_SOFT_HARD_LIMITS;
3408
3409   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_XYZ);
3410   if (len != 0) {
3411     RNA_def_property_array(prop, len);
3412   }
3413   if (default_value) {
3414     RNA_def_property_float_array_default(prop, default_value);
3415   }
3416   if (hardmin != hardmax) {
3417     RNA_def_property_range(prop, hardmin, hardmax);
3418   }
3419   RNA_def_property_ui_text(prop, ui_name, ui_description);
3420   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3421
3422   return prop;
3423 }
3424
3425 PropertyRNA *RNA_def_float_vector_xyz(StructOrFunctionRNA *cont_,
3426                                       const char *identifier,
3427                                       int len,
3428                                       const float *default_value,
3429                                       float hardmin,
3430                                       float hardmax,
3431                                       const char *ui_name,
3432                                       const char *ui_description,
3433                                       float softmin,
3434                                       float softmax)
3435 {
3436   PropertyRNA *prop;
3437
3438   prop = RNA_def_float_vector(cont_,
3439                               identifier,
3440                               len,
3441                               default_value,
3442                               hardmin,
3443                               hardmax,
3444                               ui_name,
3445                               ui_description,
3446                               softmin,
3447                               softmax);
3448   prop->subtype = PROP_XYZ_LENGTH;
3449
3450   return prop;
3451 }
3452
3453 PropertyRNA *RNA_def_float_color(StructOrFunctionRNA *cont_,
3454                                  const char *identifier,
3455                                  int len,
3456                                  const float *default_value,
3457                                  float hardmin,
3458                                  float hardmax,
3459                                  const char *ui_name,
3460                                  const char *ui_description,
3461                                  float softmin,
3462                                  float softmax)
3463 {
3464   ContainerRNA *cont = cont_;
3465   PropertyRNA *prop;
3466
3467   ASSERT_SOFT_HARD_LIMITS;
3468
3469   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_COLOR);
3470   if (len != 0) {
3471     RNA_def_property_array(prop, len);
3472   }
3473   if (default_value) {
3474     RNA_def_property_float_array_default(prop, default_value);
3475   }
3476   if (hardmin != hardmax) {
3477     RNA_def_property_range(prop, hardmin, hardmax);
3478   }
3479   RNA_def_property_ui_text(prop, ui_name, ui_description);
3480   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3481
3482   return prop;
3483 }
3484
3485 PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont_,
3486                                   const char *identifier,
3487                                   int rows,
3488                                   int columns,
3489                                   const float *default_value,
3490                                   float hardmin,
3491                                   float hardmax,
3492                                   const char *ui_name,
3493                                   const char *ui_description,
3494                                   float softmin,
3495                                   float softmax)
3496 {
3497   ContainerRNA *cont = cont_;
3498   PropertyRNA *prop;
3499   const int length[2] = {rows, columns};
3500
3501   ASSERT_SOFT_HARD_LIMITS;
3502
3503   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_MATRIX);
3504   RNA_def_property_multi_array(prop, 2, length);
3505   if (default_value) {
3506     RNA_def_property_float_array_default(prop, default_value);
3507   }
3508   if (hardmin != hardmax) {
3509     RNA_def_property_range(prop, hardmin, hardmax);
3510   }
3511   RNA_def_property_ui_text(prop, ui_name, ui_description);
3512   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3513
3514   return prop;
3515 }
3516
3517 PropertyRNA *RNA_def_float_rotation(StructOrFunctionRNA *cont_,
3518                                     const char *identifier,
3519                                     int len,
3520                                     const float *default_value,
3521                                     float hardmin,
3522                                     float hardmax,
3523                                     const char *ui_name,
3524                                     const char *ui_description,
3525                                     float softmin,
3526                                     float softmax)
3527 {
3528   ContainerRNA *cont = cont_;
3529   PropertyRNA *prop;
3530
3531   ASSERT_SOFT_HARD_LIMITS;
3532
3533   prop = RNA_def_property(cont, identifier, PROP_FLOAT, (len >= 3) ? PROP_EULER : PROP_ANGLE);
3534   if (len != 0) {
3535     RNA_def_property_array(prop, len);
3536     if (default_value) {
3537       RNA_def_property_float_array_default(prop, default_value);
3538     }
3539   }
3540   else {
3541     /* RNA_def_property_float_default must be called outside */
3542     BLI_assert(default_value == NULL);
3543   }
3544   if (hardmin != hardmax) {
3545     RNA_def_property_range(prop, hardmin, hardmax);
3546   }
3547   RNA_def_property_ui_text(prop, ui_name, ui_description);
3548   RNA_def_property_ui_range(prop, softmin, softmax, 10, 3);
3549
3550   return prop;
3551 }
3552
3553 PropertyRNA *RNA_def_float_distance(StructOrFunctionRNA *cont_,
3554                                     const char *identifier,
3555                                     float default_value,
3556                                     float hardmin,
3557                                     float hardmax,
3558                                     const char *ui_name,
3559                                     const char *ui_description,
3560                                     float softmin,
3561                                     float softmax)
3562 {
3563   PropertyRNA *prop = RNA_def_float(cont_,
3564                                     identifier,
3565                                     default_value,
3566                                     hardmin,
3567                                     hardmax,
3568                                     ui_name,
3569                                     ui_description,
3570                                     softmin,
3571                                     softmax);
3572   RNA_def_property_subtype(prop, PROP_DISTANCE);
3573
3574   return prop;
3575 }
3576
3577 PropertyRNA *RNA_def_float_array(StructOrFunctionRNA *cont_,
3578                                  const char *identifier,
3579                                  int len,
3580                                  const float *default_value,
3581                                  float hardmin,
3582                                  float hardmax,
3583                                  const char *ui_name,
3584                                  const char *ui_description,
3585                                  float softmin,
3586                                  float softmax)
3587 {
3588   ContainerRNA *cont = cont_;
3589   PropertyRNA *prop;
3590
3591   ASSERT_SOFT_HARD_LIMITS;
3592
3593   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE);
3594   if (len != 0) {
3595     RNA_def_property_array(prop, len);
3596   }
3597   if (default_value) {
3598     RNA_def_property_float_array_default(prop, default_value);
3599   }
3600   if (hardmin != hardmax) {
3601     RNA_def_property_range(prop, hardmin, hardmax);
3602   }
3603   RNA_def_property_ui_text(prop, ui_name, ui_description);
3604   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3605
3606   return prop;
3607 }
3608
3609 PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont_,
3610                                       const char *identifier,
3611                                       float default_value,
3612                                       float hardmin,
3613                                       float hardmax,
3614                                       const char *ui_name,
3615                                       const char *ui_description,
3616                                       float softmin,
3617                                       float softmax)
3618 {
3619   ContainerRNA *cont = cont_;
3620   PropertyRNA *prop;
3621
3622   ASSERT_SOFT_HARD_LIMITS;
3623
3624   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_PERCENTAGE);
3625   RNA_def_property_float_default(prop, default_value);
3626   if (hardmin != hardmax) {
3627     RNA_def_property_range(prop, hardmin, hardmax);
3628   }
3629   RNA_def_property_ui_text(prop, ui_name, ui_description);
3630   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3631
3632   return prop;
3633 }
3634
3635 PropertyRNA *RNA_def_float_factor(StructOrFunctionRNA *cont_,
3636                                   const char *identifier,
3637                                   float default_value,
3638                                   float hardmin,
3639                                   float hardmax,
3640                                   const char *ui_name,
3641                                   const char *ui_description,
3642                                   float softmin,
3643                                   float softmax)
3644 {
3645   ContainerRNA *cont = cont_;
3646   PropertyRNA *prop;
3647
3648   ASSERT_SOFT_HARD_LIMITS;
3649
3650   prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_FACTOR);
3651   RNA_def_property_float_default(prop, default_value);
3652   if (hardmin != hardmax) {
3653     RNA_def_property_range(prop, hardmin, hardmax);
3654   }
3655   RNA_def_property_ui_text(prop, ui_name, ui_description);
3656   RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
3657
3658   return prop;
3659 }
3660
3661 PropertyRNA *RNA_def_pointer(StructOrFunctionRNA *cont_,
3662                              const char *identifier,
3663                              const char *type,
3664                              const char *ui_name,
3665                              const char *ui_description)
3666 {
3667   ContainerRNA *cont = cont_;
3668   PropertyRNA *prop;
3669
3670   prop = RNA_def_property(cont, identifier, PROP_POINTER, PROP_NONE);
3671   RNA_def_property_struct_type(prop, type);
3672   RNA_def_property_ui_text(prop, ui_name, ui_description);
3673
3674   return prop;
3675 }
3676
3677 PropertyRNA *RNA_def_pointer_runtime(StructOrFunctionRNA *cont_,
3678                                      const char *identifier,
3679                                      StructRNA *type,