e106f8236c9a68692435ab4e2dd12fa0268a255a
[blender.git] / source / blender / makesrna / intern / rna_define.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Blender Foundation (2008).
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/makesrna/intern/rna_define.c
24  *  \ingroup RNA
25  */
26
27
28 #include <float.h>
29 #include <limits.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <ctype.h>
34
35 #include "MEM_guardedalloc.h"
36
37 #include "DNA_genfile.h"
38 #include "DNA_sdna_types.h"
39
40 #include "BLI_utildefines.h"
41 #include "BLI_ghash.h"
42
43 #include "RNA_define.h"
44
45 #include "rna_internal.h"
46
47 /* Global used during defining */
48
49 BlenderDefRNA DefRNA = {NULL, {NULL, NULL}, {NULL, NULL}, NULL, 0, 0, 0, 1};
50
51 /* Duplicated code since we can't link in blenkernel or blenlib */
52
53 #ifndef MIN2
54 #define MIN2(x,y) ((x)<(y)? (x): (y))
55 #define MAX2(x,y) ((x)>(y)? (x): (y))
56 #endif
57
58 /* pedantic check for '.', do this since its a hassle for translators */
59 #ifndef NDEBUG
60 #  define DESCR_CHECK(description, id1, id2)                                  \
61         if (description && (description)[0]) {                                    \
62                 int i = strlen(description);                                          \
63                 if ((description)[i - 1] == '.') {                                    \
64                         fprintf(stderr, "%s: '%s' '%s' description ends with a '.' !\n",  \
65                                 __func__, id1 ? id1 : "", id2 ? id2 : "");                \
66                 }                                                                     \
67         }                                                                         \
68
69 #else
70 #  define DESCR_CHECK(description, id1, id2)
71 #endif
72
73 void rna_addtail(ListBase *listbase, void *vlink)
74 {
75         Link *link = vlink;
76
77         link->next = NULL;
78         link->prev = listbase->last;
79
80         if (listbase->last) ((Link *)listbase->last)->next = link;
81         if (listbase->first == NULL) listbase->first = link;
82         listbase->last = link;
83 }
84
85 static void rna_remlink(ListBase *listbase, void *vlink)
86 {
87         Link *link = vlink;
88
89         if (link->next) link->next->prev = link->prev;
90         if (link->prev) link->prev->next = link->next;
91
92         if (listbase->last == link) listbase->last = link->prev;
93         if (listbase->first == link) listbase->first = link->next;
94 }
95
96 PropertyDefRNA *rna_findlink(ListBase *listbase, const char *identifier)
97 {
98         Link *link;
99
100         for (link = listbase->first; link; link = link->next) {
101                 PropertyRNA *prop = ((PropertyDefRNA *)link)->prop;
102                 if (prop && (strcmp(prop->identifier, identifier) == 0)) {
103                         return (PropertyDefRNA *)link;
104                 }
105         }
106
107         return NULL;
108 }
109
110 void rna_freelinkN(ListBase *listbase, void *vlink)
111 {
112         rna_remlink(listbase, vlink);
113         MEM_freeN(vlink);
114 }
115
116 void rna_freelistN(ListBase *listbase)
117 {
118         Link *link, *next;
119         
120         for (link = listbase->first; link; link = next) {
121                 next = link->next;
122                 MEM_freeN(link);
123         }
124         
125         listbase->first = listbase->last = NULL;
126 }
127
128 StructDefRNA *rna_find_struct_def(StructRNA *srna)
129 {
130         StructDefRNA *dsrna;
131
132         if (!DefRNA.preprocess) {
133                 /* we should never get here */
134                 fprintf(stderr, "%s: only at preprocess time.\n", __func__);
135                 return NULL;
136         }
137
138         dsrna = DefRNA.structs.last;
139         for (; dsrna; dsrna = dsrna->cont.prev)
140                 if (dsrna->srna == srna)
141                         return dsrna;
142
143         return NULL;
144 }
145
146 PropertyDefRNA *rna_find_struct_property_def(StructRNA *srna, PropertyRNA *prop)
147 {
148         StructDefRNA *dsrna;
149         PropertyDefRNA *dprop;
150
151         if (!DefRNA.preprocess) {
152                 /* we should never get here */
153                 fprintf(stderr, "%s: only at preprocess time.\n", __func__);
154                 return NULL;
155         }
156
157         dsrna = rna_find_struct_def(srna);
158         dprop = dsrna->cont.properties.last;
159         for (; dprop; dprop = dprop->prev)
160                 if (dprop->prop == prop)
161                         return dprop;
162
163         dsrna = DefRNA.structs.last;
164         for (; dsrna; dsrna = dsrna->cont.prev) {
165                 dprop = dsrna->cont.properties.last;
166                 for (; dprop; dprop = dprop->prev)
167                         if (dprop->prop == prop)
168                                 return dprop;
169         }
170
171         return NULL;
172 }
173
174 #if 0
175 static PropertyDefRNA *rna_find_property_def(PropertyRNA *prop)
176 {
177         PropertyDefRNA *dprop;
178
179         if (!DefRNA.preprocess) {
180                 /* we should never get here */
181                 fprintf(stderr, "%s: only at preprocess time.\n", __func__);
182                 return NULL;
183         }
184
185         dprop = rna_find_struct_property_def(DefRNA.laststruct, prop);
186         if (dprop)
187                 return dprop;
188
189         dprop = rna_find_parameter_def(prop);
190         if (dprop)
191                 return dprop;
192
193         return NULL;
194 }
195 #endif
196
197 FunctionDefRNA *rna_find_function_def(FunctionRNA *func)
198 {
199         StructDefRNA *dsrna;
200         FunctionDefRNA *dfunc;
201
202         if (!DefRNA.preprocess) {
203                 /* we should never get here */
204                 fprintf(stderr, "%s: only at preprocess time.\n", __func__);
205                 return NULL;
206         }
207
208         dsrna = rna_find_struct_def(DefRNA.laststruct);
209         dfunc = dsrna->functions.last;
210         for (; dfunc; dfunc = dfunc->cont.prev)
211                 if (dfunc->func == func)
212                         return dfunc;
213
214         dsrna = DefRNA.structs.last;
215         for (; dsrna; dsrna = dsrna->cont.prev) {
216                 dfunc = dsrna->functions.last;
217                 for (; dfunc; dfunc = dfunc->cont.prev)
218                         if (dfunc->func == func)
219                                 return dfunc;
220         }
221
222         return NULL;
223 }
224
225 PropertyDefRNA *rna_find_parameter_def(PropertyRNA *parm)
226 {
227         StructDefRNA *dsrna;
228         FunctionDefRNA *dfunc;
229         PropertyDefRNA *dparm;
230
231         if (!DefRNA.preprocess) {
232                 /* we should never get here */
233                 fprintf(stderr, "%s: only at preprocess time.\n", __func__);
234                 return NULL;
235         }
236
237         dsrna = rna_find_struct_def(DefRNA.laststruct);
238         dfunc = dsrna->functions.last;
239         for (; dfunc; dfunc = dfunc->cont.prev) {
240                 dparm = dfunc->cont.properties.last;
241                 for (; dparm; dparm = dparm->prev)
242                         if (dparm->prop == parm)
243                                 return dparm;
244         }
245
246         dsrna = DefRNA.structs.last;
247         for (; dsrna; dsrna = dsrna->cont.prev) {
248                 dfunc = dsrna->functions.last;
249                 for (; dfunc; dfunc = dfunc->cont.prev) {
250                         dparm = dfunc->cont.properties.last;
251                         for (; dparm; dparm = dparm->prev)
252                                 if (dparm->prop == parm)
253                                         return dparm;
254                 }
255         }
256
257         return NULL;
258 }
259
260 static ContainerDefRNA *rna_find_container_def(ContainerRNA *cont)
261 {
262         StructDefRNA *ds;
263         FunctionDefRNA *dfunc;
264
265         if (!DefRNA.preprocess) {
266                 /* we should never get here */
267                 fprintf(stderr, "%s: only at preprocess time.\n", __func__);
268                 return NULL;
269         }
270
271         ds = rna_find_struct_def((StructRNA*)cont);
272         if (ds)
273                 return &ds->cont;
274
275         dfunc = rna_find_function_def((FunctionRNA*)cont);
276         if (dfunc)
277                 return &dfunc->cont;
278
279         return NULL;
280 }
281
282 /* DNA utility function for looking up members */
283
284 typedef struct DNAStructMember {
285         const char *type;
286         const char *name;
287         int arraylength;
288         int pointerlevel;
289 } DNAStructMember;
290
291 static int rna_member_cmp(const char *name, const char *oname)
292 {
293         int a = 0;
294         
295         /* compare without pointer or array part */
296         while (name[0] =='*')
297                 name++;
298         while (oname[0] =='*')
299                 oname++;
300         
301         while (1) {
302                 if (name[a] =='[' && oname[a] == 0) return 1;
303                 if (name[a] =='[' && oname[a] =='[') return 1;
304                 if (name[a] == 0) break;
305                 if (name[a] != oname[a]) return 0;
306                 a++;
307         }
308         if (name[a] == 0 && oname[a] == '.') return 2;
309         if (name[a] == 0 && oname[a] == '-' && oname[a+1] == '>') return 3;
310
311         return (name[a] == oname[a]);
312 }
313
314 static int rna_find_sdna_member(SDNA *sdna, const char *structname, const char *membername, DNAStructMember *smember)
315 {
316         const char *dnaname;
317         short *sp;
318         int a, b, structnr, totmember, cmp;
319
320         structnr = DNA_struct_find_nr(sdna, structname);
321         if (structnr == -1)
322                 return 0;
323
324         sp = sdna->structs[structnr];
325         totmember = sp[1];
326         sp += 2;
327
328         for (a = 0; a<totmember; a++, sp += 2) {
329                 dnaname = sdna->names[sp[1]];
330
331                 cmp = rna_member_cmp(dnaname, membername);
332
333                 if (cmp == 1) {
334                         smember->type = sdna->types[sp[0]];
335                         smember->name = dnaname;
336
337                         if (strstr(membername, "["))
338                                 smember->arraylength = 0;
339                         else
340                                 smember->arraylength = DNA_elem_array_size(smember->name, strlen(smember->name));
341
342                         smember->pointerlevel = 0;
343                         for (b = 0; dnaname[b] == '*'; b++)
344                                 smember->pointerlevel++;
345
346                         return 1;
347                 }
348                 else if (cmp == 2) {
349                         smember->type = "";
350                         smember->name = dnaname;
351                         smember->pointerlevel = 0;
352                         smember->arraylength = 0;
353
354                         membername = strstr(membername, ".") + strlen(".");
355                         rna_find_sdna_member(sdna, sdna->types[sp[0]], membername, smember);
356
357                         return 1;
358                 }
359                 else if (cmp == 3) {
360                         smember->type = "";
361                         smember->name = dnaname;
362                         smember->pointerlevel = 0;
363                         smember->arraylength = 0;
364
365                         membername = strstr(membername, "->") + strlen("->");
366                         rna_find_sdna_member(sdna, sdna->types[sp[0]], membername, smember);
367
368                         return 1;
369                 }
370         }
371
372         return 0;
373 }
374
375 static int rna_validate_identifier(const char *identifier, char *error, int property)
376 {
377         int a = 0;
378         
379         /*  list from http://docs.python.org/py3k/reference/lexical_analysis.html#keywords */
380         static const char *kwlist[] = {
381                 /* "False", "None", "True", */
382                 "and", "as", "assert", "break",
383                 "class", "continue", "def", "del", "elif", "else", "except",
384                 "finally", "for", "from", "global", "if", "import", "in",
385                 "is", "lambda", "nonlocal", "not", "or", "pass", "raise",
386                 "return", "try", "while", "with", "yield", NULL
387         };
388         
389         
390         if (!isalpha(identifier[0])) {
391                 strcpy(error, "first character failed isalpha() check");
392                 return 0;
393         }
394         
395         for (a = 0; identifier[a]; a++) {
396                 if (DefRNA.preprocess && property) {
397                         if (isalpha(identifier[a]) && isupper(identifier[a])) {
398                                 strcpy(error, "property names must contain lower case characters only");
399                                 return 0;
400                         }
401                 }
402                 
403                 if (identifier[a] =='_') {
404                         continue;
405                 }
406
407                 if (identifier[a] ==' ') {
408                         strcpy(error, "spaces are not okay in identifier names");
409                         return 0;
410                 }
411
412                 if (isalnum(identifier[a]) == 0) {
413                         strcpy(error, "one of the characters failed an isalnum() check and is not an underscore");
414                         return 0;
415                 }
416         }
417         
418         for (a = 0; kwlist[a]; a++) {
419                 if (strcmp(identifier, kwlist[a]) == 0) {
420                         strcpy(error, "this keyword is reserved by python");
421                         return 0;
422                 }
423         }
424
425         if (property) {
426                 static const char *kwlist_prop[] = {
427                         /* not keywords but reserved all the same because py uses */
428                         "keys", "values", "items", "get",
429                         NULL
430                 };
431
432                 for (a = 0; kwlist_prop[a]; a++) {
433                         if (strcmp(identifier, kwlist_prop[a]) == 0) {
434                                 strcpy(error, "this keyword is reserved by python");
435                                 return 0;
436                         }
437                 }
438         }
439         
440         return 1;
441 }
442
443 /* Blender Data Definition */
444
445 BlenderRNA *RNA_create(void)
446 {
447         BlenderRNA *brna;
448
449         brna = MEM_callocN(sizeof(BlenderRNA), "BlenderRNA");
450
451         DefRNA.sdna = DNA_sdna_from_data(DNAstr,  DNAlen, 0);
452         DefRNA.structs.first = DefRNA.structs.last = NULL;
453         DefRNA.error = 0;
454         DefRNA.preprocess = 1;
455
456         return brna;
457 }
458
459 void RNA_define_free(BlenderRNA *UNUSED(brna))
460 {
461         StructDefRNA *ds;
462         FunctionDefRNA *dfunc;
463         AllocDefRNA *alloc;
464
465         for (alloc = DefRNA.allocs.first; alloc; alloc = alloc->next)
466                 MEM_freeN(alloc->mem);
467         rna_freelistN(&DefRNA.allocs);
468
469         for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
470                 for (dfunc = ds->functions.first; dfunc; dfunc = dfunc->cont.next)
471                         rna_freelistN(&dfunc->cont.properties);
472
473                 rna_freelistN(&ds->cont.properties);
474                 rna_freelistN(&ds->functions);
475         }
476
477         rna_freelistN(&DefRNA.structs);
478
479         if (DefRNA.sdna) {
480                 DNA_sdna_free(DefRNA.sdna);
481                 DefRNA.sdna = NULL;
482         }
483
484         DefRNA.error = 0;
485 }
486
487 void RNA_define_verify_sdna(int verify)
488 {
489         DefRNA.verify = verify;
490 }
491
492 void RNA_struct_free_extension(StructRNA *srna, ExtensionRNA *ext)
493 {
494 #ifdef RNA_RUNTIME
495         ext->free(ext->data);                   /* decref's the PyObject that the srna owns */
496         RNA_struct_blender_type_set(srna, NULL); /* this gets accessed again - XXX fixme */
497         RNA_struct_py_type_set(srna, NULL);     /* NULL the srna's value so RNA_struct_free wont complain of a leak */
498 #endif
499 }
500
501 void RNA_struct_free(BlenderRNA *brna, StructRNA *srna)
502 {
503 #ifdef RNA_RUNTIME
504         FunctionRNA *func, *nextfunc;
505         PropertyRNA *prop, *nextprop;
506         PropertyRNA *parm, *nextparm;
507
508         /*
509         if (srna->flag & STRUCT_RUNTIME) {
510                 if (RNA_struct_py_type_get(srna)) {
511                         fprintf(stderr, "%s '%s' freed while holding a python reference\n", __func__, srna->identifier);
512                 }
513         } */
514
515         for (prop = srna->cont.properties.first; prop; prop = nextprop) {
516                 nextprop = prop->next;
517
518                 RNA_def_property_free_pointers(prop);
519
520                 if (prop->flag & PROP_RUNTIME)
521                         rna_freelinkN(&srna->cont.properties, prop);
522         }
523
524         for (func = srna->functions.first; func; func = nextfunc) {
525                 nextfunc = func->cont.next;
526
527                 for (parm = func->cont.properties.first; parm; parm = nextparm) {
528                         nextparm = parm->next;
529
530                         RNA_def_property_free_pointers(parm);
531
532                         if (parm->flag & PROP_RUNTIME)
533                                 rna_freelinkN(&func->cont.properties, parm);
534                 }
535
536                 RNA_def_func_free_pointers(func);
537
538                 if (func->flag & FUNC_RUNTIME)
539                         rna_freelinkN(&srna->functions, func);
540         }
541
542         RNA_def_struct_free_pointers(srna);
543
544         if (srna->flag & STRUCT_RUNTIME)
545                 rna_freelinkN(&brna->structs, srna);
546
547 #endif
548 }
549
550 void RNA_free(BlenderRNA *brna)
551 {
552         StructRNA *srna, *nextsrna;
553         FunctionRNA *func;
554
555         if (DefRNA.preprocess) {
556                 RNA_define_free(brna);
557
558                 for (srna = brna->structs.first; srna; srna = srna->cont.next) {
559                         for (func = srna->functions.first; func; func = func->cont.next)
560                                 rna_freelistN(&func->cont.properties);
561
562                         rna_freelistN(&srna->cont.properties);
563                         rna_freelistN(&srna->functions);
564                 }
565
566                 rna_freelistN(&brna->structs);
567                 
568                 MEM_freeN(brna);
569         }
570         else {
571                 for (srna = brna->structs.first; srna; srna = nextsrna) {
572                         nextsrna = srna->cont.next;
573                         RNA_struct_free(brna, srna);
574                 }
575         }
576 }
577
578 static size_t rna_property_type_sizeof(PropertyType type)
579 {
580         switch (type) {
581                 case PROP_BOOLEAN: return sizeof(BoolPropertyRNA);
582                 case PROP_INT: return sizeof(IntPropertyRNA);
583                 case PROP_FLOAT: return sizeof(FloatPropertyRNA);
584                 case PROP_STRING: return sizeof(StringPropertyRNA);
585                 case PROP_ENUM: return sizeof(EnumPropertyRNA);
586                 case PROP_POINTER: return sizeof(PointerPropertyRNA);
587                 case PROP_COLLECTION: return sizeof(CollectionPropertyRNA);
588                 default: return 0;
589         }
590 }
591
592 static StructDefRNA *rna_find_def_struct(StructRNA *srna)
593 {
594         StructDefRNA *ds;
595
596         for (ds = DefRNA.structs.first; ds; ds = ds->cont.next)
597                 if (ds->srna == srna)
598                         return ds;
599
600         return NULL;
601 }
602
603 /* Struct Definition */
604
605 StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
606 {
607         StructRNA *srna, *srnafrom = NULL;
608         StructDefRNA *ds = NULL, *dsfrom = NULL;
609         PropertyRNA *prop;
610         
611         if (DefRNA.preprocess) {
612                 char error[512];
613
614                 if (rna_validate_identifier(identifier, error, 0) == 0) {
615                         fprintf(stderr, "%s: struct identifier \"%s\" error - %s\n", __func__, identifier, error);
616                         DefRNA.error = 1;
617                 }
618         }
619         
620         if (from) {
621                 /* find struct to derive from */
622                 for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next)
623                         if (strcmp(srnafrom->identifier, from) == 0)
624                                 break;
625
626                 if (!srnafrom) {
627                         fprintf(stderr, "%s: struct %s not found to define %s.\n", __func__, from, identifier);
628                         DefRNA.error = 1;
629                 }
630         }
631
632         srna = MEM_callocN(sizeof(StructRNA), "StructRNA");
633         DefRNA.laststruct = srna;
634
635         if (srnafrom) {
636                 /* copy from struct to derive stuff, a bit clumsy since we can't
637                  * use MEM_dupallocN, data structs may not be alloced but builtin */
638                 memcpy(srna, srnafrom, sizeof(StructRNA));
639                 srna->cont.prophash = NULL;
640                 srna->cont.properties.first = srna->cont.properties.last = NULL;
641                 srna->functions.first = srna->functions.last = NULL;
642                 srna->py_type = NULL;
643
644                 if (DefRNA.preprocess) {
645                         srna->base = srnafrom;
646                         dsfrom = rna_find_def_struct(srnafrom);
647                 }
648                 else
649                         srna->base = srnafrom;
650         }
651         
652         srna->identifier = identifier;
653         srna->name = identifier; /* may be overwritten later RNA_def_struct_ui_text */
654         srna->description = "";
655         srna->flag |= STRUCT_UNDO;
656         if (!srnafrom)
657                 srna->icon = ICON_DOT;
658
659         rna_addtail(&brna->structs, srna);
660
661         if (DefRNA.preprocess) {
662                 ds = MEM_callocN(sizeof(StructDefRNA), "StructDefRNA");
663                 ds->srna = srna;
664                 rna_addtail(&DefRNA.structs, ds);
665
666                 if (dsfrom)
667                         ds->dnafromname = dsfrom->dnaname;
668         }
669
670         /* in preprocess, try to find sdna */
671         if (DefRNA.preprocess)
672                 RNA_def_struct_sdna(srna, srna->identifier);
673         else
674                 srna->flag |= STRUCT_RUNTIME;
675
676         if (srnafrom) {
677                 srna->nameproperty = srnafrom->nameproperty;
678                 srna->iteratorproperty = srnafrom->iteratorproperty;
679         }
680         else {
681                 /* define some builtin properties */
682                 prop = RNA_def_property(&srna->cont, "rna_properties", PROP_COLLECTION, PROP_NONE);
683                 RNA_def_property_flag(prop, PROP_BUILTIN);
684                 RNA_def_property_ui_text(prop, "Properties", "RNA property collection");
685
686                 if (DefRNA.preprocess) {
687                         RNA_def_property_struct_type(prop, "Property");
688                         RNA_def_property_collection_funcs(prop, "rna_builtin_properties_begin", "rna_builtin_properties_next",
689                                                           "rna_iterator_listbase_end", "rna_builtin_properties_get", NULL, NULL,
690                                                           "rna_builtin_properties_lookup_string", NULL);
691                 }
692                 else {
693 #ifdef RNA_RUNTIME
694                         CollectionPropertyRNA *cprop = (CollectionPropertyRNA*)prop;
695                         cprop->begin = rna_builtin_properties_begin;
696                         cprop->next = rna_builtin_properties_next;
697                         cprop->get = rna_builtin_properties_get;
698                         cprop->item_type = &RNA_Property;
699 #endif
700                 }
701
702                 prop = RNA_def_property(&srna->cont, "rna_type", PROP_POINTER, PROP_NONE);
703                 RNA_def_property_flag(prop, PROP_HIDDEN);
704                 RNA_def_property_ui_text(prop, "RNA", "RNA type definition");
705
706                 if (DefRNA.preprocess) {
707                         RNA_def_property_struct_type(prop, "Struct");
708                         RNA_def_property_pointer_funcs(prop, "rna_builtin_type_get", NULL, NULL, NULL);
709                 }
710                 else {
711 #ifdef RNA_RUNTIME
712                         PointerPropertyRNA *pprop = (PointerPropertyRNA*)prop;
713                         pprop->get = rna_builtin_type_get;
714                         pprop->type = &RNA_Struct;
715 #endif
716                 }
717         }
718
719         return srna;
720 }
721
722 void RNA_def_struct_sdna(StructRNA *srna, const char *structname)
723 {
724         StructDefRNA *ds;
725
726         if (!DefRNA.preprocess) {
727                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
728                 return;
729         }
730
731         ds = rna_find_def_struct(srna);
732
733         if (!DNA_struct_find_nr(DefRNA.sdna, structname)) {
734                 if (!DefRNA.silent) {
735                         fprintf(stderr, "%s: %s not found.\n", __func__, structname);
736                         DefRNA.error = 1;
737                 }
738                 return;
739         }
740
741         ds->dnaname = structname;
742 }
743
744 void RNA_def_struct_sdna_from(StructRNA *srna, const char *structname, const char *propname)
745 {
746         StructDefRNA *ds;
747
748         if (!DefRNA.preprocess) {
749                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
750                 return;
751         }
752
753         ds = rna_find_def_struct(srna);
754
755         if (!ds->dnaname) {
756                 fprintf(stderr, "%s: %s base struct must know DNA already.\n", __func__, structname);
757                 return;
758         }
759
760         if (!DNA_struct_find_nr(DefRNA.sdna, structname)) {
761                 if (!DefRNA.silent) {
762                         fprintf(stderr, "%s: %s not found.\n", __func__, structname);
763                         DefRNA.error = 1;
764                 }
765                 return;
766         }
767
768         ds->dnafromprop = propname;
769         ds->dnaname = structname;
770 }
771
772 void RNA_def_struct_name_property(struct StructRNA *srna, struct PropertyRNA *prop)
773 {
774         if (prop->type != PROP_STRING) {
775                 fprintf(stderr, "%s: \"%s.%s\", must be a string property.\n", __func__, srna->identifier, prop->identifier);
776                 DefRNA.error = 1;
777         }
778         else
779                 srna->nameproperty = prop;
780 }
781
782 void RNA_def_struct_nested(BlenderRNA *brna, StructRNA *srna, const char *structname)
783 {
784         StructRNA *srnafrom;
785
786         /* find struct to derive from */
787         for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next)
788                 if (strcmp(srnafrom->identifier, structname) == 0)
789                         break;
790
791         if (!srnafrom) {
792                 fprintf(stderr, "%s: struct %s not found for %s.\n", __func__, structname, srna->identifier);
793                 DefRNA.error = 1;
794         }
795
796         srna->nested = srnafrom;
797 }
798
799 void RNA_def_struct_flag(StructRNA *srna, int flag)
800 {
801         srna->flag |= flag;
802 }
803
804 void RNA_def_struct_clear_flag(StructRNA *srna, int flag)
805 {
806         srna->flag &= ~flag;
807 }
808
809 void RNA_def_struct_refine_func(StructRNA *srna, const char *refine)
810 {
811         if (!DefRNA.preprocess) {
812                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
813                 return;
814         }
815
816         if (refine) srna->refine = (StructRefineFunc)refine;
817 }
818
819 void RNA_def_struct_idprops_func(StructRNA *srna, const char *idproperties)
820 {
821         if (!DefRNA.preprocess) {
822                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
823                 return;
824         }
825
826         if (idproperties) srna->idproperties = (IDPropertiesFunc)idproperties;
827 }
828
829 void RNA_def_struct_register_funcs(StructRNA *srna, const char *reg, const char *unreg, const char *instance)
830 {
831         if (!DefRNA.preprocess) {
832                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
833                 return;
834         }
835
836         if (reg) srna->reg = (StructRegisterFunc)reg;
837         if (unreg) srna->unreg = (StructUnregisterFunc)unreg;
838         if (instance) srna->instance = (StructInstanceFunc)instance;
839 }
840
841 void RNA_def_struct_path_func(StructRNA *srna, const char *path)
842 {
843         if (!DefRNA.preprocess) {
844                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
845                 return;
846         }
847
848         if (path) srna->path = (StructPathFunc)path;
849 }
850
851 void RNA_def_struct_identifier(StructRNA *srna, const char *identifier)
852 {
853         if (DefRNA.preprocess) {
854                 fprintf(stderr, "%s: only at runtime.\n", __func__);
855                 return;
856         }
857
858         srna->identifier = identifier;
859 }
860
861 void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description)
862 {
863         DESCR_CHECK(description, srna->identifier, NULL);
864
865         srna->name = name;
866         srna->description = description;
867 }
868
869 void RNA_def_struct_ui_icon(StructRNA *srna, int icon)
870 {
871         srna->icon = icon;
872 }
873
874 void RNA_def_struct_translation_context(StructRNA *srna, const char *context)
875 {
876         srna->translation_context = context;
877 }
878
879 /* Property Definition */
880
881 PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
882 {
883         /*StructRNA *srna= DefRNA.laststruct;*/ /* invalid for python defined props */
884         ContainerRNA *cont = cont_;
885         ContainerDefRNA *dcont;
886         PropertyDefRNA *dprop = NULL;
887         PropertyRNA *prop;
888
889         if (DefRNA.preprocess) {
890                 char error[512];
891                 
892                 if (rna_validate_identifier(identifier, error, 1) == 0) {
893                         fprintf(stderr, "%s: property identifier \"%s.%s\" - %s\n", __func__,
894                                 CONTAINER_RNA_ID(cont), identifier, error);
895                         DefRNA.error = 1;
896                 }
897                 
898                 dcont = rna_find_container_def(cont);
899
900                 /* XXX - toto, detect supertype collisions */
901                 if (rna_findlink(&dcont->properties, identifier)) {
902                         fprintf(stderr, "%s: duplicate identifier \"%s.%s\"\n", __func__, CONTAINER_RNA_ID(cont), identifier);
903                         DefRNA.error = 1;
904                 }
905
906                 dprop = MEM_callocN(sizeof(PropertyDefRNA), "PropertyDefRNA");
907                 rna_addtail(&dcont->properties, dprop);
908         }
909
910         prop = MEM_callocN(rna_property_type_sizeof(type), "PropertyRNA");
911
912         switch (type) {
913                 case PROP_BOOLEAN:
914                         break;
915                 case PROP_INT: {
916                         IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
917
918                         iprop->hardmin = (subtype == PROP_UNSIGNED)? 0: INT_MIN;
919                         iprop->hardmax = INT_MAX;
920
921                         iprop->softmin = (subtype == PROP_UNSIGNED)? 0: -10000; /* rather arbitrary .. */
922                         iprop->softmax = 10000;
923                         iprop->step = 1;
924                         break;
925                 }
926                 case PROP_FLOAT: {
927                         FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
928
929                         fprop->hardmin = (subtype == PROP_UNSIGNED)? 0.0f: -FLT_MAX;
930                         fprop->hardmax = FLT_MAX;
931
932                         if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
933                                 fprop->softmin = 0.0f;
934                                 fprop->softmax = 1.0f;
935                         }
936                         else if (subtype == PROP_FACTOR) {
937                                 fprop->softmin = fprop->hardmin = 0.0f;
938                                 fprop->softmax = fprop->hardmax = 1.0f;
939                         }
940                         else {
941                                 fprop->softmin = (subtype == PROP_UNSIGNED)? 0.0f: -10000.0f; /* rather arbitrary .. */
942                                 fprop->softmax = 10000.0f;
943                         }
944                         fprop->step = 10;
945                         fprop->precision = 3;
946                         break;
947                 }
948                 case PROP_STRING: {
949                         StringPropertyRNA *sprop = (StringPropertyRNA*)prop;
950
951                         sprop->defaultvalue = "";
952                         sprop->maxlength = 0;
953                         break;
954                 }
955                 case PROP_ENUM:
956                 case PROP_POINTER:
957                 case PROP_COLLECTION:
958                         break;
959                 default:
960                         fprintf(stderr, "%s: \"%s.%s\", invalid property type.\n", __func__, CONTAINER_RNA_ID(cont), identifier);
961                         DefRNA.error = 1;
962                         return NULL;
963         }
964
965         if (DefRNA.preprocess) {
966                 dprop->cont = cont;
967                 dprop->prop = prop;
968         }
969
970         prop->magic = RNA_MAGIC;
971         prop->identifier = identifier;
972         prop->type = type;
973         prop->subtype = subtype;
974         prop->name = identifier;
975         prop->description = "";
976         /* a priori not raw editable */
977         prop->rawtype = -1;
978
979         if (type != PROP_COLLECTION && type != PROP_POINTER) {
980                 prop->flag = PROP_EDITABLE;
981         
982                 if (type != PROP_STRING)
983                         prop->flag |= PROP_ANIMATABLE;
984         }
985
986         if (DefRNA.preprocess) {
987                 switch (type) {
988                         case PROP_BOOLEAN:
989                                 DefRNA.silent = 1;
990                                 RNA_def_property_boolean_sdna(prop, NULL, identifier, 0);
991                                 DefRNA.silent = 0;
992                                 break;
993                         case PROP_INT: {
994                                 DefRNA.silent = 1;
995                                 RNA_def_property_int_sdna(prop, NULL, identifier);
996                                 DefRNA.silent = 0;
997                                 break;
998                         }
999                         case PROP_FLOAT: {
1000                                 DefRNA.silent = 1;
1001                                 RNA_def_property_float_sdna(prop, NULL, identifier);
1002                                 DefRNA.silent = 0;
1003                                 break;
1004                         }
1005                         case PROP_STRING: {
1006                                 DefRNA.silent = 1;
1007                                 RNA_def_property_string_sdna(prop, NULL, identifier);
1008                                 DefRNA.silent = 0;
1009                                 break;
1010                         }
1011                         case PROP_ENUM:
1012                                 DefRNA.silent = 1;
1013                                 RNA_def_property_enum_sdna(prop, NULL, identifier);
1014                                 DefRNA.silent = 0;
1015                                 break;
1016                         case PROP_POINTER:
1017                                 DefRNA.silent = 1;
1018                                 RNA_def_property_pointer_sdna(prop, NULL, identifier);
1019                                 DefRNA.silent = 0;
1020                                 break;
1021                         case PROP_COLLECTION:
1022                                 DefRNA.silent = 1;
1023                                 RNA_def_property_collection_sdna(prop, NULL, identifier, NULL);
1024                                 DefRNA.silent = 0;
1025                                 break;
1026                 }
1027         }
1028         else {
1029                 prop->flag |= PROP_IDPROPERTY|PROP_RUNTIME;
1030 #ifdef RNA_RUNTIME
1031                 if (cont->prophash)
1032                         BLI_ghash_insert(cont->prophash, (void*)prop->identifier, prop);
1033 #endif
1034         }
1035
1036         rna_addtail(&cont->properties, prop);
1037
1038         return prop;
1039 }
1040
1041 void RNA_def_property_flag(PropertyRNA *prop, int flag)
1042 {
1043         prop->flag |= flag;
1044 }
1045
1046 void RNA_def_property_clear_flag(PropertyRNA *prop, int flag)
1047 {
1048         prop->flag &= ~flag;
1049 }
1050
1051 void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype)
1052 {
1053         prop->subtype = subtype;
1054 }
1055
1056 void RNA_def_property_array(PropertyRNA *prop, int length)
1057 {
1058         StructRNA *srna = DefRNA.laststruct;
1059
1060         if (length<0) {
1061                 fprintf(stderr, "%s: \"%s.%s\", array length must be zero of greater.\n", __func__,
1062                         srna->identifier, prop->identifier);
1063                 DefRNA.error = 1;
1064                 return;
1065         }
1066
1067         if (length>RNA_MAX_ARRAY_LENGTH) {
1068                 fprintf(stderr, "%s: \"%s.%s\", array length must be smaller than %d.\n", __func__,
1069                         srna->identifier, prop->identifier, RNA_MAX_ARRAY_LENGTH);
1070                 DefRNA.error = 1;
1071                 return;
1072         }
1073
1074         if (prop->arraydimension > 1) {
1075                 fprintf(stderr, "%s: \"%s.%s\", array dimensions has been set to %u but would be overwritten as 1.\n",
1076                         __func__, srna->identifier, prop->identifier, prop->arraydimension);
1077                 DefRNA.error = 1;
1078                 return;
1079         }
1080
1081         switch (prop->type) {
1082                 case PROP_BOOLEAN:
1083                 case PROP_INT:
1084                 case PROP_FLOAT:
1085                         prop->arraylength[0] = length;
1086                         prop->totarraylength = length;
1087                         prop->arraydimension = 1;
1088                         break;
1089                 default:
1090                         fprintf(stderr, "%s: \"%s.%s\", only boolean/int/float can be array.\n",
1091                                 __func__, srna->identifier, prop->identifier);
1092                         DefRNA.error = 1;
1093                         break;
1094         }
1095 }
1096
1097 void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, const int length[])
1098 {
1099         StructRNA *srna = DefRNA.laststruct;
1100         int i;
1101         
1102         if (dimension < 1 || dimension > RNA_MAX_ARRAY_DIMENSION) {
1103                 fprintf(stderr, "%s: \"%s.%s\", array dimension must be between 1 and %d.\n",
1104                         __func__, srna->identifier, prop->identifier, RNA_MAX_ARRAY_DIMENSION);
1105                 DefRNA.error = 1;
1106                 return;
1107         }
1108
1109         switch (prop->type) {
1110                 case PROP_BOOLEAN:
1111                 case PROP_INT:
1112                 case PROP_FLOAT:
1113                         break;
1114                 default:
1115                         fprintf(stderr, "%s: \"%s.%s\", only boolean/int/float can be array.\n",
1116                                 __func__, srna->identifier, prop->identifier);
1117                         DefRNA.error = 1;
1118                         break;
1119         }
1120
1121         prop->arraydimension = dimension;
1122         prop->totarraylength = 0;
1123
1124         if (length) {
1125                 memcpy(prop->arraylength, length, sizeof(int)*dimension);
1126
1127                 prop->totarraylength = length[0];
1128                 for (i = 1; i<dimension; i++)
1129                         prop->totarraylength *= length[i];
1130         }
1131         else
1132                 memset(prop->arraylength, 0, sizeof(prop->arraylength));
1133
1134         /* TODO make sure arraylength values are sane  */
1135 }
1136
1137 void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
1138 {
1139         DESCR_CHECK(description, prop->identifier, NULL);
1140
1141         prop->name = name;
1142         prop->description = description;
1143 }
1144
1145 void RNA_def_property_ui_icon(PropertyRNA *prop, int icon, int consecutive)
1146 {
1147         prop->icon = icon;
1148         if (consecutive)
1149                 prop->flag |= PROP_ICONS_CONSECUTIVE;
1150 }
1151
1152 void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
1153 {
1154         StructRNA *srna = DefRNA.laststruct;
1155
1156         switch (prop->type) {
1157                 case PROP_INT: {
1158                         IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
1159                         iprop->softmin = (int)min;
1160                         iprop->softmax = (int)max;
1161                         iprop->step = (int)step;
1162                         break;
1163                 }
1164                 case PROP_FLOAT: {
1165                         FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
1166                         fprop->softmin = (float)min;
1167                         fprop->softmax = (float)max;
1168                         fprop->step = (float)step;
1169                         fprop->precision = (int)precision;
1170                         break;
1171                 }
1172                 default:
1173                         fprintf(stderr, "%s: \"%s.%s\", invalid type for ui range.\n",
1174                                 __func__, srna->identifier, prop->identifier);
1175                         DefRNA.error = 1;
1176                         break;
1177         }
1178 }
1179
1180 void RNA_def_property_range(PropertyRNA *prop, double min, double max)
1181 {
1182         StructRNA *srna = DefRNA.laststruct;
1183
1184         switch (prop->type) {
1185                 case PROP_INT: {
1186                         IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
1187                         iprop->hardmin = (int)min;
1188                         iprop->hardmax = (int)max;
1189                         iprop->softmin = MAX2((int)min, iprop->hardmin);
1190                         iprop->softmax = MIN2((int)max, iprop->hardmax);
1191                         break;
1192                 }
1193                 case PROP_FLOAT: {
1194                         FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
1195                         fprop->hardmin = (float)min;
1196                         fprop->hardmax = (float)max;
1197                         fprop->softmin = MAX2((float)min, fprop->hardmin);
1198                         fprop->softmax = MIN2((float)max, fprop->hardmax);
1199                         break;
1200                 }
1201                 default:
1202                         fprintf(stderr, "%s: \"%s.%s\", invalid type for range.\n", __func__, srna->identifier, prop->identifier);
1203                         DefRNA.error = 1;
1204                         break;
1205         }
1206 }
1207
1208 void RNA_def_property_struct_type(PropertyRNA *prop, const char *type)
1209 {
1210         StructRNA *srna = DefRNA.laststruct;
1211
1212         if (!DefRNA.preprocess) {
1213                 fprintf(stderr, "%s \"%s.%s\": only during preprocessing.\n", __func__, srna->identifier, prop->identifier);
1214                 return;
1215         }
1216
1217         switch (prop->type) {
1218                 case PROP_POINTER: {
1219                         PointerPropertyRNA *pprop = (PointerPropertyRNA*)prop;
1220                         pprop->type = (StructRNA*)type;
1221                         break;
1222                 }
1223                 case PROP_COLLECTION: {
1224                         CollectionPropertyRNA *cprop = (CollectionPropertyRNA*)prop;
1225                         cprop->item_type = (StructRNA*)type;
1226                         break;
1227                 }
1228                 default:
1229                         fprintf(stderr, "%s: \"%s.%s\", invalid type for struct type.\n",
1230                                 __func__, srna->identifier, prop->identifier);
1231                         DefRNA.error = 1;
1232                         break;
1233         }
1234 }
1235
1236 void RNA_def_property_struct_runtime(PropertyRNA *prop, StructRNA *type)
1237 {
1238         StructRNA *srna = DefRNA.laststruct;
1239
1240         if (DefRNA.preprocess) {
1241                 fprintf(stderr, "%s: only at runtime.\n", __func__);
1242                 return;
1243         }
1244
1245         switch (prop->type) {
1246                 case PROP_POINTER: {
1247                         PointerPropertyRNA *pprop = (PointerPropertyRNA*)prop;
1248                         pprop->type = type;
1249
1250                         if (type && (type->flag & STRUCT_ID_REFCOUNT))
1251                                 prop->flag |= PROP_ID_REFCOUNT;
1252
1253                         break;
1254                 }
1255                 case PROP_COLLECTION: {
1256                         CollectionPropertyRNA *cprop = (CollectionPropertyRNA*)prop;
1257                         cprop->item_type = type;
1258                         break;
1259                 }
1260                 default:
1261                         fprintf(stderr, "%s: \"%s.%s\", invalid type for struct type.\n",
1262                                 __func__, srna->identifier, prop->identifier);
1263                         DefRNA.error = 1;
1264                         break;
1265         }
1266 }
1267
1268 void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item)
1269 {
1270         StructRNA *srna = DefRNA.laststruct;
1271         int i, defaultfound = 0;
1272
1273         switch (prop->type) {
1274                 case PROP_ENUM: {
1275                         EnumPropertyRNA *eprop = (EnumPropertyRNA*)prop;
1276                         eprop->item = (EnumPropertyItem*)item;
1277                         eprop->totitem = 0;
1278                         for (i = 0; item[i].identifier; i++) {
1279                                 eprop->totitem++;
1280
1281                                 if (item[i].identifier[0] && item[i].value == eprop->defaultvalue)
1282                                         defaultfound = 1;
1283                         }
1284
1285                         if (!defaultfound) {
1286                                 for (i = 0; item[i].identifier; i++) {
1287                                         if (item[i].identifier[0]) {
1288                                                 eprop->defaultvalue = item[i].value;
1289                                                 break;
1290                                         }
1291                                 }
1292                         }
1293
1294                         break;
1295                 }
1296                 default:
1297                         fprintf(stderr, "%s: \"%s.%s\", invalid type for struct type.\n",
1298                                 __func__, srna->identifier, prop->identifier);
1299                         DefRNA.error = 1;
1300                         break;
1301         }
1302 }
1303
1304 void RNA_def_property_string_maxlength(PropertyRNA *prop, int maxlength)
1305 {
1306         StructRNA *srna = DefRNA.laststruct;
1307
1308         switch (prop->type) {
1309                 case PROP_STRING: {
1310                         StringPropertyRNA *sprop = (StringPropertyRNA*)prop;
1311                         sprop->maxlength = maxlength;
1312                         break;
1313                 }
1314                 default:
1315                         fprintf(stderr, "%s: \"%s.%s\", type is not string.\n", __func__, srna->identifier, prop->identifier);
1316                         DefRNA.error = 1;
1317                         break;
1318         }
1319 }
1320
1321 void RNA_def_property_boolean_default(PropertyRNA *prop, int value)
1322 {
1323         StructRNA *srna = DefRNA.laststruct;
1324
1325         switch (prop->type) {
1326                 case PROP_BOOLEAN: {
1327                         BoolPropertyRNA *bprop = (BoolPropertyRNA*)prop;
1328                         bprop->defaultvalue = value;
1329                         break;
1330                 }
1331                 default:
1332                         fprintf(stderr, "%s: \"%s.%s\", type is not boolean.\n", __func__, srna->identifier, prop->identifier);
1333                         DefRNA.error = 1;
1334                         break;
1335         }
1336 }
1337
1338 void RNA_def_property_boolean_array_default(PropertyRNA *prop, const int *array)
1339 {
1340         StructRNA *srna = DefRNA.laststruct;
1341
1342         switch (prop->type) {
1343                 case PROP_BOOLEAN: {
1344                         BoolPropertyRNA *bprop = (BoolPropertyRNA*)prop;
1345                         bprop->defaultarray = array;
1346                         break;
1347                 }
1348                 default:
1349                         fprintf(stderr, "%s: \"%s.%s\", type is not boolean.\n", __func__, srna->identifier, prop->identifier);
1350                         DefRNA.error = 1;
1351                         break;
1352         }
1353 }
1354
1355 void RNA_def_property_int_default(PropertyRNA *prop, int value)
1356 {
1357         StructRNA *srna = DefRNA.laststruct;
1358
1359         switch (prop->type) {
1360                 case PROP_INT: {
1361                         IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
1362                         iprop->defaultvalue = value;
1363                         break;
1364                 }
1365                 default:
1366                         fprintf(stderr, "%s: \"%s.%s\", type is not int.\n", __func__, srna->identifier, prop->identifier);
1367                         DefRNA.error = 1;
1368                         break;
1369         }
1370 }
1371
1372 void RNA_def_property_int_array_default(PropertyRNA *prop, const int *array)
1373 {
1374         StructRNA *srna = DefRNA.laststruct;
1375
1376         switch (prop->type) {
1377                 case PROP_INT: {
1378                         IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
1379                         iprop->defaultarray = array;
1380                         break;
1381                 }
1382                 default:
1383                         fprintf(stderr, "%s: \"%s.%s\", type is not int.\n", __func__, srna->identifier, prop->identifier);
1384                         DefRNA.error = 1;
1385                         break;
1386         }
1387 }
1388
1389 void RNA_def_property_float_default(PropertyRNA *prop, float value)
1390 {
1391         StructRNA *srna = DefRNA.laststruct;
1392
1393         switch (prop->type) {
1394                 case PROP_FLOAT: {
1395                         FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
1396                         fprop->defaultvalue = value;
1397                         break;
1398                 }
1399                 default:
1400                         fprintf(stderr, "%s: \"%s.%s\", type is not float.\n", __func__, srna->identifier, prop->identifier);
1401                         DefRNA.error = 1;
1402                         break;
1403         }
1404 }
1405 /* array must remain valid after this function finishes */
1406 void RNA_def_property_float_array_default(PropertyRNA *prop, const float *array)
1407 {
1408         StructRNA *srna = DefRNA.laststruct;
1409
1410         switch (prop->type) {
1411                 case PROP_FLOAT: {
1412                         FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
1413                         fprop->defaultarray = array; /* WARNING, this array must not come from the stack and lost */
1414                         break;
1415                 }
1416                 default:
1417                         fprintf(stderr, "%s: \"%s.%s\", type is not float.\n", __func__, srna->identifier, prop->identifier);
1418                         DefRNA.error = 1;
1419                         break;
1420         }
1421 }
1422
1423 void RNA_def_property_string_default(PropertyRNA *prop, const char *value)
1424 {
1425         StructRNA *srna = DefRNA.laststruct;
1426
1427         switch (prop->type) {
1428                 case PROP_STRING: {
1429                         StringPropertyRNA *sprop = (StringPropertyRNA*)prop;
1430                         sprop->defaultvalue = value;
1431                         break;
1432                 }
1433                 default:
1434                         fprintf(stderr, "%s: \"%s.%s\", type is not string.\n", __func__, srna->identifier, prop->identifier);
1435                         DefRNA.error = 1;
1436                         break;
1437         }
1438 }
1439
1440 void RNA_def_property_enum_default(PropertyRNA *prop, int value)
1441 {
1442         StructRNA *srna = DefRNA.laststruct;
1443         int i, defaultfound = 0;
1444
1445         switch (prop->type) {
1446                 case PROP_ENUM: {
1447                         EnumPropertyRNA *eprop = (EnumPropertyRNA*)prop;
1448                         eprop->defaultvalue = value;
1449
1450                         if (prop->flag & PROP_ENUM_FLAG) {
1451                                 /* check all bits are accounted for */
1452                                 int totflag = 0;
1453                                 for (i = 0; i<eprop->totitem; i++) {
1454                                         if (eprop->item[i].identifier[0]) {
1455                                                 totflag |= eprop->item[i].value;
1456                                         }
1457                                 }
1458
1459                                 if (eprop->defaultvalue & ~totflag) {
1460                                         fprintf(stderr, "%s: \"%s.%s\", default includes unused bits (%d).\n",
1461                                                 __func__, srna->identifier, prop->identifier, eprop->defaultvalue & ~totflag);
1462                                         DefRNA.error = 1;
1463                                 }
1464                         }
1465                         else {
1466                                 for (i = 0; i<eprop->totitem; i++) {
1467                                         if (eprop->item[i].identifier[0] && eprop->item[i].value == eprop->defaultvalue)
1468                                                 defaultfound = 1;
1469                                 }
1470
1471                                 if (!defaultfound && eprop->totitem) {
1472                                         if (value == 0) {
1473                                                 eprop->defaultvalue = eprop->item[0].value;
1474                                         }
1475                                         else {
1476                                                 fprintf(stderr, "%s: \"%s.%s\", default is not in items.\n",
1477                                                         __func__, srna->identifier, prop->identifier);
1478                                                 DefRNA.error = 1;
1479                                         }
1480                                 }
1481                         }
1482
1483                         break;
1484                 }
1485                 default:
1486                         fprintf(stderr, "%s: \"%s.%s\", type is not enum.\n", __func__, srna->identifier, prop->identifier);
1487                         DefRNA.error = 1;
1488                         break;
1489         }
1490 }
1491
1492 /* SDNA */
1493
1494 static PropertyDefRNA *rna_def_property_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1495 {
1496         DNAStructMember smember;
1497         StructDefRNA *ds;
1498         PropertyDefRNA *dp;
1499
1500         dp = rna_find_struct_property_def(DefRNA.laststruct, prop);
1501         if (dp == NULL) return NULL;
1502
1503         ds = rna_find_struct_def((StructRNA*)dp->cont);
1504
1505         if (!structname)
1506                 structname = ds->dnaname;
1507         if (!propname)
1508                 propname = prop->identifier;
1509
1510         if (!rna_find_sdna_member(DefRNA.sdna, structname, propname, &smember)) {
1511                 if (DefRNA.silent) {
1512                         return NULL;
1513                 }
1514                 else if (!DefRNA.verify) {
1515                         /* some basic values to survive even with sdna info */
1516                         dp->dnastructname = structname;
1517                         dp->dnaname = propname;
1518                         if (prop->type == PROP_BOOLEAN)
1519                                 dp->dnaarraylength = 1;
1520                         if (prop->type == PROP_POINTER)
1521                                 dp->dnapointerlevel = 1;
1522                         return dp;
1523                 }
1524                 else {
1525                         fprintf(stderr, "%s: \"%s.%s\" (identifier \"%s\") not found.\n",
1526                                 __func__, structname, propname, prop->identifier);
1527                         DefRNA.error = 1;
1528                         return NULL;
1529                 }
1530         }
1531
1532         if (smember.arraylength > 1) {
1533                 prop->arraylength[0] = smember.arraylength;
1534                 prop->totarraylength = smember.arraylength;
1535                 prop->arraydimension = 1;
1536         }
1537         else {
1538                 prop->arraydimension = 0;
1539                 prop->totarraylength = 0;
1540         }
1541         
1542         dp->dnastructname = structname;
1543         dp->dnastructfromname = ds->dnafromname;
1544         dp->dnastructfromprop = ds->dnafromprop;
1545         dp->dnaname = propname;
1546         dp->dnatype = smember.type;
1547         dp->dnaarraylength = smember.arraylength;
1548         dp->dnapointerlevel = smember.pointerlevel;
1549
1550         return dp;
1551 }
1552
1553 void RNA_def_property_boolean_sdna(PropertyRNA *prop, const char *structname, const char *propname, int bit)
1554 {
1555         PropertyDefRNA *dp;
1556         StructRNA *srna = DefRNA.laststruct;
1557         
1558         if (!DefRNA.preprocess) {
1559                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1560                 return;
1561         }
1562
1563         if (prop->type != PROP_BOOLEAN) {
1564                 fprintf(stderr, "%s: \"%s.%s\", type is not boolean.\n", __func__, srna->identifier, prop->identifier);
1565                 DefRNA.error = 1;
1566                 return;
1567         }
1568
1569         if ((dp = rna_def_property_sdna(prop, structname, propname))) {
1570
1571                 if (DefRNA.silent == 0) {
1572                         /* error check to ensure floats are not wrapped as ints/bools */
1573                         if (dp->dnatype && *dp->dnatype && IS_DNATYPE_INT_COMPAT(dp->dnatype) == 0) {
1574                                 fprintf(stderr, "%s: %s.%s is a '%s' but wrapped as type '%s'.\n",
1575                                         __func__, srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type));
1576                                 DefRNA.error = 1;
1577                                 return;
1578                         }
1579                 }
1580
1581                 dp->booleanbit = bit;
1582         }
1583 }
1584
1585 void RNA_def_property_boolean_negative_sdna(PropertyRNA *prop, const char *structname,
1586                                             const char *propname, int booleanbit)
1587 {
1588         PropertyDefRNA *dp;
1589
1590         RNA_def_property_boolean_sdna(prop, structname, propname, booleanbit);
1591
1592         dp = rna_find_struct_property_def(DefRNA.laststruct, prop);
1593
1594         if (dp)
1595                 dp->booleannegative = 1;
1596 }
1597
1598 void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1599 {
1600         PropertyDefRNA *dp;
1601         IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
1602         StructRNA *srna = DefRNA.laststruct;
1603         
1604         if (!DefRNA.preprocess) {
1605                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1606                 return;
1607         }
1608
1609         if (prop->type != PROP_INT) {
1610                 fprintf(stderr, "%s: \"%s.%s\", type is not int.\n", __func__, srna->identifier, prop->identifier);
1611                 DefRNA.error = 1;
1612                 return;
1613         }
1614
1615         if ((dp = rna_def_property_sdna(prop, structname, propname))) {
1616
1617                 /* error check to ensure floats are not wrapped as ints/bools */
1618                 if (DefRNA.silent == 0) {
1619                         if (dp->dnatype && *dp->dnatype && IS_DNATYPE_INT_COMPAT(dp->dnatype) == 0) {
1620                                 fprintf(stderr, "%s: %s.%s is a '%s' but wrapped as type '%s'.\n",
1621                                         __func__, srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type));
1622                                 DefRNA.error = 1;
1623                                 return;
1624                         }
1625                 }
1626
1627                 /* SDNA doesn't pass us unsigned unfortunately .. */
1628                 if (dp->dnatype && strcmp(dp->dnatype, "char") == 0) {
1629                         iprop->hardmin = iprop->softmin = CHAR_MIN;
1630                         iprop->hardmax = iprop->softmax = CHAR_MAX;
1631                 }
1632                 else if (dp->dnatype && strcmp(dp->dnatype, "short") == 0) {
1633                         iprop->hardmin = iprop->softmin = SHRT_MIN;
1634                         iprop->hardmax = iprop->softmax = SHRT_MAX;
1635                 }
1636                 else if (dp->dnatype && strcmp(dp->dnatype, "int") == 0) {
1637                         iprop->hardmin = INT_MIN;
1638                         iprop->hardmax = INT_MAX;
1639
1640                         iprop->softmin = -10000; /* rather arbitrary .. */
1641                         iprop->softmax = 10000;
1642                 }
1643
1644                 if (prop->subtype == PROP_UNSIGNED || prop->subtype == PROP_PERCENTAGE || prop->subtype == PROP_FACTOR)
1645                         iprop->hardmin = iprop->softmin = 0;
1646         }
1647 }
1648
1649 void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1650 {
1651         PropertyDefRNA *dp;
1652         FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
1653         StructRNA *srna = DefRNA.laststruct;
1654
1655         if (!DefRNA.preprocess) {
1656                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1657                 return;
1658         }
1659
1660         if (prop->type != PROP_FLOAT) {
1661                 fprintf(stderr, "%s: \"%s.%s\", type is not float.\n", __func__, srna->identifier, prop->identifier);
1662                 DefRNA.error = 1;
1663                 return;
1664         }
1665
1666         if ((dp = rna_def_property_sdna(prop, structname, propname))) {
1667                 /* silent is for internal use */
1668                 if (DefRNA.silent == 0) {
1669                         if (dp->dnatype && *dp->dnatype && IS_DNATYPE_FLOAT_COMPAT(dp->dnatype) == 0) {
1670                                 if (prop->subtype != PROP_COLOR_GAMMA) { /* colors are an exception. these get translated */
1671                                         fprintf(stderr, "%s: %s.%s is a '%s' but wrapped as type '%s'.\n",
1672                                                 __func__, srna->identifier, prop->identifier, dp->dnatype,
1673                                                 RNA_property_typename(prop->type));
1674                                         DefRNA.error = 1;
1675                                         return;
1676                                 }
1677                         }
1678                 }
1679
1680                 if (dp->dnatype && strcmp(dp->dnatype, "char") == 0) {
1681                         fprop->hardmin = fprop->softmin = 0.0f;
1682                         fprop->hardmax = fprop->softmax = 1.0f;
1683                 }
1684         }
1685
1686         rna_def_property_sdna(prop, structname, propname);
1687 }
1688
1689 void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1690 {
1691         /* PropertyDefRNA *dp; */
1692         StructRNA *srna = DefRNA.laststruct;
1693         
1694         if (!DefRNA.preprocess) {
1695                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1696                 return;
1697         }
1698
1699         if (prop->type != PROP_ENUM) {
1700                 fprintf(stderr, "%s: \"%s.%s\", type is not enum.\n", __func__, srna->identifier, prop->identifier);
1701                 DefRNA.error = 1;
1702                 return;
1703         }
1704
1705         if (( /* dp= */ rna_def_property_sdna(prop, structname, propname))) {
1706                 if (prop->arraydimension) {
1707                         prop->arraydimension = 0;
1708                         prop->totarraylength = 0;
1709
1710                         if (!DefRNA.silent) {
1711                                 fprintf(stderr, "%s: \"%s.%s\", array not supported for enum type.\n",
1712                                         __func__, structname, propname);
1713                                 DefRNA.error = 1;
1714                         }
1715                 }
1716         }
1717 }
1718
1719 void RNA_def_property_enum_bitflag_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1720 {
1721         PropertyDefRNA *dp;
1722
1723         RNA_def_property_enum_sdna(prop, structname, propname);
1724
1725         dp = rna_find_struct_property_def(DefRNA.laststruct, prop);
1726
1727         if (dp)
1728                 dp->enumbitflags = 1;
1729 }
1730
1731 void RNA_def_property_string_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1732 {
1733         /* PropertyDefRNA *dp; */
1734         StringPropertyRNA *sprop = (StringPropertyRNA*)prop;
1735         StructRNA *srna = DefRNA.laststruct;
1736
1737         if (!DefRNA.preprocess) {
1738                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1739                 return;
1740         }
1741
1742         if (prop->type != PROP_STRING) {
1743                 fprintf(stderr, "%s: \"%s.%s\", type is not string.\n", __func__, srna->identifier, prop->identifier);
1744                 DefRNA.error = 1;
1745                 return;
1746         }
1747
1748         if ((/* dp= */ rna_def_property_sdna(prop, structname, propname))) {
1749                 if (prop->arraydimension) {
1750                         sprop->maxlength = prop->totarraylength;
1751                         prop->arraydimension = 0;
1752                         prop->totarraylength = 0;
1753                 }
1754         }
1755 }
1756
1757 void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1758 {
1759         /* PropertyDefRNA *dp; */
1760         StructRNA *srna = DefRNA.laststruct;
1761         
1762         if (!DefRNA.preprocess) {
1763                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1764                 return;
1765         }
1766
1767         if (prop->type != PROP_POINTER) {
1768                 fprintf(stderr, "%s: \"%s.%s\", type is not pointer.\n", __func__, srna->identifier, prop->identifier);
1769                 DefRNA.error = 1;
1770                 return;
1771         }
1772
1773         if ((/* dp= */ rna_def_property_sdna(prop, structname, propname))) {
1774                 if (prop->arraydimension) {
1775                         prop->arraydimension = 0;
1776                         prop->totarraylength = 0;
1777
1778                         if (!DefRNA.silent) {
1779                                 fprintf(stderr, "%s: \"%s.%s\", array not supported for pointer type.\n",
1780                                         __func__, structname, propname);
1781                                 DefRNA.error = 1;
1782                         }
1783                 }
1784         }
1785 }
1786
1787 void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, const char *propname,
1788                                       const char *lengthpropname)
1789 {
1790         PropertyDefRNA *dp;
1791         CollectionPropertyRNA *cprop = (CollectionPropertyRNA*)prop;
1792         StructRNA *srna = DefRNA.laststruct;
1793
1794         if (!DefRNA.preprocess) {
1795                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1796                 return;
1797         }
1798
1799         if (prop->type != PROP_COLLECTION) {
1800                 fprintf(stderr, "%s: \"%s.%s\", type is not collection.\n", __func__, srna->identifier, prop->identifier);
1801                 DefRNA.error = 1;
1802                 return;
1803         }
1804
1805         if ((dp = rna_def_property_sdna(prop, structname, propname))) {
1806                 if (prop->arraydimension && !lengthpropname) {
1807                         prop->arraydimension = 0;
1808                         prop->totarraylength = 0;
1809
1810                         if (!DefRNA.silent) {
1811                                 fprintf(stderr, "%s: \"%s.%s\", array of collections not supported.\n",
1812                                         __func__, structname, propname);
1813                                 DefRNA.error = 1;
1814                         }
1815                 }
1816
1817                 if (dp->dnatype && strcmp(dp->dnatype, "ListBase") == 0) {
1818                         cprop->next = (PropCollectionNextFunc)"rna_iterator_listbase_next";
1819                         cprop->get = (PropCollectionGetFunc)"rna_iterator_listbase_get";
1820                         cprop->end = (PropCollectionEndFunc)"rna_iterator_listbase_end";
1821                 }
1822         }
1823
1824         if (dp && lengthpropname) {
1825                 DNAStructMember smember;
1826                 StructDefRNA *ds = rna_find_struct_def((StructRNA*)dp->cont);
1827
1828                 if (!structname)
1829                         structname = ds->dnaname;
1830
1831                 if (lengthpropname[0] == 0 || rna_find_sdna_member(DefRNA.sdna, structname, lengthpropname, &smember)) {
1832                         if (lengthpropname[0] == 0) {
1833                                 dp->dnalengthfixed = prop->totarraylength;
1834                                 prop->arraydimension = 0;
1835                                 prop->totarraylength = 0;
1836                         }
1837                         else {
1838                                 dp->dnalengthstructname = structname;
1839                                 dp->dnalengthname = lengthpropname;
1840                                 prop->totarraylength = 0;
1841                         }
1842
1843                         cprop->next = (PropCollectionNextFunc)"rna_iterator_array_next";
1844                         cprop->end = (PropCollectionEndFunc)"rna_iterator_array_end";
1845
1846                         if (dp->dnapointerlevel >= 2)
1847                                 cprop->get = (PropCollectionGetFunc)"rna_iterator_array_dereference_get";
1848                         else
1849                                 cprop->get = (PropCollectionGetFunc)"rna_iterator_array_get";
1850                 }
1851                 else {
1852                         if (!DefRNA.silent) {
1853                                 fprintf(stderr, "%s: \"%s.%s\" not found.\n", __func__, structname, lengthpropname);
1854                                 DefRNA.error = 1;
1855                         }
1856                 }
1857         }
1858 }
1859
1860 void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
1861 {
1862         prop->translation_context = context;
1863 }
1864
1865 /* Functions */
1866
1867 void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable)
1868 {
1869         if (!DefRNA.preprocess) {
1870                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1871                 return;
1872         }
1873
1874         if (editable) prop->editable = (EditableFunc)editable;
1875 }
1876
1877 void RNA_def_property_editable_array_func(PropertyRNA *prop, const char *editable)
1878 {
1879         if (!DefRNA.preprocess) {
1880                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1881                 return;
1882         }
1883
1884         if (editable) prop->itemeditable = (ItemEditableFunc)editable;
1885 }
1886
1887 void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *func)
1888 {
1889         if (!DefRNA.preprocess) {
1890                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1891                 return;
1892         }
1893
1894         prop->noteflag = noteflag;
1895         prop->update = (UpdateFunc)func;
1896 }
1897
1898 void RNA_def_property_update_runtime(PropertyRNA *prop, void *func)
1899 {
1900         prop->update = func;
1901 }
1902
1903 void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength)
1904 {
1905         if (!DefRNA.preprocess) {
1906                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1907                 return;
1908         }
1909
1910         if (!(prop->flag & PROP_DYNAMIC)) {
1911                 fprintf(stderr, "%s: property is a not dynamic array.\n", __func__);
1912                 DefRNA.error = 1;
1913                 return;
1914         }
1915
1916         if (getlength) prop->getlength = (PropArrayLengthGetFunc)getlength;
1917 }
1918
1919 void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set)
1920 {
1921         StructRNA *srna = DefRNA.laststruct;
1922
1923         if (!DefRNA.preprocess) {
1924                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1925                 return;
1926         }
1927
1928         switch (prop->type) {
1929                 case PROP_BOOLEAN: {
1930                         BoolPropertyRNA *bprop = (BoolPropertyRNA*)prop;
1931
1932                         if (prop->arraydimension) {
1933                                 if (get) bprop->getarray = (PropBooleanArrayGetFunc)get;
1934                                 if (set) bprop->setarray = (PropBooleanArraySetFunc)set;
1935                         }
1936                         else {
1937                                 if (get) bprop->get = (PropBooleanGetFunc)get;
1938                                 if (set) bprop->set = (PropBooleanSetFunc)set;
1939                         }
1940                         break;
1941                 }
1942                 default:
1943                         fprintf(stderr, "%s: \"%s.%s\", type is not boolean.\n", __func__, srna->identifier, prop->identifier);
1944                         DefRNA.error = 1;
1945                         break;
1946         }
1947 }
1948
1949 void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
1950 {
1951         StructRNA *srna = DefRNA.laststruct;
1952
1953         if (!DefRNA.preprocess) {
1954                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1955                 return;
1956         }
1957
1958         switch (prop->type) {
1959                 case PROP_INT: {
1960                         IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
1961
1962                         if (prop->arraydimension) {
1963                                 if (get) iprop->getarray = (PropIntArrayGetFunc)get;
1964                                 if (set) iprop->setarray = (PropIntArraySetFunc)set;
1965                         }
1966                         else {
1967                                 if (get) iprop->get = (PropIntGetFunc)get;
1968                                 if (set) iprop->set = (PropIntSetFunc)set;
1969                         }
1970                         if (range) iprop->range = (PropIntRangeFunc)range;
1971                         break;
1972                 }
1973                 default:
1974                         fprintf(stderr, "%s: \"%s.%s\", type is not int.\n", __func__, srna->identifier, prop->identifier);
1975                         DefRNA.error = 1;
1976                         break;
1977         }
1978 }
1979
1980 void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
1981 {
1982         StructRNA *srna = DefRNA.laststruct;
1983
1984         if (!DefRNA.preprocess) {
1985                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1986                 return;
1987         }
1988
1989         switch (prop->type) {
1990                 case PROP_FLOAT: {
1991                         FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
1992
1993                         if (prop->arraydimension) {
1994                                 if (get) fprop->getarray = (PropFloatArrayGetFunc)get;
1995                                 if (set) fprop->setarray = (PropFloatArraySetFunc)set;
1996                         }
1997                         else {
1998                                 if (get) fprop->get = (PropFloatGetFunc)get;
1999                                 if (set) fprop->set = (PropFloatSetFunc)set;
2000                         }
2001                         if (range) fprop->range = (PropFloatRangeFunc)range;
2002                         break;
2003                 }
2004                 default:
2005                         fprintf(stderr, "%s: \"%s.%s\", type is not float.\n", __func__, srna->identifier, prop->identifier);
2006                         DefRNA.error = 1;
2007                         break;
2008         }
2009 }
2010
2011 void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set, const char *item)
2012 {
2013         StructRNA *srna = DefRNA.laststruct;
2014
2015         if (!DefRNA.preprocess) {
2016                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
2017                 return;
2018         }
2019
2020         switch (prop->type) {
2021                 case PROP_ENUM: {
2022                         EnumPropertyRNA *eprop = (EnumPropertyRNA*)prop;
2023
2024                         if (get) eprop->get = (PropEnumGetFunc)get;
2025                         if (set) eprop->set = (PropEnumSetFunc)set;
2026                         if (item) eprop->itemf = (PropEnumItemFunc)item;
2027                         break;
2028                 }
2029                 default:
2030                         fprintf(stderr, "%s: \"%s.%s\", type is not enum.\n", __func__, srna->identifier, prop->identifier);
2031                         DefRNA.error = 1;
2032                         break;
2033         }
2034 }
2035
2036 void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set)
2037 {
2038         StructRNA *srna = DefRNA.laststruct;
2039
2040         if (!DefRNA.preprocess) {
2041                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
2042                 return;
2043         }
2044
2045         switch (prop->type) {
2046                 case PROP_STRING: {
2047                         StringPropertyRNA *sprop = (StringPropertyRNA*)prop;
2048
2049                         if (get) sprop->get = (PropStringGetFunc)get;
2050                         if (length) sprop->length = (PropStringLengthFunc)length;
2051                         if (set) sprop->set = (PropStringSetFunc)set;
2052                         break;
2053                 }
2054                 default:
2055                         fprintf(stderr, "%s: \"%s.%s\", type is not string.\n", __func__, srna->identifier, prop->identifier);
2056                         DefRNA.error = 1;
2057                         break;
2058         }
2059 }
2060
2061 void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set,
2062                                     const char *typef, const char *poll)
2063 {
2064         StructRNA *srna = DefRNA.laststruct;
2065
2066         if (!DefRNA.preprocess) {
2067                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
2068                 return;
2069         }
2070
2071         switch (prop->type) {
2072                 case PROP_POINTER: {
2073                         PointerPropertyRNA *pprop = (PointerPropertyRNA*)prop;
2074
2075                         if (get) pprop->get = (PropPointerGetFunc)get;
2076                         if (set) pprop->set = (PropPointerSetFunc)set;
2077                         if (typef) pprop->typef = (PropPointerTypeFunc)typef;
2078                         if (poll) pprop->poll = (PropPointerPollFunc)poll;
2079                         break;
2080                 }
2081                 default:
2082                         fprintf(stderr, "%s: \"%s.%s\", type is not pointer.\n", __func__, srna->identifier, prop->identifier);
2083                         DefRNA.error = 1;
2084                         break;
2085         }
2086 }
2087
2088 void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end,
2089                                        const char *get, const char *length, const char *lookupint,
2090                                        const char *lookupstring, const char *assignint)
2091 {
2092         StructRNA *srna = DefRNA.laststruct;
2093
2094         if (!DefRNA.preprocess) {
2095                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
2096                 return;
2097         }
2098
2099         switch (prop->type) {
2100                 case PROP_COLLECTION: {
2101                         CollectionPropertyRNA *cprop = (CollectionPropertyRNA*)prop;
2102
2103                         if (begin) cprop->begin = (PropCollectionBeginFunc)begin;
2104                         if (next) cprop->next = (PropCollectionNextFunc)next;
2105                         if (end) cprop->end = (PropCollectionEndFunc)end;
2106                         if (get) cprop->get = (PropCollectionGetFunc)get;
2107                         if (length) cprop->length = (PropCollectionLengthFunc)length;
2108                         if (lookupint) cprop->lookupint = (PropCollectionLookupIntFunc)lookupint;
2109                         if (lookupstring) cprop->lookupstring = (PropCollectionLookupStringFunc)lookupstring;
2110                         if (assignint) cprop->assignint = (PropCollectionAssignIntFunc)assignint;
2111                         break;
2112                 }
2113                 default:
2114                         fprintf(stderr, "%s: \"%s.%s\", type is not collection.\n", __func__, srna->identifier, prop->identifier);
2115                         DefRNA.error = 1;
2116                         break;
2117         }
2118 }
2119
2120 void RNA_def_property_srna(PropertyRNA *prop, const char *type)
2121 {
2122         prop->srna = (StructRNA*)type;
2123 }
2124
2125 void RNA_def_py_data(PropertyRNA *prop, void *py_data)
2126 {
2127         prop->py_data = py_data;
2128 }
2129
2130 /* Compact definitions */
2131
2132 PropertyRNA *RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, int default_value,
2133                              const char *ui_name, const char *ui_description)
2134 {
2135         ContainerRNA *cont = cont_;
2136         PropertyRNA *prop;
2137         
2138         prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_NONE);
2139         RNA_def_property_boolean_default(prop, default_value);
2140         RNA_def_property_ui_text(prop, ui_name, ui_description);
2141
2142         return prop;
2143 }
2144
2145 PropertyRNA *RNA_def_boolean_array(StructOrFunctionRNA *cont_, const char *identifier, int len, int *default_value,
2146                                    const char *ui_name, const char *ui_description)
2147 {
2148         ContainerRNA *cont = cont_;
2149         PropertyRNA *prop;
2150         
2151         prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_NONE);
2152         if (len != 0) RNA_def_property_array(prop, len);
2153         if (default_value) RNA_def_property_boolean_array_default(prop, default_value);
2154         RNA_def_property_ui_text(prop, ui_name, ui_description);
2155
2156         return prop;
2157 }
2158
2159 PropertyRNA *RNA_def_boolean_layer(StructOrFunctionRNA *cont_, const char *identifier, int len, int *default_value,
2160                                    const char *ui_name, const char *ui_description)
2161 {
2162         ContainerRNA *cont = cont_;
2163         PropertyRNA *prop;
2164         
2165         prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_LAYER);
2166         if (len != 0) RNA_def_property_array(prop, len);
2167         if (default_value) RNA_def_property_boolean_array_default(prop, default_value);
2168         RNA_def_property_ui_text(prop, ui_name, ui_description);
2169
2170         return prop;
2171 }
2172
2173 PropertyRNA *RNA_def_boolean_layer_member(StructOrFunctionRNA *cont_, const char *identifier, int len,
2174                                           int *default_value, const char *ui_name, const char *ui_description)
2175 {
2176         ContainerRNA *cont = cont_;
2177         PropertyRNA *prop;
2178         
2179         prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_LAYER_MEMBER);
2180         if (len != 0) RNA_def_property_array(prop, len);
2181         if (default_value) RNA_def_property_boolean_array_default(prop, default_value);
2182         RNA_def_property_ui_text(prop, ui_name, ui_description);
2183
2184         return prop;
2185 }
2186
2187 PropertyRNA *RNA_def_boolean_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, int *default_value,
2188                                     const char *ui_name, const char *ui_description)
2189 {
2190         ContainerRNA *cont = cont_;
2191         PropertyRNA *prop;
2192         
2193         prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_XYZ); /* XXX */
2194         if (len != 0) RNA_def_property_array(prop, len);
2195         if (default_value) RNA_def_property_boolean_array_default(prop, default_value);
2196         RNA_def_property_ui_text(prop, ui_name, ui_description);
2197
2198         return prop;
2199 }
2200
2201 PropertyRNA *RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin,
2202                          int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
2203 {
2204         ContainerRNA *cont = cont_;
2205         PropertyRNA *prop;
2206         
2207         prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE);
2208         RNA_def_property_int_default(prop, default_value);
2209         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2210         RNA_def_property_ui_text(prop, ui_name, ui_description);
2211         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2212
2213         return prop;
2214 }
2215
2216 PropertyRNA *RNA_def_int_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, const int *default_value,
2217                                 int hardmin, int hardmax, const char *ui_name, const char *ui_description,
2218                                 int softmin, int softmax)
2219 {
2220         ContainerRNA *cont = cont_;
2221         PropertyRNA *prop;
2222         
2223         prop = RNA_def_property(cont, identifier, PROP_INT, PROP_XYZ); /* XXX */
2224         if (len != 0) RNA_def_property_array(prop, len);
2225         if (default_value) RNA_def_property_int_array_default(prop, default_value);
2226         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2227         RNA_def_property_ui_text(prop, ui_name, ui_description);
2228         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2229
2230         return prop;
2231 }
2232
2233 PropertyRNA *RNA_def_int_array(StructOrFunctionRNA *cont_, const char *identifier, int len, const int *default_value,
2234                                int hardmin, int hardmax, const char *ui_name, const char *ui_description,
2235                                int softmin, int softmax)
2236 {
2237         ContainerRNA *cont = cont_;
2238         PropertyRNA *prop;
2239         
2240         prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE);
2241         if (len != 0) RNA_def_property_array(prop, len);
2242         if (default_value) RNA_def_property_int_array_default(prop, default_value);
2243         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2244         RNA_def_property_ui_text(prop, ui_name, ui_description);
2245         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2246
2247         return prop;
2248 }
2249
2250 PropertyRNA *RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen,
2251                             const char *ui_name, const char *ui_description)
2252 {
2253         ContainerRNA *cont = cont_;
2254         PropertyRNA *prop;
2255         
2256         prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_NONE);
2257         if (maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen);
2258         if (default_value) RNA_def_property_string_default(prop, default_value);
2259         RNA_def_property_ui_text(prop, ui_name, ui_description);
2260
2261         return prop;
2262 }
2263
2264 PropertyRNA *RNA_def_string_file_path(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value,
2265                                       int maxlen, const char *ui_name, const char *ui_description)
2266 {
2267         ContainerRNA *cont = cont_;
2268         PropertyRNA *prop;
2269         
2270         prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_FILEPATH);
2271         if (maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen);
2272         if (default_value) RNA_def_property_string_default(prop, default_value);
2273         RNA_def_property_ui_text(prop, ui_name, ui_description);
2274
2275         return prop;
2276 }
2277
2278 PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value,
2279                                      int maxlen, const char *ui_name, const char *ui_description)
2280 {
2281         ContainerRNA *cont = cont_;
2282         PropertyRNA *prop;
2283         
2284         prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_DIRPATH);
2285         if (maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen);
2286         if (default_value) RNA_def_property_string_default(prop, default_value);
2287         RNA_def_property_ui_text(prop, ui_name, ui_description);
2288
2289         return prop;
2290 }
2291
2292 PropertyRNA *RNA_def_string_file_name(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value,
2293                                       int maxlen, const char *ui_name, const char *ui_description)
2294 {
2295         ContainerRNA *cont = cont_;
2296         PropertyRNA *prop;
2297         
2298         prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_FILENAME);
2299         if (maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen);
2300         if (default_value) RNA_def_property_string_default(prop, default_value);
2301         RNA_def_property_ui_text(prop, ui_name, ui_description);
2302
2303         return prop;
2304 }
2305
2306 PropertyRNA *RNA_def_string_translate(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value,
2307                                       int maxlen, const char *ui_name, const char *ui_description)
2308 {
2309         ContainerRNA *cont = cont_;
2310         PropertyRNA *prop;
2311
2312         prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_TRANSLATE);
2313         if (maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen);
2314         if (default_value) RNA_def_property_string_default(prop, default_value);
2315         RNA_def_property_ui_text(prop, ui_name, ui_description);
2316
2317         return prop;
2318 }
2319
2320 PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items,
2321                           int default_value, const char *ui_name, const char *ui_description)
2322 {
2323         ContainerRNA *cont = cont_;
2324         PropertyRNA *prop;
2325
2326         if (!items) {
2327                 printf("%s: items not allowed to be NULL.\n", __func__);
2328                 return NULL;
2329         }
2330         
2331         prop = RNA_def_property(cont, identifier, PROP_ENUM, PROP_NONE);
2332         if (items) RNA_def_property_enum_items(prop, items);
2333         RNA_def_property_enum_default(prop, default_value);
2334         RNA_def_property_ui_text(prop, ui_name, ui_description);
2335
2336         return prop;
2337 }
2338
2339 /* same as above but sets 'PROP_ENUM_FLAG' before setting the default value */
2340 PropertyRNA *RNA_def_enum_flag(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items,
2341                                int default_value, const char *ui_name, const char *ui_description)
2342 {
2343         ContainerRNA *cont = cont_;
2344         PropertyRNA *prop;
2345
2346         if (!items) {
2347                 printf("%s: items not allowed to be NULL.\n", __func__);
2348                 return NULL;
2349         }
2350
2351         prop = RNA_def_property(cont, identifier, PROP_ENUM, PROP_NONE);
2352         RNA_def_property_flag(prop, PROP_ENUM_FLAG); /* important to run before default set */
2353         if (items) RNA_def_property_enum_items(prop, items);
2354         RNA_def_property_enum_default(prop, default_value);
2355         RNA_def_property_ui_text(prop, ui_name, ui_description);
2356
2357         return prop;
2358 }
2359
2360 void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
2361 {
2362         EnumPropertyRNA *eprop = (EnumPropertyRNA*)prop;
2363         eprop->itemf = itemfunc;
2364 }
2365
2366 void RNA_def_enum_py_data(PropertyRNA *prop, void *py_data)
2367 {
2368         EnumPropertyRNA *eprop = (EnumPropertyRNA*)prop;
2369         eprop->py_data = py_data;
2370 }
2371
2372 PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value,
2373                            float hardmin, float hardmax, const char *ui_name, const char *ui_description,
2374                            float softmin, float softmax)
2375 {
2376         ContainerRNA *cont = cont_;
2377         PropertyRNA *prop;
2378         
2379         prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE);
2380         RNA_def_property_float_default(prop, default_value);
2381         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2382         RNA_def_property_ui_text(prop, ui_name, ui_description);
2383         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2384
2385         return prop;
2386 }
2387
2388 PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont_, const char *identifier, int len,
2389                                   const float *default_value, float hardmin, float hardmax, const char *ui_name,
2390                                   const char *ui_description, float softmin, float softmax)
2391 {
2392         ContainerRNA *cont = cont_;
2393         PropertyRNA *prop;
2394         
2395         prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_XYZ);
2396         if (len != 0) RNA_def_property_array(prop, len);
2397         if (default_value) RNA_def_property_float_array_default(prop, default_value);
2398         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2399         RNA_def_property_ui_text(prop, ui_name, ui_description);
2400         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2401
2402         return prop;
2403 }
2404
2405 PropertyRNA *RNA_def_float_vector_xyz(StructOrFunctionRNA *cont_, const char *identifier, int len,
2406                                       const float *default_value, float hardmin, float hardmax, const char *ui_name,
2407                                       const char *ui_description, float softmin, float softmax)
2408 {
2409         PropertyRNA *prop;
2410         
2411         prop = RNA_def_float_vector(cont_, identifier, len, default_value, hardmin, hardmax, ui_name, ui_description,
2412                                     softmin, softmax);
2413         prop->subtype = PROP_XYZ_LENGTH;
2414
2415         return prop;
2416 }
2417
2418 PropertyRNA *RNA_def_float_color(StructOrFunctionRNA *cont_, const char *identifier, int len,
2419                                  const float *default_value, float hardmin, float hardmax, const char *ui_name,
2420                                  const char *ui_description, float softmin, float softmax)
2421 {
2422         ContainerRNA *cont = cont_;
2423         PropertyRNA *prop;
2424         
2425         prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_COLOR);
2426         if (len != 0) RNA_def_property_array(prop, len);
2427         if (default_value) RNA_def_property_float_array_default(prop, default_value);
2428         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2429         RNA_def_property_ui_text(prop, ui_name, ui_description);
2430         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2431
2432         return prop;
2433 }
2434
2435
2436 PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont_, const char *identifier, int rows, int columns,
2437                                   const float *default_value, float hardmin, float hardmax, const char *ui_name,
2438                                   const char *ui_description, float softmin, float softmax)
2439 {
2440         ContainerRNA *cont = cont_;
2441         PropertyRNA *prop;
2442         int length[2];
2443
2444         length[0] = rows;
2445         length[1] = columns;
2446
2447         prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_MATRIX);
2448         RNA_def_property_multi_array(prop, 2, length);
2449         if (default_value) RNA_def_property_float_array_default(prop, default_value);
2450         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2451         RNA_def_property_ui_text(prop, ui_name, ui_description);
2452         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2453
2454         return prop;
2455 }
2456
2457 PropertyRNA *RNA_def_float_rotation(StructOrFunctionRNA *cont_, const char *identifier, int len,
2458                                     const float *default_value, float hardmin, float hardmax, const char *ui_name,
2459                                     const char *ui_description, float softmin, float softmax)
2460 {
2461         ContainerRNA *cont = cont_;
2462         PropertyRNA *prop;
2463         
2464         prop = RNA_def_property(cont, identifier, PROP_FLOAT, (len != 0) ? PROP_EULER : PROP_ANGLE);
2465         if (len != 0) {
2466                 RNA_def_property_array(prop, len);
2467                 if (default_value) RNA_def_property_float_array_default(prop, default_value);
2468         }
2469         else {
2470                 /* RNA_def_property_float_default must be called outside */
2471                 BLI_assert(default_value == NULL);
2472         }
2473         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2474         RNA_def_property_ui_text(prop, ui_name, ui_description);
2475         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2476
2477         return prop;
2478 }
2479
2480 PropertyRNA *RNA_def_float_array(StructOrFunctionRNA *cont_, const char *identifier, int len,
2481                                  const float *default_value, float hardmin, float hardmax, const char *ui_name,
2482                                  const char *ui_description, float softmin, float softmax)
2483 {
2484         ContainerRNA *cont = cont_;
2485         PropertyRNA *prop;
2486         
2487         prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE);
2488         if (len != 0) RNA_def_property_array(prop, len);
2489         if (default_value) RNA_def_property_float_array_default(prop, default_value);
2490         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2491         RNA_def_property_ui_text(prop, ui_name, ui_description);
2492         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2493
2494         return prop;
2495 }
2496
2497 PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont_, const char *identifier, float default_value,
2498                                       float hardmin, float hardmax, const char *ui_name, const char *ui_description,
2499                                       float softmin, float softmax)
2500 {
2501         ContainerRNA *cont = cont_;
2502         PropertyRNA *prop;
2503         
2504         prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_PERCENTAGE);
2505         RNA_def_property_float_default(prop, default_value);
2506         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2507         RNA_def_property_ui_text(prop, ui_name, ui_description);
2508         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2509
2510         return prop;
2511 }
2512
2513 PropertyRNA *RNA_def_float_factor(StructOrFunctionRNA *cont_, const char *identifier, float default_value,
2514                                   float hardmin, float hardmax, const char *ui_name, const char *ui_description,
2515                                   float softmin, float softmax)
2516 {
2517         ContainerRNA *cont = cont_;
2518         PropertyRNA *prop;
2519         
2520         prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_FACTOR);
2521         RNA_def_property_float_default(prop, default_value);
2522         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2523         RNA_def_property_ui_text(prop, ui_name, ui_description);
2524         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2525
2526         return prop;
2527 }
2528
2529 PropertyRNA *RNA_def_pointer(StructOrFunctionRNA *cont_, const char *identifier, const char *type,
2530                              const char *ui_name, const char *ui_description)
2531 {
2532         ContainerRNA *cont = cont_;
2533         PropertyRNA *prop;
2534         
2535         prop = RNA_def_property(cont, identifier, PROP_POINTER, PROP_NONE);
2536         RNA_def_property_struct_type(prop, type);
2537         RNA_def_property_ui_text(prop, ui_name, ui_description);
2538
2539         return prop;
2540 }
2541
2542 PropertyRNA *RNA_def_pointer_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type,
2543                                      const char *ui_name, const char *ui_description)
2544 {
2545         ContainerRNA *cont = cont_;
2546         PropertyRNA *prop;
2547         
2548         prop = RNA_def_property(cont, identifier, PROP_POINTER, PROP_NONE);
2549         RNA_def_property_struct_runtime(prop, type);
2550         RNA_def_property_ui_text(prop, ui_name, ui_description);
2551
2552         return prop;
2553 }
2554
2555 PropertyRNA *RNA_def_collection(StructOrFunctionRNA *cont_, const char *identifier, const char *type,
2556                                 const char *ui_name, const char *ui_description)
2557 {
2558         ContainerRNA *cont = cont_;
2559         PropertyRNA *prop;
2560         
2561         prop = RNA_def_property(cont, identifier, PROP_COLLECTION, PROP_NONE);
2562         RNA_def_property_struct_type(prop, type);
2563         RNA_def_property_ui_text(prop, ui_name, ui_description);
2564
2565         return prop;
2566 }
2567
2568 PropertyRNA *RNA_def_collection_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type,
2569                                         const char *ui_name, const char *ui_description)
2570 {
2571         ContainerRNA *cont = cont_;
2572         PropertyRNA *prop;
2573         
2574         prop = RNA_def_property(cont, identifier, PROP_COLLECTION, PROP_NONE);
2575         RNA_def_property_struct_runtime(prop, type);
2576         RNA_def_property_ui_text(prop, ui_name, ui_description);
2577
2578         return prop;
2579 }
2580
2581 /* Function */
2582
2583 static FunctionRNA *rna_def_function(StructRNA *srna, const char *identifier)
2584 {
2585         FunctionRNA *func;
2586         StructDefRNA *dsrna;
2587         FunctionDefRNA *dfunc;
2588
2589         if (DefRNA.preprocess) {
2590                 char error[512];
2591
2592                 if (rna_validate_identifier(identifier, error, 0) == 0) {
2593                         fprintf(stderr, "%s: function identifier \"%s\" - %s\n", __func__, identifier, error);
2594                         DefRNA.error = 1;
2595                 }
2596         }
2597
2598         func = MEM_callocN(sizeof(FunctionRNA), "FunctionRNA");
2599         func->identifier = identifier;
2600         func->description = identifier;
2601
2602         rna_addtail(&srna->functions, func);
2603
2604         if (DefRNA.preprocess) {
2605                 dsrna = rna_find_struct_def(srna);
2606                 dfunc = MEM_callocN(sizeof(FunctionDefRNA), "FunctionDefRNA");
2607                 rna_addtail(&dsrna->functions, dfunc);
2608                 dfunc->func = func;
2609         }
2610         else
2611                 func->flag |= FUNC_RUNTIME;
2612
2613         return func;
2614 }
2615
2616 FunctionRNA *RNA_def_function(StructRNA *srna, const char *identifier, const char *call)
2617 {
2618         FunctionRNA *func;
2619         FunctionDefRNA *dfunc;
2620
2621         func = rna_def_function(srna, identifier);
2622
2623         if (!DefRNA.preprocess) {
2624                 fprintf(stderr, "%s: only at preprocess time.\n", __func__);
2625                 return func;
2626         }
2627
2628         dfunc = rna_find_function_def(func);
2629         dfunc->call = call;
2630
2631         return func;
2632 }
2633
2634 FunctionRNA *RNA_def_function_runtime(StructRNA *srna, const char *identifier, CallFunc call)
2635 {
2636         FunctionRNA *func;
2637
2638         func = rna_def_function(srna, identifier);
2639
2640         if (DefRNA.preprocess) {
2641                 fprintf(stderr, "%s: only at runtime.\n", __func__);
2642                 return func;
2643         }
2644
2645         func->call = call;
2646
2647
2648         return func;
2649 }
2650
2651 /* C return value only!, multiple RNA returns can be done with RNA_def_function_output */
2652 void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret)
2653 {
2654         if (ret->flag & PROP_DYNAMIC) {
2655                 fprintf(stderr, "%s: \"%s.%s\", dynamic values are not allowed as strict returns, "
2656                         "use RNA_def_function_output instead.\n", __func__, func->identifier, ret->identifier);
2657                 return;
2658         }
2659         else if (ret->arraydimension) {
2660                 fprintf(stderr, "%s: \"%s.%s\", arrays are not allowed as strict returns, "
2661                         "use RNA_def_function_output instead.\n", __func__, func->identifier, ret->identifier);
2662                 return;
2663         }
2664
2665         func->c_ret = ret;
2666
2667         RNA_def_function_output(func, ret);
2668 }
2669
2670 void RNA_def_function_output(FunctionRNA *UNUSED(func), PropertyRNA *ret)
2671 {
2672         ret->flag |= PROP_OUTPUT;
2673 }
2674
2675 void RNA_def_function_flag(FunctionRNA *func, int flag)
2676 {
2677         func->flag |= flag;
2678 }
2679
2680 void RNA_def_function_ui_description(FunctionRNA *func, const char *description)
2681 {
2682         func->description = description;
2683 }
2684
2685 int rna_parameter_size(PropertyRNA *parm)
2686 {
2687         PropertyType ptype = parm->type;
2688         int len = parm->totarraylength; /* only supports fixed length at the moment */
2689
2690         if (len > 0) {
2691                 /* XXX in other parts is mentioned that strings can be dynamic as well */
2692                 if (parm->flag & PROP_DYNAMIC)
2693                         return sizeof(void *);
2694
2695                 switch (ptype) {
2696                         case PROP_BOOLEAN:
2697                         case PROP_INT:
2698                                 return sizeof(int)*len;
2699                         case PROP_FLOAT:
2700                                 return sizeof(float)*len;
2701                         default:
2702                                 break;
2703                 }
2704         }
2705         else {
2706                 switch (ptype) {
2707                         case PROP_BOOLEAN:
2708                         case PROP_INT:
2709                         case PROP_ENUM:
2710                                 return sizeof(int);
2711                         case PROP_FLOAT:
2712                                 return sizeof(float);
2713                         case PROP_STRING:
2714                                 /* return values don't store a pointer to the original */
2715                                 if (parm->flag & PROP_THICK_WRAP) {
2716                                         StringPropertyRNA *sparm = (StringPropertyRNA*)parm;
2717                                         return sizeof(char) * sparm->maxlength;
2718                                 }
2719                                 else
2720                                         return sizeof(char *);
2721                         case PROP_POINTER: {
2722 #ifdef RNA_RUNTIME
2723                                 if (parm->flag & PROP_RNAPTR)
2724                                         return sizeof(PointerRNA);
2725                                 else
2726                                         return sizeof(void *);
2727 #else
2728                                 if (parm->flag & PROP_RNAPTR)
2729                                         return sizeof(PointerRNA);
2730                                 else
2731                                         return sizeof(void *);
2732 #endif
2733                         }
2734                         case PROP_COLLECTION:
2735                                 return sizeof(ListBase);
2736                 }
2737         }
2738
2739         return sizeof(void *);
2740 }
2741
2742 /* this function returns the size of the memory allocated for the parameter,
2743  * useful for instance for memory alignment or for storing additional information */
2744 int rna_parameter_size_alloc(PropertyRNA *parm)
2745 {
2746         int size = rna_parameter_size(parm);
2747
2748         if (parm->flag & PROP_DYNAMIC)
2749                 size += sizeof(((ParameterDynAlloc *)NULL)->array_tot);
2750
2751         return size;
2752 }
2753
2754 /* Dynamic Enums */
2755
2756 void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
2757 {
2758         EnumPropertyItem *newitems;
2759         int tot = *totitem;
2760
2761         if (tot == 0) {
2762                 *items = MEM_callocN(sizeof(EnumPropertyItem)*8, "RNA_enum_items_add");
2763         }
2764         else if (tot >= 8 && (tot&(tot-1)) == 0) {
2765                 /* power of two > 8 */
2766                 newitems = MEM_callocN(sizeof(EnumPropertyItem)*tot*2, "RNA_enum_items_add");
2767                 memcpy(newitems, *items, sizeof(EnumPropertyItem)*tot);
2768                 MEM_freeN(*items);
2769                 *items = newitems;
2770         }
2771
2772         (*items)[tot] = *item;
2773         *totitem = tot+1;
2774 }
2775
2776 void RNA_enum_item_add_separator(EnumPropertyItem **items, int *totitem)
2777 {
2778         static EnumPropertyItem sepr = {0, "", 0, NULL, NULL};
2779         RNA_enum_item_add(items, totitem, &sepr);
2780 }
2781
2782 void RNA_enum_items_add(EnumPropertyItem **items, int *totitem, EnumPropertyItem *item)
2783 {
2784         for (; item->identifier; item++)
2785                 RNA_enum_item_add(items, totitem, item);
2786 }
2787
2788 void RNA_enum_items_add_value(EnumPropertyItem **items, int *totitem, EnumPropertyItem *item, int value)
2789 {
2790         for (; item->identifier; item++) {
2791                 if (item->value == value) {
2792                         RNA_enum_item_add(items, totitem, item);
2793                         /* break on first match - does this break anything?
2794                          * (is quick hack to get object->parent_type working ok for armature/lattice) */
2795                         break;
2796                 }
2797         }
2798 }
2799
2800 void RNA_enum_item_end(EnumPropertyItem **items, int *totitem)
2801 {
2802         static EnumPropertyItem empty = {0, NULL, 0, NULL, NULL};
2803         RNA_enum_item_add(items, totitem, &empty);
2804 }
2805
2806 /* Memory management */
2807
2808 #ifdef RNA_RUNTIME
2809 void RNA_def_struct_duplicate_pointers(StructRNA *srna)
2810 {
2811         if (srna->identifier) srna->identifier = BLI_strdup(srna->identifier);
2812         if (srna->name) srna->name = BLI_strdup(srna->name);
2813         if (srna->description) srna->description = BLI_strdup(srna->description);
2814
2815         srna->flag |= STRUCT_FREE_POINTERS;
2816 }
2817
2818 void RNA_def_struct_free_pointers(StructRNA *srna)
2819 {
2820         if (srna->flag & STRUCT_FREE_POINTERS) {
2821                 if (srna->identifier) MEM_freeN((void*)srna->identifier);
2822                 if (srna->name) MEM_freeN((void*)srna->name);
2823                 if (srna->description) MEM_freeN((void*)srna->description);
2824         }
2825 }
2826
2827 void RNA_def_func_duplicate_pointers(FunctionRNA *func)
2828 {
2829         if (func->identifier) func->identifier = BLI_strdup(func->identifier);
2830         if (func->description) func->description = BLI_strdup(func->description);
2831
2832         func->flag |= FUNC_FREE_POINTERS;
2833 }
2834
2835 void RNA_def_func_free_pointers(FunctionRNA *func)
2836 {
2837         if (func->flag & FUNC_FREE_POINTERS) {
2838                 if (func->identifier) MEM_freeN((void*)func->identifier);
2839                 if (func->description) MEM_freeN((void*)func->description);
2840         }
2841 }
2842
2843 void RNA_def_property_duplicate_pointers(StructOrFunctionRNA *cont_, PropertyRNA *prop)
2844 {
2845         ContainerRNA *cont = cont_;
2846         EnumPropertyItem *earray;
2847         float *farray;
2848         int *iarray;
2849         int a;
2850
2851         /* annoying since we just added this to a hash, could make this add the correct key to the hash
2852          * in the first place */
2853         if (prop->identifier) {
2854                 if (cont->prophash) {
2855                         BLI_ghash_remove(cont->prophash, (void*)prop->identifier, NULL, NULL);
2856                         prop->identifier = BLI_strdup(prop->identifier);
2857                         BLI_ghash_insert(cont->prophash, (void*)prop->identifier, prop);
2858                 }
2859                 else {
2860                         prop->identifier = BLI_strdup(prop->identifier);
2861                 }
2862         }
2863
2864         if (prop->name) prop->name = BLI_strdup(prop->name);
2865         if (prop->description) prop->description = BLI_strdup(prop->description);
2866
2867         switch (prop->type) {
2868                 case PROP_BOOLEAN: {
2869                         BoolPropertyRNA *bprop = (BoolPropertyRNA*)prop;
2870
2871                         if (bprop->defaultarray) {
2872                                 iarray = MEM_callocN(sizeof(int)*prop->totarraylength, "RNA_def_property_store");
2873                                 memcpy(iarray, bprop->defaultarray, sizeof(int)*prop->totarraylength);
2874                                 bprop->defaultarray = iarray;
2875                         }
2876                         break;
2877                 }
2878                 case PROP_INT: {
2879                         IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
2880
2881                         if (iprop->defaultarray) {
2882                                 iarray = MEM_callocN(sizeof(int)*prop->totarraylength, "RNA_def_property_store");
2883                                 memcpy(iarray, iprop->defaultarray, sizeof(int)*prop->totarraylength);
2884                                 iprop->defaultarray = iarray;
2885                         }
2886                         break;
2887                 }
2888                 case PROP_ENUM: {
2889                         EnumPropertyRNA *eprop = (EnumPropertyRNA*)prop;
2890
2891                         if (eprop->item) {
2892                                 earray = MEM_callocN(sizeof(EnumPropertyItem)*(eprop->totitem+1), "RNA_def_property_store"),
2893                                 memcpy(earray, eprop->item, sizeof(EnumPropertyItem)*(eprop->totitem+1));
2894                                 eprop->item = earray;
2895
2896                                 for (a = 0; a<eprop->totitem; a++) {
2897                                         if (eprop->item[a].identifier)
2898                                                 eprop->item[a].identifier = BLI_strdup(eprop->item[a].identifier);
2899                                         if (eprop->item[a].name)
2900                                                 eprop->item[a].name = BLI_strdup(eprop->item[a].name);
2901                                         if (eprop->item[a].description)
2902                                                 eprop->item[a].description = BLI_strdup(eprop->item[a].description);
2903                                 }
2904                         }
2905                         break;
2906                 }
2907                 case PROP_FLOAT: {
2908                         FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
2909
2910                         if (fprop->defaultarray) {
2911                                 farray = MEM_callocN(sizeof(float)*prop->totarraylength, "RNA_def_property_store");
2912                                 memcpy(farray, fprop->defaultarray, sizeof(float)*prop->totarraylength);
2913                                 fprop->defaultarray = farray;
2914                         }
2915                         break;
2916                 }
2917                 case PROP_STRING: {
2918                         StringPropertyRNA *sprop = (StringPropertyRNA*)prop;
2919                         if (sprop->defaultvalue)
2920                                 sprop->defaultvalue = BLI_strdup(sprop->defaultvalue);
2921                         break;
2922                 }
2923                 default:
2924                         break;
2925         }
2926
2927         prop->flag |= PROP_FREE_POINTERS;
2928 }
2929
2930 void RNA_def_property_free_pointers(PropertyRNA *prop)
2931 {
2932         if (prop->flag & PROP_FREE_POINTERS) {
2933                 int a;
2934
2935                 if (prop->identifier)
2936                         MEM_freeN((void*)prop->identifier);
2937                 if (prop->name)
2938                         MEM_freeN((void*)prop->name);
2939                 if (prop->description)
2940                         MEM_freeN((void*)prop->description);
2941                 if (prop->py_data)
2942                         MEM_freeN(prop->py_data);
2943
2944                 switch (prop->type) {
2945                         case PROP_BOOLEAN: {
2946                                 BoolPropertyRNA *bprop = (BoolPropertyRNA*)prop;
2947                                 if (bprop->defaultarray)
2948                                         MEM_freeN((void*)bprop->defaultarray);
2949                                 break;
2950                         }
2951                         case PROP_INT: {
2952                                 IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
2953                                 if (iprop->defaultarray)
2954                                         MEM_freeN((void*)iprop->defaultarray);
2955                                 break;
2956                         }
2957                         case PROP_FLOAT: {
2958                                 FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
2959                                 if (fprop->defaultarray)
2960                                         MEM_freeN((void*)fprop->defaultarray);
2961                                 break;
2962                         }
2963                         case PROP_ENUM: {
2964                                 EnumPropertyRNA *eprop = (EnumPropertyRNA*)prop;
2965
2966                                 for (a = 0; a<eprop->totitem; a++) {
2967                                         if (eprop->item[a].identifier)
2968                                                 MEM_freeN((void*)eprop->item[a].identifier);
2969                                         if (eprop->item[a].name)
2970                                                 MEM_freeN((void*)eprop->item[a].name);
2971                                         if (eprop->item[a].description)
2972                                                 MEM_freeN((void*)eprop->item[a].description);
2973                                 }
2974
2975                                 if (eprop->item) MEM_freeN((void*)eprop->item);
2976                                 break;
2977                         }
2978                         case PROP_STRING: {
2979                                 StringPropertyRNA *sprop = (StringPropertyRNA*)prop;
2980                                 if (sprop->defaultvalue)
2981                                         MEM_freeN((void*)sprop->defaultvalue);
2982                                 break;
2983                         }
2984                         default:
2985                                 break;
2986                 }
2987         }
2988 }
2989
2990 static void rna_def_property_free(StructOrFunctionRNA *cont_, PropertyRNA *prop)
2991 {
2992         ContainerRNA *cont = cont_;
2993         
2994         if (prop->flag & PROP_RUNTIME) {
2995                 if (cont->prophash)
2996                         BLI_ghash_remove(cont->prophash, (void*)prop->identifier, NULL, NULL);
2997
2998                 RNA_def_property_free_pointers(prop);
2999                 rna_freelinkN(&cont->properties, prop);
3000         }
3001         else {
3002                 RNA_def_property_free_pointers(prop);
3003         }
3004 }
3005
3006 /* note: only intended for removing dynamic props */
3007 int RNA_def_property_free_identifier(StructOrFunctionRNA *cont_, const char *identifier)
3008 {
3009         ContainerRNA *cont = cont_;
3010         PropertyRNA *prop;
3011         
3012         for (prop = cont->properties.first; prop; prop = prop->next) {
3013                 if (strcmp(prop->identifier, identifier) == 0) {
3014                         if (prop->flag & PROP_RUNTIME) {
3015                                 rna_def_property_free(cont_, prop);
3016                                 return 1;
3017                         }
3018                         else {
3019                                 return -1;
3020                         }
3021                 }
3022         }
3023         return 0;
3024 }
3025 #endif
3026
3027 const char *RNA_property_typename(PropertyType type)
3028 {
3029         switch (type) {
3030                 case PROP_BOOLEAN: return "PROP_BOOLEAN";
3031                 case PROP_INT: return "PROP_INT";
3032                 case PROP_FLOAT: return "PROP_FLOAT";
3033                 case PROP_STRING: return "PROP_STRING";
3034                 case PROP_ENUM: return "PROP_ENUM";
3035                 case PROP_POINTER: return "PROP_POINTER";
3036                 case PROP_COLLECTION: return "PROP_COLLECTION";
3037         }
3038
3039         return "PROP_UNKNOWN";
3040 }