78780678af4fcc5a0d97b7cfb46edd6990521a91
[blender-staging.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/reference/lexical_analysis.html#id5 */
380         static const char *kwlist[] = {
381                 "and", "as", "assert", "break",
382                 "class", "continue", "def", "del",
383                 "elif", "else", "except", "exec",
384                 "finally", "for", "from", "global",
385                 "if", "import", "in", "is",
386                 "lambda", "not", "or", "pass",
387                 "print", "raise", "return", "try",
388                 "while", "with", "yield", NULL
389         };
390         
391         
392         if (!isalpha(identifier[0])) {
393                 strcpy(error, "first character failed isalpha() check");
394                 return 0;
395         }
396         
397         for (a = 0; identifier[a]; a++) {
398                 if (DefRNA.preprocess && property) {
399                         if (isalpha(identifier[a]) && isupper(identifier[a])) {
400                                 strcpy(error, "property names must contain lower case characters only");
401                                 return 0;
402                         }
403                 }
404                 
405                 if (identifier[a] =='_') {
406                         continue;
407                 }
408
409                 if (identifier[a] ==' ') {
410                         strcpy(error, "spaces are not okay in identifier names");
411                         return 0;
412                 }
413
414                 if (isalnum(identifier[a]) == 0) {
415                         strcpy(error, "one of the characters failed an isalnum() check and is not an underscore");
416                         return 0;
417                 }
418         }
419         
420         for (a = 0; kwlist[a]; a++) {
421                 if (strcmp(identifier, kwlist[a]) == 0) {
422                         strcpy(error, "this keyword is reserved by python");
423                         return 0;
424                 }
425         }
426
427         if (property) {
428                 static const char *kwlist_prop[] = {
429                         /* not keywords but reserved all the same because py uses */
430                         "keys", "values", "items", "get",
431                         NULL
432                 };
433
434                 for (a = 0; kwlist_prop[a]; a++) {
435                         if (strcmp(identifier, kwlist_prop[a]) == 0) {
436                                 strcpy(error, "this keyword is reserved by python");
437                                 return 0;
438                         }
439                 }
440         }
441         
442         return 1;
443 }
444
445 /* Blender Data Definition */
446
447 BlenderRNA *RNA_create(void)
448 {
449         BlenderRNA *brna;
450
451         brna = MEM_callocN(sizeof(BlenderRNA), "BlenderRNA");
452
453         DefRNA.sdna = DNA_sdna_from_data(DNAstr,  DNAlen, 0);
454         DefRNA.structs.first = DefRNA.structs.last = NULL;
455         DefRNA.error = 0;
456         DefRNA.preprocess = 1;
457
458         return brna;
459 }
460
461 void RNA_define_free(BlenderRNA *UNUSED(brna))
462 {
463         StructDefRNA *ds;
464         FunctionDefRNA *dfunc;
465         AllocDefRNA *alloc;
466
467         for (alloc = DefRNA.allocs.first; alloc; alloc = alloc->next)
468                 MEM_freeN(alloc->mem);
469         rna_freelistN(&DefRNA.allocs);
470
471         for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) {
472                 for (dfunc = ds->functions.first; dfunc; dfunc = dfunc->cont.next)
473                         rna_freelistN(&dfunc->cont.properties);
474
475                 rna_freelistN(&ds->cont.properties);
476                 rna_freelistN(&ds->functions);
477         }
478
479         rna_freelistN(&DefRNA.structs);
480
481         if (DefRNA.sdna) {
482                 DNA_sdna_free(DefRNA.sdna);
483                 DefRNA.sdna = NULL;
484         }
485
486         DefRNA.error = 0;
487 }
488
489 void RNA_define_verify_sdna(int verify)
490 {
491         DefRNA.verify = verify;
492 }
493
494 void RNA_struct_free_extension(StructRNA *srna, ExtensionRNA *ext)
495 {
496 #ifdef RNA_RUNTIME
497         ext->free(ext->data);                   /* decref's the PyObject that the srna owns */
498         RNA_struct_blender_type_set(srna, NULL); /* this gets accessed again - XXX fixme */
499         RNA_struct_py_type_set(srna, NULL);     /* NULL the srna's value so RNA_struct_free wont complain of a leak */
500 #endif
501 }
502
503 void RNA_struct_free(BlenderRNA *brna, StructRNA *srna)
504 {
505 #ifdef RNA_RUNTIME
506         FunctionRNA *func, *nextfunc;
507         PropertyRNA *prop, *nextprop;
508         PropertyRNA *parm, *nextparm;
509
510         /*
511         if(srna->flag & STRUCT_RUNTIME) {
512                 if(RNA_struct_py_type_get(srna)) {
513                         fprintf(stderr, "%s '%s' freed while holding a python reference\n", __func__, srna->identifier);
514                 }
515         } */
516
517         for (prop = srna->cont.properties.first; prop; prop = nextprop) {
518                 nextprop = prop->next;
519
520                 RNA_def_property_free_pointers(prop);
521
522                 if (prop->flag & PROP_RUNTIME)
523                         rna_freelinkN(&srna->cont.properties, prop);
524         }
525
526         for (func = srna->functions.first; func; func = nextfunc) {
527                 nextfunc = func->cont.next;
528
529                 for (parm = func->cont.properties.first; parm; parm = nextparm) {
530                         nextparm = parm->next;
531
532                         RNA_def_property_free_pointers(parm);
533
534                         if (parm->flag & PROP_RUNTIME)
535                                 rna_freelinkN(&func->cont.properties, parm);
536                 }
537
538                 RNA_def_func_free_pointers(func);
539
540                 if (func->flag & FUNC_RUNTIME)
541                         rna_freelinkN(&srna->functions, func);
542         }
543
544         RNA_def_struct_free_pointers(srna);
545
546         if (srna->flag & STRUCT_RUNTIME)
547                 rna_freelinkN(&brna->structs, srna);
548
549 #endif
550 }
551
552 void RNA_free(BlenderRNA *brna)
553 {
554         StructRNA *srna, *nextsrna;
555         FunctionRNA *func;
556
557         if (DefRNA.preprocess) {
558                 RNA_define_free(brna);
559
560                 for (srna = brna->structs.first; srna; srna = srna->cont.next) {
561                         for (func = srna->functions.first; func; func = func->cont.next)
562                                 rna_freelistN(&func->cont.properties);
563
564                         rna_freelistN(&srna->cont.properties);
565                         rna_freelistN(&srna->functions);
566                 }
567
568                 rna_freelistN(&brna->structs);
569                 
570                 MEM_freeN(brna);
571         }
572         else {
573                 for (srna = brna->structs.first; srna; srna = nextsrna) {
574                         nextsrna = srna->cont.next;
575                         RNA_struct_free(brna, srna);
576                 }
577         }
578 }
579
580 static size_t rna_property_type_sizeof(PropertyType type)
581 {
582         switch (type) {
583                 case PROP_BOOLEAN: return sizeof(BoolPropertyRNA);
584                 case PROP_INT: return sizeof(IntPropertyRNA);
585                 case PROP_FLOAT: return sizeof(FloatPropertyRNA);
586                 case PROP_STRING: return sizeof(StringPropertyRNA);
587                 case PROP_ENUM: return sizeof(EnumPropertyRNA);
588                 case PROP_POINTER: return sizeof(PointerPropertyRNA);
589                 case PROP_COLLECTION: return sizeof(CollectionPropertyRNA);
590                 default: return 0;
591         }
592 }
593
594 static StructDefRNA *rna_find_def_struct(StructRNA *srna)
595 {
596         StructDefRNA *ds;
597
598         for (ds = DefRNA.structs.first; ds; ds = ds->cont.next)
599                 if (ds->srna == srna)
600                         return ds;
601
602         return NULL;
603 }
604
605 /* Struct Definition */
606
607 StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
608 {
609         StructRNA *srna, *srnafrom = NULL;
610         StructDefRNA *ds = NULL, *dsfrom = NULL;
611         PropertyRNA *prop;
612         
613         if (DefRNA.preprocess) {
614                 char error[512];
615
616                 if (rna_validate_identifier(identifier, error, 0) == 0) {
617                         fprintf(stderr, "%s: struct identifier \"%s\" error - %s\n", __func__, identifier, error);
618                         DefRNA.error = 1;
619                 }
620         }
621         
622         if (from) {
623                 /* find struct to derive from */
624                 for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next)
625                         if (strcmp(srnafrom->identifier, from) == 0)
626                                 break;
627
628                 if (!srnafrom) {
629                         fprintf(stderr, "%s: struct %s not found to define %s.\n", __func__, from, identifier);
630                         DefRNA.error = 1;
631                 }
632         }
633
634         srna = MEM_callocN(sizeof(StructRNA), "StructRNA");
635         DefRNA.laststruct = srna;
636
637         if (srnafrom) {
638                 /* copy from struct to derive stuff, a bit clumsy since we can't
639                  * use MEM_dupallocN, data structs may not be alloced but builtin */
640                 memcpy(srna, srnafrom, sizeof(StructRNA));
641                 srna->cont.prophash = NULL;
642                 srna->cont.properties.first = srna->cont.properties.last = NULL;
643                 srna->functions.first = srna->functions.last = NULL;
644                 srna->py_type = NULL;
645
646                 if (DefRNA.preprocess) {
647                         srna->base = srnafrom;
648                         dsfrom = rna_find_def_struct(srnafrom);
649                 }
650                 else
651                         srna->base = srnafrom;
652         }
653         
654         srna->identifier = identifier;
655         srna->name = identifier; /* may be overwritten later RNA_def_struct_ui_text */
656         srna->description = "";
657         srna->flag |= STRUCT_UNDO;
658         if (!srnafrom)
659                 srna->icon = ICON_DOT;
660
661         rna_addtail(&brna->structs, srna);
662
663         if (DefRNA.preprocess) {
664                 ds = MEM_callocN(sizeof(StructDefRNA), "StructDefRNA");
665                 ds->srna = srna;
666                 rna_addtail(&DefRNA.structs, ds);
667
668                 if (dsfrom)
669                         ds->dnafromname = dsfrom->dnaname;
670         }
671
672         /* in preprocess, try to find sdna */
673         if (DefRNA.preprocess)
674                 RNA_def_struct_sdna(srna, srna->identifier);
675         else
676                 srna->flag |= STRUCT_RUNTIME;
677
678         if (srnafrom) {
679                 srna->nameproperty = srnafrom->nameproperty;
680                 srna->iteratorproperty = srnafrom->iteratorproperty;
681         }
682         else {
683                 /* define some builtin properties */
684                 prop = RNA_def_property(&srna->cont, "rna_properties", PROP_COLLECTION, PROP_NONE);
685                 RNA_def_property_flag(prop, PROP_BUILTIN);
686                 RNA_def_property_ui_text(prop, "Properties", "RNA property collection");
687
688                 if (DefRNA.preprocess) {
689                         RNA_def_property_struct_type(prop, "Property");
690                         RNA_def_property_collection_funcs(prop, "rna_builtin_properties_begin", "rna_builtin_properties_next", "rna_iterator_listbase_end", "rna_builtin_properties_get", NULL, NULL, "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__, CONTAINER_RNA_ID(cont), identifier, error);
894                         DefRNA.error = 1;
895                 }
896                 
897                 dcont = rna_find_container_def(cont);
898
899                 /* XXX - toto, detect supertype collisions */
900                 if (rna_findlink(&dcont->properties, identifier)) {
901                         fprintf(stderr, "%s: duplicate identifier \"%s.%s\"\n", __func__, CONTAINER_RNA_ID(cont), identifier);
902                         DefRNA.error = 1;
903                 }
904
905                 dprop = MEM_callocN(sizeof(PropertyDefRNA), "PropertyDefRNA");
906                 rna_addtail(&dcont->properties, dprop);
907         }
908
909         prop = MEM_callocN(rna_property_type_sizeof(type), "PropertyRNA");
910
911         switch (type) {
912                 case PROP_BOOLEAN:
913                         break;
914                 case PROP_INT: {
915                         IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
916
917                         iprop->hardmin = (subtype == PROP_UNSIGNED)? 0: INT_MIN;
918                         iprop->hardmax = INT_MAX;
919
920                         iprop->softmin = (subtype == PROP_UNSIGNED)? 0: -10000; /* rather arbitrary .. */
921                         iprop->softmax = 10000;
922                         iprop->step = 1;
923                         break;
924                 }
925                 case PROP_FLOAT: {
926                         FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
927
928                         fprop->hardmin = (subtype == PROP_UNSIGNED)? 0.0f: -FLT_MAX;
929                         fprop->hardmax = FLT_MAX;
930
931                         if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
932                                 fprop->softmin = 0.0f;
933                                 fprop->softmax = 1.0f;
934                         }
935                         else if (subtype == PROP_FACTOR) {
936                                 fprop->softmin = fprop->hardmin = 0.0f;
937                                 fprop->softmax = fprop->hardmax = 1.0f;
938                         }
939                         else {
940                                 fprop->softmin = (subtype == PROP_UNSIGNED)? 0.0f: -10000.0f; /* rather arbitrary .. */
941                                 fprop->softmax = 10000.0f;
942                         }
943                         fprop->step = 10;
944                         fprop->precision = 3;
945                         break;
946                 }
947                 case PROP_STRING: {
948                         StringPropertyRNA *sprop = (StringPropertyRNA*)prop;
949
950                         sprop->defaultvalue = "";
951                         sprop->maxlength = 0;
952                         break;
953                 }
954                 case PROP_ENUM:
955                 case PROP_POINTER:
956                 case PROP_COLLECTION:
957                         break;
958                 default:
959                         fprintf(stderr, "%s: \"%s.%s\", invalid property type.\n", __func__, CONTAINER_RNA_ID(cont), identifier);
960                         DefRNA.error = 1;
961                         return NULL;
962         }
963
964         if (DefRNA.preprocess) {
965                 dprop->cont = cont;
966                 dprop->prop = prop;
967         }
968
969         prop->magic = RNA_MAGIC;
970         prop->identifier = identifier;
971         prop->type = type;
972         prop->subtype = subtype;
973         prop->name = identifier;
974         prop->description = "";
975         /* a priori not raw editable */
976         prop->rawtype = -1;
977
978         if (type != PROP_COLLECTION && type != PROP_POINTER) {
979                 prop->flag = PROP_EDITABLE;
980         
981                 if (type != PROP_STRING)
982                         prop->flag |= PROP_ANIMATABLE;
983         }
984
985         if (DefRNA.preprocess) {
986                 switch (type) {
987                         case PROP_BOOLEAN:
988                                 DefRNA.silent = 1;
989                                 RNA_def_property_boolean_sdna(prop, NULL, identifier, 0);
990                                 DefRNA.silent = 0;
991                                 break;
992                         case PROP_INT: {
993                                 DefRNA.silent = 1;
994                                 RNA_def_property_int_sdna(prop, NULL, identifier);
995                                 DefRNA.silent = 0;
996                                 break;
997                         }
998                         case PROP_FLOAT: {
999                                 DefRNA.silent = 1;
1000                                 RNA_def_property_float_sdna(prop, NULL, identifier);
1001                                 DefRNA.silent = 0;
1002                                 break;
1003                         }
1004                         case PROP_STRING: {
1005                                 DefRNA.silent = 1;
1006                                 RNA_def_property_string_sdna(prop, NULL, identifier);
1007                                 DefRNA.silent = 0;
1008                                 break;
1009                         }
1010                         case PROP_ENUM:
1011                                 DefRNA.silent = 1;
1012                                 RNA_def_property_enum_sdna(prop, NULL, identifier);
1013                                 DefRNA.silent = 0;
1014                                 break;
1015                         case PROP_POINTER:
1016                                 DefRNA.silent = 1;
1017                                 RNA_def_property_pointer_sdna(prop, NULL, identifier);
1018                                 DefRNA.silent = 0;
1019                                 break;
1020                         case PROP_COLLECTION:
1021                                 DefRNA.silent = 1;
1022                                 RNA_def_property_collection_sdna(prop, NULL, identifier, NULL);
1023                                 DefRNA.silent = 0;
1024                                 break;
1025                 }
1026         }
1027         else {
1028                 prop->flag |= PROP_IDPROPERTY|PROP_RUNTIME;
1029 #ifdef RNA_RUNTIME
1030                 if (cont->prophash)
1031                         BLI_ghash_insert(cont->prophash, (void*)prop->identifier, prop);
1032 #endif
1033         }
1034
1035         rna_addtail(&cont->properties, prop);
1036
1037         return prop;
1038 }
1039
1040 void RNA_def_property_flag(PropertyRNA *prop, int flag)
1041 {
1042         prop->flag |= flag;
1043 }
1044
1045 void RNA_def_property_clear_flag(PropertyRNA *prop, int flag)
1046 {
1047         prop->flag &= ~flag;
1048 }
1049
1050 void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype)
1051 {
1052         prop->subtype = subtype;
1053 }
1054
1055 void RNA_def_property_array(PropertyRNA *prop, int length)
1056 {
1057         StructRNA *srna = DefRNA.laststruct;
1058
1059         if (length<0) {
1060                 fprintf(stderr, "%s: \"%s.%s\", array length must be zero of greater.\n", __func__, srna->identifier, prop->identifier);
1061                 DefRNA.error = 1;
1062                 return;
1063         }
1064
1065         if (length>RNA_MAX_ARRAY_LENGTH) {
1066                 fprintf(stderr, "%s: \"%s.%s\", array length must be smaller than %d.\n", __func__, srna->identifier, prop->identifier, RNA_MAX_ARRAY_LENGTH);
1067                 DefRNA.error = 1;
1068                 return;
1069         }
1070
1071         if (prop->arraydimension > 1) {
1072                 fprintf(stderr, "%s: \"%s.%s\", array dimensions has been set to %u but would be overwritten as 1.\n", __func__, srna->identifier, prop->identifier, prop->arraydimension);
1073                 DefRNA.error = 1;
1074                 return;
1075         }
1076
1077         switch (prop->type) {
1078                 case PROP_BOOLEAN:
1079                 case PROP_INT:
1080                 case PROP_FLOAT:
1081                         prop->arraylength[0] = length;
1082                         prop->totarraylength = length;
1083                         prop->arraydimension = 1;
1084                         break;
1085                 default:
1086                         fprintf(stderr, "%s: \"%s.%s\", only boolean/int/float can be array.\n", __func__, srna->identifier, prop->identifier);
1087                         DefRNA.error = 1;
1088                         break;
1089         }
1090 }
1091
1092 void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, const int length[])
1093 {
1094         StructRNA *srna = DefRNA.laststruct;
1095         int i;
1096         
1097         if (dimension < 1 || dimension > RNA_MAX_ARRAY_DIMENSION) {
1098                 fprintf(stderr, "%s: \"%s.%s\", array dimension must be between 1 and %d.\n", __func__, srna->identifier, prop->identifier, RNA_MAX_ARRAY_DIMENSION);
1099                 DefRNA.error = 1;
1100                 return;
1101         }
1102
1103         switch (prop->type) {
1104                 case PROP_BOOLEAN:
1105                 case PROP_INT:
1106                 case PROP_FLOAT:
1107                         break;
1108                 default:
1109                         fprintf(stderr, "%s: \"%s.%s\", only boolean/int/float can be array.\n", __func__, srna->identifier, prop->identifier);
1110                         DefRNA.error = 1;
1111                         break;
1112         }
1113
1114         prop->arraydimension = dimension;
1115         prop->totarraylength = 0;
1116
1117         if (length) {
1118                 memcpy(prop->arraylength, length, sizeof(int)*dimension);
1119
1120                 prop->totarraylength = length[0];
1121                 for (i = 1; i<dimension; i++)
1122                         prop->totarraylength *= length[i];
1123         }
1124         else
1125                 memset(prop->arraylength, 0, sizeof(prop->arraylength));
1126
1127         /* TODO make sure arraylength values are sane  */
1128 }
1129
1130 void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
1131 {
1132         DESCR_CHECK(description, prop->identifier, NULL);
1133
1134         prop->name = name;
1135         prop->description = description;
1136 }
1137
1138 void RNA_def_property_ui_icon(PropertyRNA *prop, int icon, int consecutive)
1139 {
1140         prop->icon = icon;
1141         if (consecutive)
1142                 prop->flag |= PROP_ICONS_CONSECUTIVE;
1143 }
1144
1145 void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
1146 {
1147         StructRNA *srna = DefRNA.laststruct;
1148
1149         switch (prop->type) {
1150                 case PROP_INT: {
1151                         IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
1152                         iprop->softmin = (int)min;
1153                         iprop->softmax = (int)max;
1154                         iprop->step = (int)step;
1155                         break;
1156                 }
1157                 case PROP_FLOAT: {
1158                         FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
1159                         fprop->softmin = (float)min;
1160                         fprop->softmax = (float)max;
1161                         fprop->step = (float)step;
1162                         fprop->precision = (int)precision;
1163                         break;
1164                 }
1165                 default:
1166                         fprintf(stderr, "%s: \"%s.%s\", invalid type for ui range.\n", __func__, srna->identifier, prop->identifier);
1167                         DefRNA.error = 1;
1168                         break;
1169         }
1170 }
1171
1172 void RNA_def_property_range(PropertyRNA *prop, double min, double max)
1173 {
1174         StructRNA *srna = DefRNA.laststruct;
1175
1176         switch (prop->type) {
1177                 case PROP_INT: {
1178                         IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
1179                         iprop->hardmin = (int)min;
1180                         iprop->hardmax = (int)max;
1181                         iprop->softmin = MAX2((int)min, iprop->hardmin);
1182                         iprop->softmax = MIN2((int)max, iprop->hardmax);
1183                         break;
1184                 }
1185                 case PROP_FLOAT: {
1186                         FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
1187                         fprop->hardmin = (float)min;
1188                         fprop->hardmax = (float)max;
1189                         fprop->softmin = MAX2((float)min, fprop->hardmin);
1190                         fprop->softmax = MIN2((float)max, fprop->hardmax);
1191                         break;
1192                 }
1193                 default:
1194                         fprintf(stderr, "%s: \"%s.%s\", invalid type for range.\n", __func__, srna->identifier, prop->identifier);
1195                         DefRNA.error = 1;
1196                         break;
1197         }
1198 }
1199
1200 void RNA_def_property_struct_type(PropertyRNA *prop, const char *type)
1201 {
1202         StructRNA *srna = DefRNA.laststruct;
1203
1204         if (!DefRNA.preprocess) {
1205                 fprintf(stderr, "%s \"%s.%s\": only during preprocessing.\n", __func__, srna->identifier, prop->identifier);
1206                 return;
1207         }
1208
1209         switch (prop->type) {
1210                 case PROP_POINTER: {
1211                         PointerPropertyRNA *pprop = (PointerPropertyRNA*)prop;
1212                         pprop->type = (StructRNA*)type;
1213                         break;
1214                 }
1215                 case PROP_COLLECTION: {
1216                         CollectionPropertyRNA *cprop = (CollectionPropertyRNA*)prop;
1217                         cprop->item_type = (StructRNA*)type;
1218                         break;
1219                 }
1220                 default:
1221                         fprintf(stderr, "%s: \"%s.%s\", invalid type for struct type.\n", __func__, srna->identifier, prop->identifier);
1222                         DefRNA.error = 1;
1223                         break;
1224         }
1225 }
1226
1227 void RNA_def_property_struct_runtime(PropertyRNA *prop, StructRNA *type)
1228 {
1229         StructRNA *srna = DefRNA.laststruct;
1230
1231         if (DefRNA.preprocess) {
1232                 fprintf(stderr, "%s: only at runtime.\n", __func__);
1233                 return;
1234         }
1235
1236         switch (prop->type) {
1237                 case PROP_POINTER: {
1238                         PointerPropertyRNA *pprop = (PointerPropertyRNA*)prop;
1239                         pprop->type = type;
1240
1241                         if (type && (type->flag & STRUCT_ID_REFCOUNT))
1242                                 prop->flag |= PROP_ID_REFCOUNT;
1243
1244                         break;
1245                 }
1246                 case PROP_COLLECTION: {
1247                         CollectionPropertyRNA *cprop = (CollectionPropertyRNA*)prop;
1248                         cprop->item_type = type;
1249                         break;
1250                 }
1251                 default:
1252                         fprintf(stderr, "%s: \"%s.%s\", invalid type for struct type.\n", __func__, srna->identifier, prop->identifier);
1253                         DefRNA.error = 1;
1254                         break;
1255         }
1256 }
1257
1258 void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item)
1259 {
1260         StructRNA *srna = DefRNA.laststruct;
1261         int i, defaultfound = 0;
1262
1263         switch (prop->type) {
1264                 case PROP_ENUM: {
1265                         EnumPropertyRNA *eprop = (EnumPropertyRNA*)prop;
1266                         eprop->item = (EnumPropertyItem*)item;
1267                         eprop->totitem = 0;
1268                         for (i = 0; item[i].identifier; i++) {
1269                                 eprop->totitem++;
1270
1271                                 if (item[i].identifier[0] && item[i].value == eprop->defaultvalue)
1272                                         defaultfound = 1;
1273                         }
1274
1275                         if (!defaultfound) {
1276                                 for (i = 0; item[i].identifier; i++) {
1277                                         if (item[i].identifier[0]) {
1278                                                 eprop->defaultvalue = item[i].value;
1279                                                 break;
1280                                         }
1281                                 }
1282                         }
1283
1284                         break;
1285                 }
1286                 default:
1287                         fprintf(stderr, "%s: \"%s.%s\", invalid type for struct type.\n", __func__, srna->identifier, prop->identifier);
1288                         DefRNA.error = 1;
1289                         break;
1290         }
1291 }
1292
1293 void RNA_def_property_string_maxlength(PropertyRNA *prop, int maxlength)
1294 {
1295         StructRNA *srna = DefRNA.laststruct;
1296
1297         switch (prop->type) {
1298                 case PROP_STRING: {
1299                         StringPropertyRNA *sprop = (StringPropertyRNA*)prop;
1300                         sprop->maxlength = maxlength;
1301                         break;
1302                 }
1303                 default:
1304                         fprintf(stderr, "%s: \"%s.%s\", type is not string.\n", __func__, srna->identifier, prop->identifier);
1305                         DefRNA.error = 1;
1306                         break;
1307         }
1308 }
1309
1310 void RNA_def_property_boolean_default(PropertyRNA *prop, int value)
1311 {
1312         StructRNA *srna = DefRNA.laststruct;
1313
1314         switch (prop->type) {
1315                 case PROP_BOOLEAN: {
1316                         BoolPropertyRNA *bprop = (BoolPropertyRNA*)prop;
1317                         bprop->defaultvalue = value;
1318                         break;
1319                 }
1320                 default:
1321                         fprintf(stderr, "%s: \"%s.%s\", type is not boolean.\n", __func__, srna->identifier, prop->identifier);
1322                         DefRNA.error = 1;
1323                         break;
1324         }
1325 }
1326
1327 void RNA_def_property_boolean_array_default(PropertyRNA *prop, const int *array)
1328 {
1329         StructRNA *srna = DefRNA.laststruct;
1330
1331         switch (prop->type) {
1332                 case PROP_BOOLEAN: {
1333                         BoolPropertyRNA *bprop = (BoolPropertyRNA*)prop;
1334                         bprop->defaultarray = array;
1335                         break;
1336                 }
1337                 default:
1338                         fprintf(stderr, "%s: \"%s.%s\", type is not boolean.\n", __func__, srna->identifier, prop->identifier);
1339                         DefRNA.error = 1;
1340                         break;
1341         }
1342 }
1343
1344 void RNA_def_property_int_default(PropertyRNA *prop, int value)
1345 {
1346         StructRNA *srna = DefRNA.laststruct;
1347
1348         switch (prop->type) {
1349                 case PROP_INT: {
1350                         IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
1351                         iprop->defaultvalue = value;
1352                         break;
1353                 }
1354                 default:
1355                         fprintf(stderr, "%s: \"%s.%s\", type is not int.\n", __func__, srna->identifier, prop->identifier);
1356                         DefRNA.error = 1;
1357                         break;
1358         }
1359 }
1360
1361 void RNA_def_property_int_array_default(PropertyRNA *prop, const int *array)
1362 {
1363         StructRNA *srna = DefRNA.laststruct;
1364
1365         switch (prop->type) {
1366                 case PROP_INT: {
1367                         IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
1368                         iprop->defaultarray = array;
1369                         break;
1370                 }
1371                 default:
1372                         fprintf(stderr, "%s: \"%s.%s\", type is not int.\n", __func__, srna->identifier, prop->identifier);
1373                         DefRNA.error = 1;
1374                         break;
1375         }
1376 }
1377
1378 void RNA_def_property_float_default(PropertyRNA *prop, float value)
1379 {
1380         StructRNA *srna = DefRNA.laststruct;
1381
1382         switch (prop->type) {
1383                 case PROP_FLOAT: {
1384                         FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
1385                         fprop->defaultvalue = value;
1386                         break;
1387                 }
1388                 default:
1389                         fprintf(stderr, "%s: \"%s.%s\", type is not float.\n", __func__, srna->identifier, prop->identifier);
1390                         DefRNA.error = 1;
1391                         break;
1392         }
1393 }
1394 /* array must remain valid after this function finishes */
1395 void RNA_def_property_float_array_default(PropertyRNA *prop, const float *array)
1396 {
1397         StructRNA *srna = DefRNA.laststruct;
1398
1399         switch (prop->type) {
1400                 case PROP_FLOAT: {
1401                         FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
1402                         fprop->defaultarray = array; /* WARNING, this array must not come from the stack and lost */
1403                         break;
1404                 }
1405                 default:
1406                         fprintf(stderr, "%s: \"%s.%s\", type is not float.\n", __func__, srna->identifier, prop->identifier);
1407                         DefRNA.error = 1;
1408                         break;
1409         }
1410 }
1411
1412 void RNA_def_property_string_default(PropertyRNA *prop, const char *value)
1413 {
1414         StructRNA *srna = DefRNA.laststruct;
1415
1416         switch (prop->type) {
1417                 case PROP_STRING: {
1418                         StringPropertyRNA *sprop = (StringPropertyRNA*)prop;
1419                         sprop->defaultvalue = value;
1420                         break;
1421                 }
1422                 default:
1423                         fprintf(stderr, "%s: \"%s.%s\", type is not string.\n", __func__, srna->identifier, prop->identifier);
1424                         DefRNA.error = 1;
1425                         break;
1426         }
1427 }
1428
1429 void RNA_def_property_enum_default(PropertyRNA *prop, int value)
1430 {
1431         StructRNA *srna = DefRNA.laststruct;
1432         int i, defaultfound = 0;
1433
1434         switch (prop->type) {
1435                 case PROP_ENUM: {
1436                         EnumPropertyRNA *eprop = (EnumPropertyRNA*)prop;
1437                         eprop->defaultvalue = value;
1438
1439                         if (prop->flag & PROP_ENUM_FLAG) {
1440                                 /* check all bits are accounted for */
1441                                 int totflag = 0;
1442                                 for (i = 0; i<eprop->totitem; i++) {
1443                                         if (eprop->item[i].identifier[0]) {
1444                                                 totflag |= eprop->item[i].value;
1445                                         }
1446                                 }
1447
1448                                 if (eprop->defaultvalue & ~totflag) {
1449                                         fprintf(stderr, "%s: \"%s.%s\", default includes unused bits (%d).\n", __func__, srna->identifier, prop->identifier, eprop->defaultvalue & ~totflag);
1450                                         DefRNA.error = 1;
1451                                 }
1452                         }
1453                         else {
1454                                 for (i = 0; i<eprop->totitem; i++) {
1455                                         if (eprop->item[i].identifier[0] && eprop->item[i].value == eprop->defaultvalue)
1456                                                 defaultfound = 1;
1457                                 }
1458
1459                                 if (!defaultfound && eprop->totitem) {
1460                                         if (value == 0) {
1461                                                 eprop->defaultvalue = eprop->item[0].value;
1462                                         }
1463                                         else {
1464                                                 fprintf(stderr, "%s: \"%s.%s\", default is not in items.\n", __func__, srna->identifier, prop->identifier);
1465                                                 DefRNA.error = 1;
1466                                         }
1467                                 }
1468                         }
1469
1470                         break;
1471                 }
1472                 default:
1473                         fprintf(stderr, "%s: \"%s.%s\", type is not enum.\n", __func__, srna->identifier, prop->identifier);
1474                         DefRNA.error = 1;
1475                         break;
1476         }
1477 }
1478
1479 /* SDNA */
1480
1481 static PropertyDefRNA *rna_def_property_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1482 {
1483         DNAStructMember smember;
1484         StructDefRNA *ds;
1485         PropertyDefRNA *dp;
1486
1487         dp = rna_find_struct_property_def(DefRNA.laststruct, prop);
1488         if (dp == NULL) return NULL;
1489
1490         ds = rna_find_struct_def((StructRNA*)dp->cont);
1491
1492         if (!structname)
1493                 structname = ds->dnaname;
1494         if (!propname)
1495                 propname = prop->identifier;
1496
1497         if (!rna_find_sdna_member(DefRNA.sdna, structname, propname, &smember)) {
1498                 if (DefRNA.silent) {
1499                         return NULL;
1500                 }
1501                 else if (!DefRNA.verify) {
1502                         /* some basic values to survive even with sdna info */
1503                         dp->dnastructname = structname;
1504                         dp->dnaname = propname;
1505                         if (prop->type == PROP_BOOLEAN)
1506                                 dp->dnaarraylength = 1;
1507                         if (prop->type == PROP_POINTER)
1508                                 dp->dnapointerlevel = 1;
1509                         return dp;
1510                 }
1511                 else {
1512                         fprintf(stderr, "%s: \"%s.%s\" (identifier \"%s\") not found.\n",
1513                                 __func__, structname, propname, prop->identifier);
1514                         DefRNA.error = 1;
1515                         return NULL;
1516                 }
1517         }
1518
1519         if (smember.arraylength > 1) {
1520                 prop->arraylength[0] = smember.arraylength;
1521                 prop->totarraylength = smember.arraylength;
1522                 prop->arraydimension = 1;
1523         }
1524         else {
1525                 prop->arraydimension = 0;
1526                 prop->totarraylength = 0;
1527         }
1528         
1529         dp->dnastructname = structname;
1530         dp->dnastructfromname = ds->dnafromname;
1531         dp->dnastructfromprop = ds->dnafromprop;
1532         dp->dnaname = propname;
1533         dp->dnatype = smember.type;
1534         dp->dnaarraylength = smember.arraylength;
1535         dp->dnapointerlevel = smember.pointerlevel;
1536
1537         return dp;
1538 }
1539
1540 void RNA_def_property_boolean_sdna(PropertyRNA *prop, const char *structname, const char *propname, int bit)
1541 {
1542         PropertyDefRNA *dp;
1543         StructRNA *srna = DefRNA.laststruct;
1544         
1545         if (!DefRNA.preprocess) {
1546                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1547                 return;
1548         }
1549
1550         if (prop->type != PROP_BOOLEAN) {
1551                 fprintf(stderr, "%s: \"%s.%s\", type is not boolean.\n", __func__, srna->identifier, prop->identifier);
1552                 DefRNA.error = 1;
1553                 return;
1554         }
1555
1556         if ((dp = rna_def_property_sdna(prop, structname, propname))) {
1557
1558                 if (DefRNA.silent == 0) {
1559                         /* error check to ensure floats are not wrapped as ints/bools */
1560                         if (dp->dnatype && *dp->dnatype && IS_DNATYPE_INT_COMPAT(dp->dnatype) == 0) {
1561                                 fprintf(stderr, "%s: %s.%s is a '%s' but wrapped as type '%s'.\n", __func__, srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type));
1562                                 DefRNA.error = 1;
1563                                 return;
1564                         }
1565                 }
1566
1567                 dp->booleanbit = bit;
1568         }
1569 }
1570
1571 void RNA_def_property_boolean_negative_sdna(PropertyRNA *prop, const char *structname, const char *propname, int booleanbit)
1572 {
1573         PropertyDefRNA *dp;
1574
1575         RNA_def_property_boolean_sdna(prop, structname, propname, booleanbit);
1576
1577         dp = rna_find_struct_property_def(DefRNA.laststruct, prop);
1578
1579         if (dp)
1580                 dp->booleannegative = 1;
1581 }
1582
1583 void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1584 {
1585         PropertyDefRNA *dp;
1586         IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
1587         StructRNA *srna = DefRNA.laststruct;
1588         
1589         if (!DefRNA.preprocess) {
1590                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1591                 return;
1592         }
1593
1594         if (prop->type != PROP_INT) {
1595                 fprintf(stderr, "%s: \"%s.%s\", type is not int.\n", __func__, srna->identifier, prop->identifier);
1596                 DefRNA.error = 1;
1597                 return;
1598         }
1599
1600         if ((dp = rna_def_property_sdna(prop, structname, propname))) {
1601
1602                 /* error check to ensure floats are not wrapped as ints/bools */
1603                 if (DefRNA.silent == 0) {
1604                         if (dp->dnatype && *dp->dnatype && IS_DNATYPE_INT_COMPAT(dp->dnatype) == 0) {
1605                                 fprintf(stderr, "%s: %s.%s is a '%s' but wrapped as type '%s'.\n", __func__, srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type));
1606                                 DefRNA.error = 1;
1607                                 return;
1608                         }
1609                 }
1610
1611                 /* SDNA doesn't pass us unsigned unfortunately .. */
1612                 if (dp->dnatype && strcmp(dp->dnatype, "char") == 0) {
1613                         iprop->hardmin = iprop->softmin = CHAR_MIN;
1614                         iprop->hardmax = iprop->softmax = CHAR_MAX;
1615                 }
1616                 else if (dp->dnatype && strcmp(dp->dnatype, "short") == 0) {
1617                         iprop->hardmin = iprop->softmin = SHRT_MIN;
1618                         iprop->hardmax = iprop->softmax = SHRT_MAX;
1619                 }
1620                 else if (dp->dnatype && strcmp(dp->dnatype, "int") == 0) {
1621                         iprop->hardmin = INT_MIN;
1622                         iprop->hardmax = INT_MAX;
1623
1624                         iprop->softmin = -10000; /* rather arbitrary .. */
1625                         iprop->softmax = 10000;
1626                 }
1627
1628                 if (prop->subtype == PROP_UNSIGNED || prop->subtype == PROP_PERCENTAGE || prop->subtype == PROP_FACTOR)
1629                         iprop->hardmin = iprop->softmin = 0;
1630         }
1631 }
1632
1633 void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1634 {
1635         PropertyDefRNA *dp;
1636         FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
1637         StructRNA *srna = DefRNA.laststruct;
1638
1639         if (!DefRNA.preprocess) {
1640                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1641                 return;
1642         }
1643
1644         if (prop->type != PROP_FLOAT) {
1645                 fprintf(stderr, "%s: \"%s.%s\", type is not float.\n", __func__, srna->identifier, prop->identifier);
1646                 DefRNA.error = 1;
1647                 return;
1648         }
1649
1650         if ((dp = rna_def_property_sdna(prop, structname, propname))) {
1651                 /* silent is for internal use */
1652                 if (DefRNA.silent == 0) {
1653                         if (dp->dnatype && *dp->dnatype && IS_DNATYPE_FLOAT_COMPAT(dp->dnatype) == 0) {
1654                                 if (prop->subtype != PROP_COLOR_GAMMA) { /* colors are an exception. these get translated */
1655                                         fprintf(stderr, "%s: %s.%s is a '%s' but wrapped as type '%s'.\n", __func__, srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type));
1656                                         DefRNA.error = 1;
1657                                         return;
1658                                 }
1659                         }
1660                 }
1661
1662                 if (dp->dnatype && strcmp(dp->dnatype, "char") == 0) {
1663                         fprop->hardmin = fprop->softmin = 0.0f;
1664                         fprop->hardmax = fprop->softmax = 1.0f;
1665                 }
1666         }
1667
1668         rna_def_property_sdna(prop, structname, propname);
1669 }
1670
1671 void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1672 {
1673         /* PropertyDefRNA *dp; */
1674         StructRNA *srna = DefRNA.laststruct;
1675         
1676         if (!DefRNA.preprocess) {
1677                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1678                 return;
1679         }
1680
1681         if (prop->type != PROP_ENUM) {
1682                 fprintf(stderr, "%s: \"%s.%s\", type is not enum.\n", __func__, srna->identifier, prop->identifier);
1683                 DefRNA.error = 1;
1684                 return;
1685         }
1686
1687         if (( /* dp= */ rna_def_property_sdna(prop, structname, propname))) {
1688                 if (prop->arraydimension) {
1689                         prop->arraydimension = 0;
1690                         prop->totarraylength = 0;
1691
1692                         if (!DefRNA.silent) {
1693                                 fprintf(stderr, "%s: \"%s.%s\", array not supported for enum type.\n", __func__, structname, propname);
1694                                 DefRNA.error = 1;
1695                         }
1696                 }
1697         }
1698 }
1699
1700 void RNA_def_property_enum_bitflag_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1701 {
1702         PropertyDefRNA *dp;
1703
1704         RNA_def_property_enum_sdna(prop, structname, propname);
1705
1706         dp = rna_find_struct_property_def(DefRNA.laststruct, prop);
1707
1708         if (dp)
1709                 dp->enumbitflags = 1;
1710 }
1711
1712 void RNA_def_property_string_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1713 {
1714         /* PropertyDefRNA *dp; */
1715         StringPropertyRNA *sprop = (StringPropertyRNA*)prop;
1716         StructRNA *srna = DefRNA.laststruct;
1717
1718         if (!DefRNA.preprocess) {
1719                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1720                 return;
1721         }
1722
1723         if (prop->type != PROP_STRING) {
1724                 fprintf(stderr, "%s: \"%s.%s\", type is not string.\n", __func__, srna->identifier, prop->identifier);
1725                 DefRNA.error = 1;
1726                 return;
1727         }
1728
1729         if ((/* dp= */ rna_def_property_sdna(prop, structname, propname))) {
1730                 if (prop->arraydimension) {
1731                         sprop->maxlength = prop->totarraylength;
1732                         prop->arraydimension = 0;
1733                         prop->totarraylength = 0;
1734                 }
1735         }
1736 }
1737
1738 void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1739 {
1740         /* PropertyDefRNA *dp; */
1741         StructRNA *srna = DefRNA.laststruct;
1742         
1743         if (!DefRNA.preprocess) {
1744                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1745                 return;
1746         }
1747
1748         if (prop->type != PROP_POINTER) {
1749                 fprintf(stderr, "%s: \"%s.%s\", type is not pointer.\n", __func__, srna->identifier, prop->identifier);
1750                 DefRNA.error = 1;
1751                 return;
1752         }
1753
1754         if ((/* dp= */ rna_def_property_sdna(prop, structname, propname))) {
1755                 if (prop->arraydimension) {
1756                         prop->arraydimension = 0;
1757                         prop->totarraylength = 0;
1758
1759                         if (!DefRNA.silent) {
1760                                 fprintf(stderr, "%s: \"%s.%s\", array not supported for pointer type.\n", __func__, structname, propname);
1761                                 DefRNA.error = 1;
1762                         }
1763                 }
1764         }
1765 }
1766
1767 void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, const char *propname, const char *lengthpropname)
1768 {
1769         PropertyDefRNA *dp;
1770         CollectionPropertyRNA *cprop = (CollectionPropertyRNA*)prop;
1771         StructRNA *srna = DefRNA.laststruct;
1772
1773         if (!DefRNA.preprocess) {
1774                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1775                 return;
1776         }
1777
1778         if (prop->type != PROP_COLLECTION) {
1779                 fprintf(stderr, "%s: \"%s.%s\", type is not collection.\n", __func__, srna->identifier, prop->identifier);
1780                 DefRNA.error = 1;
1781                 return;
1782         }
1783
1784         if ((dp = rna_def_property_sdna(prop, structname, propname))) {
1785                 if (prop->arraydimension && !lengthpropname) {
1786                         prop->arraydimension = 0;
1787                         prop->totarraylength = 0;
1788
1789                         if (!DefRNA.silent) {
1790                                 fprintf(stderr, "%s: \"%s.%s\", array of collections not supported.\n", __func__, structname, propname);
1791                                 DefRNA.error = 1;
1792                         }
1793                 }
1794
1795                 if (dp->dnatype && strcmp(dp->dnatype, "ListBase") == 0) {
1796                         cprop->next = (PropCollectionNextFunc)"rna_iterator_listbase_next";
1797                         cprop->get = (PropCollectionGetFunc)"rna_iterator_listbase_get";
1798                         cprop->end = (PropCollectionEndFunc)"rna_iterator_listbase_end";
1799                 }
1800         }
1801
1802         if (dp && lengthpropname) {
1803                 DNAStructMember smember;
1804                 StructDefRNA *ds = rna_find_struct_def((StructRNA*)dp->cont);
1805
1806                 if (!structname)
1807                         structname = ds->dnaname;
1808
1809                 if (lengthpropname[0] == 0 || rna_find_sdna_member(DefRNA.sdna, structname, lengthpropname, &smember)) {
1810                         if (lengthpropname[0] == 0) {
1811                                 dp->dnalengthfixed = prop->totarraylength;
1812                                 prop->arraydimension = 0;
1813                                 prop->totarraylength = 0;
1814                         }
1815                         else {
1816                                 dp->dnalengthstructname = structname;
1817                                 dp->dnalengthname = lengthpropname;
1818                                 prop->totarraylength = 0;
1819                         }
1820
1821                         cprop->next = (PropCollectionNextFunc)"rna_iterator_array_next";
1822                         cprop->end = (PropCollectionEndFunc)"rna_iterator_array_end";
1823
1824                         if (dp->dnapointerlevel >= 2) 
1825                                 cprop->get = (PropCollectionGetFunc)"rna_iterator_array_dereference_get";
1826                         else
1827                                 cprop->get = (PropCollectionGetFunc)"rna_iterator_array_get";
1828                 }
1829                 else {
1830                         if (!DefRNA.silent) {
1831                                 fprintf(stderr, "%s: \"%s.%s\" not found.\n", __func__, structname, lengthpropname);
1832                                 DefRNA.error = 1;
1833                         }
1834                 }
1835         }
1836 }
1837
1838 void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
1839 {
1840         prop->translation_context = context;
1841 }
1842
1843 /* Functions */
1844
1845 void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable)
1846 {
1847         if (!DefRNA.preprocess) {
1848                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1849                 return;
1850         }
1851
1852         if (editable) prop->editable = (EditableFunc)editable;
1853 }
1854
1855 void RNA_def_property_editable_array_func(PropertyRNA *prop, const char *editable)
1856 {
1857         if (!DefRNA.preprocess) {
1858                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1859                 return;
1860         }
1861
1862         if (editable) prop->itemeditable = (ItemEditableFunc)editable;
1863 }
1864
1865 void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *func)
1866 {
1867         if (!DefRNA.preprocess) {
1868                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1869                 return;
1870         }
1871
1872         prop->noteflag = noteflag;
1873         prop->update = (UpdateFunc)func;
1874 }
1875
1876 void RNA_def_property_update_runtime(PropertyRNA *prop, void *func)
1877 {
1878         prop->update = func;
1879 }
1880
1881 void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength)
1882 {
1883         if (!DefRNA.preprocess) {
1884                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1885                 return;
1886         }
1887
1888         if (!(prop->flag & PROP_DYNAMIC)) {
1889                 fprintf(stderr, "%s: property is a not dynamic array.\n", __func__);
1890                 DefRNA.error = 1;
1891                 return;
1892         }
1893
1894         if (getlength) prop->getlength = (PropArrayLengthGetFunc)getlength;
1895 }
1896
1897 void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set)
1898 {
1899         StructRNA *srna = DefRNA.laststruct;
1900
1901         if (!DefRNA.preprocess) {
1902                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1903                 return;
1904         }
1905
1906         switch (prop->type) {
1907                 case PROP_BOOLEAN: {
1908                         BoolPropertyRNA *bprop = (BoolPropertyRNA*)prop;
1909
1910                         if (prop->arraydimension) {
1911                                 if (get) bprop->getarray = (PropBooleanArrayGetFunc)get;
1912                                 if (set) bprop->setarray = (PropBooleanArraySetFunc)set;
1913                         }
1914                         else {
1915                                 if (get) bprop->get = (PropBooleanGetFunc)get;
1916                                 if (set) bprop->set = (PropBooleanSetFunc)set;
1917                         }
1918                         break;
1919                 }
1920                 default:
1921                         fprintf(stderr, "%s: \"%s.%s\", type is not boolean.\n", __func__, srna->identifier, prop->identifier);
1922                         DefRNA.error = 1;
1923                         break;
1924         }
1925 }
1926
1927 void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
1928 {
1929         StructRNA *srna = DefRNA.laststruct;
1930
1931         if (!DefRNA.preprocess) {
1932                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1933                 return;
1934         }
1935
1936         switch (prop->type) {
1937                 case PROP_INT: {
1938                         IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
1939
1940                         if (prop->arraydimension) {
1941                                 if (get) iprop->getarray = (PropIntArrayGetFunc)get;
1942                                 if (set) iprop->setarray = (PropIntArraySetFunc)set;
1943                         }
1944                         else {
1945                                 if (get) iprop->get = (PropIntGetFunc)get;
1946                                 if (set) iprop->set = (PropIntSetFunc)set;
1947                         }
1948                         if (range) iprop->range = (PropIntRangeFunc)range;
1949                         break;
1950                 }
1951                 default:
1952                         fprintf(stderr, "%s: \"%s.%s\", type is not int.\n", __func__, srna->identifier, prop->identifier);
1953                         DefRNA.error = 1;
1954                         break;
1955         }
1956 }
1957
1958 void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
1959 {
1960         StructRNA *srna = DefRNA.laststruct;
1961
1962         if (!DefRNA.preprocess) {
1963                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1964                 return;
1965         }
1966
1967         switch (prop->type) {
1968                 case PROP_FLOAT: {
1969                         FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
1970
1971                         if (prop->arraydimension) {
1972                                 if (get) fprop->getarray = (PropFloatArrayGetFunc)get;
1973                                 if (set) fprop->setarray = (PropFloatArraySetFunc)set;
1974                         }
1975                         else {
1976                                 if (get) fprop->get = (PropFloatGetFunc)get;
1977                                 if (set) fprop->set = (PropFloatSetFunc)set;
1978                         }
1979                         if (range) fprop->range = (PropFloatRangeFunc)range;
1980                         break;
1981                 }
1982                 default:
1983                         fprintf(stderr, "%s: \"%s.%s\", type is not float.\n", __func__, srna->identifier, prop->identifier);
1984                         DefRNA.error = 1;
1985                         break;
1986         }
1987 }
1988
1989 void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set, const char *item)
1990 {
1991         StructRNA *srna = DefRNA.laststruct;
1992
1993         if (!DefRNA.preprocess) {
1994                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
1995                 return;
1996         }
1997
1998         switch (prop->type) {
1999                 case PROP_ENUM: {
2000                         EnumPropertyRNA *eprop = (EnumPropertyRNA*)prop;
2001
2002                         if (get) eprop->get = (PropEnumGetFunc)get;
2003                         if (set) eprop->set = (PropEnumSetFunc)set;
2004                         if (item) eprop->itemf = (PropEnumItemFunc)item;
2005                         break;
2006                 }
2007                 default:
2008                         fprintf(stderr, "%s: \"%s.%s\", type is not enum.\n", __func__, srna->identifier, prop->identifier);
2009                         DefRNA.error = 1;
2010                         break;
2011         }
2012 }
2013
2014 void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set)
2015 {
2016         StructRNA *srna = DefRNA.laststruct;
2017
2018         if (!DefRNA.preprocess) {
2019                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
2020                 return;
2021         }
2022
2023         switch (prop->type) {
2024                 case PROP_STRING: {
2025                         StringPropertyRNA *sprop = (StringPropertyRNA*)prop;
2026
2027                         if (get) sprop->get = (PropStringGetFunc)get;
2028                         if (length) sprop->length = (PropStringLengthFunc)length;
2029                         if (set) sprop->set = (PropStringSetFunc)set;
2030                         break;
2031                 }
2032                 default:
2033                         fprintf(stderr, "%s: \"%s.%s\", type is not string.\n", __func__, srna->identifier, prop->identifier);
2034                         DefRNA.error = 1;
2035                         break;
2036         }
2037 }
2038
2039 void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set, const char *typef, const char *poll)
2040 {
2041         StructRNA *srna = DefRNA.laststruct;
2042
2043         if (!DefRNA.preprocess) {
2044                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
2045                 return;
2046         }
2047
2048         switch (prop->type) {
2049                 case PROP_POINTER: {
2050                         PointerPropertyRNA *pprop = (PointerPropertyRNA*)prop;
2051
2052                         if (get) pprop->get = (PropPointerGetFunc)get;
2053                         if (set) pprop->set = (PropPointerSetFunc)set;
2054                         if (typef) pprop->typef = (PropPointerTypeFunc)typef;
2055                         if (poll) pprop->poll = (PropPointerPollFunc)poll;
2056                         break;
2057                 }
2058                 default:
2059                         fprintf(stderr, "%s: \"%s.%s\", type is not pointer.\n", __func__, srna->identifier, prop->identifier);
2060                         DefRNA.error = 1;
2061                         break;
2062         }
2063 }
2064
2065 void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end, const char *get, const char *length, const char *lookupint, const char *lookupstring, const char *assignint)
2066 {
2067         StructRNA *srna = DefRNA.laststruct;
2068
2069         if (!DefRNA.preprocess) {
2070                 fprintf(stderr, "%s: only during preprocessing.\n", __func__);
2071                 return;
2072         }
2073
2074         switch (prop->type) {
2075                 case PROP_COLLECTION: {
2076                         CollectionPropertyRNA *cprop = (CollectionPropertyRNA*)prop;
2077
2078                         if (begin) cprop->begin = (PropCollectionBeginFunc)begin;
2079                         if (next) cprop->next = (PropCollectionNextFunc)next;
2080                         if (end) cprop->end = (PropCollectionEndFunc)end;
2081                         if (get) cprop->get = (PropCollectionGetFunc)get;
2082                         if (length) cprop->length = (PropCollectionLengthFunc)length;
2083                         if (lookupint) cprop->lookupint = (PropCollectionLookupIntFunc)lookupint;
2084                         if (lookupstring) cprop->lookupstring = (PropCollectionLookupStringFunc)lookupstring;
2085                         if (assignint) cprop->assignint = (PropCollectionAssignIntFunc)assignint;
2086                         break;
2087                 }
2088                 default:
2089                         fprintf(stderr, "%s: \"%s.%s\", type is not collection.\n", __func__, srna->identifier, prop->identifier);
2090                         DefRNA.error = 1;
2091                         break;
2092         }
2093 }
2094
2095 void RNA_def_property_srna(PropertyRNA *prop, const char *type)
2096 {
2097         prop->srna = (StructRNA*)type;
2098 }
2099
2100 void RNA_def_py_data(PropertyRNA *prop, void *py_data)
2101 {
2102         prop->py_data = py_data;
2103 }
2104
2105 /* Compact definitions */
2106
2107 PropertyRNA *RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, int default_value, const char *ui_name, const char *ui_description)
2108 {
2109         ContainerRNA *cont = cont_;
2110         PropertyRNA *prop;
2111         
2112         prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_NONE);
2113         RNA_def_property_boolean_default(prop, default_value);
2114         RNA_def_property_ui_text(prop, ui_name, ui_description);
2115
2116         return prop;
2117 }
2118
2119 PropertyRNA *RNA_def_boolean_array(StructOrFunctionRNA *cont_, const char *identifier, int len, int *default_value, 
2120         const char *ui_name, const char *ui_description)
2121 {
2122         ContainerRNA *cont = cont_;
2123         PropertyRNA *prop;
2124         
2125         prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_NONE);
2126         if (len != 0) RNA_def_property_array(prop, len);
2127         if (default_value) RNA_def_property_boolean_array_default(prop, default_value);
2128         RNA_def_property_ui_text(prop, ui_name, ui_description);
2129
2130         return prop;
2131 }
2132
2133 PropertyRNA *RNA_def_boolean_layer(StructOrFunctionRNA *cont_, const char *identifier, int len, int *default_value, 
2134         const char *ui_name, const char *ui_description)
2135 {
2136         ContainerRNA *cont = cont_;
2137         PropertyRNA *prop;
2138         
2139         prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_LAYER);
2140         if (len != 0) RNA_def_property_array(prop, len);
2141         if (default_value) RNA_def_property_boolean_array_default(prop, default_value);
2142         RNA_def_property_ui_text(prop, ui_name, ui_description);
2143
2144         return prop;
2145 }
2146
2147 PropertyRNA *RNA_def_boolean_layer_member(StructOrFunctionRNA *cont_, const char *identifier, int len, int *default_value, 
2148         const char *ui_name, const char *ui_description)
2149 {
2150         ContainerRNA *cont = cont_;
2151         PropertyRNA *prop;
2152         
2153         prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_LAYER_MEMBER);
2154         if (len != 0) RNA_def_property_array(prop, len);
2155         if (default_value) RNA_def_property_boolean_array_default(prop, default_value);
2156         RNA_def_property_ui_text(prop, ui_name, ui_description);
2157
2158         return prop;
2159 }
2160
2161 PropertyRNA *RNA_def_boolean_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, int *default_value, 
2162         const char *ui_name, const char *ui_description)
2163 {
2164         ContainerRNA *cont = cont_;
2165         PropertyRNA *prop;
2166         
2167         prop = RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_XYZ); /* XXX */
2168         if (len != 0) RNA_def_property_array(prop, len);
2169         if (default_value) RNA_def_property_boolean_array_default(prop, default_value);
2170         RNA_def_property_ui_text(prop, ui_name, ui_description);
2171
2172         return prop;
2173 }
2174
2175 PropertyRNA *RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, 
2176         const char *ui_name, const char *ui_description, int softmin, int softmax)
2177 {
2178         ContainerRNA *cont = cont_;
2179         PropertyRNA *prop;
2180         
2181         prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE);
2182         RNA_def_property_int_default(prop, default_value);
2183         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2184         RNA_def_property_ui_text(prop, ui_name, ui_description);
2185         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2186
2187         return prop;
2188 }
2189
2190 PropertyRNA *RNA_def_int_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, const int *default_value, 
2191         int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
2192 {
2193         ContainerRNA *cont = cont_;
2194         PropertyRNA *prop;
2195         
2196         prop = RNA_def_property(cont, identifier, PROP_INT, PROP_XYZ); /* XXX */
2197         if (len != 0) RNA_def_property_array(prop, len);
2198         if (default_value) RNA_def_property_int_array_default(prop, default_value);
2199         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2200         RNA_def_property_ui_text(prop, ui_name, ui_description);
2201         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2202
2203         return prop;
2204 }
2205
2206 PropertyRNA *RNA_def_int_array(StructOrFunctionRNA *cont_, const char *identifier, int len, const int *default_value, 
2207         int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
2208 {
2209         ContainerRNA *cont = cont_;
2210         PropertyRNA *prop;
2211         
2212         prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE);
2213         if (len != 0) RNA_def_property_array(prop, len);
2214         if (default_value) RNA_def_property_int_array_default(prop, default_value);
2215         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2216         RNA_def_property_ui_text(prop, ui_name, ui_description);
2217         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2218
2219         return prop;
2220 }
2221
2222 PropertyRNA *RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, 
2223         const char *ui_name, const char *ui_description)
2224 {
2225         ContainerRNA *cont = cont_;
2226         PropertyRNA *prop;
2227         
2228         prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_NONE);
2229         if (maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen);
2230         if (default_value) RNA_def_property_string_default(prop, default_value);
2231         RNA_def_property_ui_text(prop, ui_name, ui_description);
2232
2233         return prop;
2234 }
2235
2236 PropertyRNA *RNA_def_string_file_path(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, 
2237         const char *ui_name, const char *ui_description)
2238 {
2239         ContainerRNA *cont = cont_;
2240         PropertyRNA *prop;
2241         
2242         prop = RNA_def_property(cont, identifier, PROP_STRING, PROP_FILEPATH);
2243         if (maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen);
2244         if (default_value) RNA_def_property_string_default(prop, default_value);
2245         RNA_def_property_ui_text(prop, ui_name, ui_description);
2246
2247         return prop;
2248 }
2249
2250 PropertyRNA *RNA_def_string_dir_path(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_DIRPATH);
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_name(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, 
2265         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_FILENAME);
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_translate(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen,
2279         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_TRANSLATE);
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_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, 
2293         const char *ui_name, const char *ui_description)
2294 {
2295         ContainerRNA *cont = cont_;
2296         PropertyRNA *prop;
2297
2298         if (!items) {
2299                 printf("%s: items not allowed to be NULL.\n", __func__);
2300                 return NULL;
2301         }
2302         
2303         prop = RNA_def_property(cont, identifier, PROP_ENUM, PROP_NONE);
2304         if (items) RNA_def_property_enum_items(prop, items);
2305         RNA_def_property_enum_default(prop, default_value);
2306         RNA_def_property_ui_text(prop, ui_name, ui_description);
2307
2308         return prop;
2309 }
2310
2311 /* same as above but sets 'PROP_ENUM_FLAG' before setting the default value */
2312 PropertyRNA *RNA_def_enum_flag(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value,
2313         const char *ui_name, const char *ui_description)
2314 {
2315         ContainerRNA *cont = cont_;
2316         PropertyRNA *prop;
2317
2318         if (!items) {
2319                 printf("%s: items not allowed to be NULL.\n", __func__);
2320                 return NULL;
2321         }
2322
2323         prop = RNA_def_property(cont, identifier, PROP_ENUM, PROP_NONE);
2324         RNA_def_property_flag(prop, PROP_ENUM_FLAG); /* important to run before default set */
2325         if (items) RNA_def_property_enum_items(prop, items);
2326         RNA_def_property_enum_default(prop, default_value);
2327         RNA_def_property_ui_text(prop, ui_name, ui_description);
2328
2329         return prop;
2330 }
2331
2332 void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
2333 {
2334         EnumPropertyRNA *eprop = (EnumPropertyRNA*)prop;
2335         eprop->itemf = itemfunc;
2336 }
2337
2338 void RNA_def_enum_py_data(PropertyRNA *prop, void *py_data)
2339 {
2340         EnumPropertyRNA *eprop = (EnumPropertyRNA*)prop;
2341         eprop->py_data = py_data;
2342 }
2343
2344 PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, 
2345         float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
2346 {
2347         ContainerRNA *cont = cont_;
2348         PropertyRNA *prop;
2349         
2350         prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE);
2351         RNA_def_property_float_default(prop, default_value);
2352         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2353         RNA_def_property_ui_text(prop, ui_name, ui_description);
2354         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2355
2356         return prop;
2357 }
2358
2359 PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, 
2360         float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
2361 {
2362         ContainerRNA *cont = cont_;
2363         PropertyRNA *prop;
2364         
2365         prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_XYZ);
2366         if (len != 0) RNA_def_property_array(prop, len);
2367         if (default_value) RNA_def_property_float_array_default(prop, default_value);
2368         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2369         RNA_def_property_ui_text(prop, ui_name, ui_description);
2370         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2371
2372         return prop;
2373 }
2374
2375 PropertyRNA *RNA_def_float_vector_xyz(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, 
2376         float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
2377 {
2378         PropertyRNA *prop;
2379         
2380         prop = RNA_def_float_vector(cont_, identifier, len, default_value, hardmin, hardmax, ui_name, ui_description, softmin, softmax);
2381         prop->subtype = PROP_XYZ_LENGTH;
2382
2383         return prop;
2384 }
2385
2386 PropertyRNA *RNA_def_float_color(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, 
2387         float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
2388 {
2389         ContainerRNA *cont = cont_;
2390         PropertyRNA *prop;
2391         
2392         prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_COLOR);
2393         if (len != 0) RNA_def_property_array(prop, len);
2394         if (default_value) RNA_def_property_float_array_default(prop, default_value);
2395         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2396         RNA_def_property_ui_text(prop, ui_name, ui_description);
2397         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2398
2399         return prop;
2400 }
2401
2402
2403 PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont_, const char *identifier, int rows, int columns, const float *default_value, 
2404         float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
2405 {
2406         ContainerRNA *cont = cont_;
2407         PropertyRNA *prop;
2408         int length[2];
2409
2410         length[0] = rows;
2411         length[1] = columns;
2412
2413         prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_MATRIX);
2414         RNA_def_property_multi_array(prop, 2, length);
2415         if (default_value) RNA_def_property_float_array_default(prop, default_value);
2416         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2417         RNA_def_property_ui_text(prop, ui_name, ui_description);
2418         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2419
2420         return prop;
2421 }
2422
2423 PropertyRNA *RNA_def_float_rotation(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value,
2424         float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
2425 {
2426         ContainerRNA *cont = cont_;
2427         PropertyRNA *prop;
2428         
2429         prop = RNA_def_property(cont, identifier, PROP_FLOAT, (len != 0) ? PROP_EULER : PROP_ANGLE);
2430         if (len != 0) {
2431                 RNA_def_property_array(prop, len);
2432                 if (default_value) RNA_def_property_float_array_default(prop, default_value);
2433         }
2434         else {
2435                 /* RNA_def_property_float_default must be called outside */
2436                 BLI_assert(default_value == NULL);
2437         }
2438         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2439         RNA_def_property_ui_text(prop, ui_name, ui_description);
2440         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2441
2442         return prop;
2443 }
2444
2445 PropertyRNA *RNA_def_float_array(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value,
2446         float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
2447 {
2448         ContainerRNA *cont = cont_;
2449         PropertyRNA *prop;
2450         
2451         prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE);
2452         if (len != 0) RNA_def_property_array(prop, len);
2453         if (default_value) RNA_def_property_float_array_default(prop, default_value);
2454         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2455         RNA_def_property_ui_text(prop, ui_name, ui_description);
2456         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2457
2458         return prop;
2459 }
2460
2461 PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont_, const char *identifier, float default_value,
2462         float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
2463 {
2464         ContainerRNA *cont = cont_;
2465         PropertyRNA *prop;
2466         
2467         prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_PERCENTAGE);
2468         RNA_def_property_float_default(prop, default_value);
2469         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2470         RNA_def_property_ui_text(prop, ui_name, ui_description);
2471         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2472
2473         return prop;
2474 }
2475
2476 PropertyRNA *RNA_def_float_factor(StructOrFunctionRNA *cont_, const char *identifier, float default_value,
2477         float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
2478 {
2479         ContainerRNA *cont = cont_;
2480         PropertyRNA *prop;
2481         
2482         prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_FACTOR);
2483         RNA_def_property_float_default(prop, default_value);
2484         if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2485         RNA_def_property_ui_text(prop, ui_name, ui_description);
2486         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2487
2488         return prop;
2489 }
2490
2491 PropertyRNA *RNA_def_pointer(StructOrFunctionRNA *cont_, const char *identifier, const char *type,
2492         const char *ui_name, const char *ui_description)
2493 {
2494         ContainerRNA *cont = cont_;
2495         PropertyRNA *prop;
2496         
2497         prop = RNA_def_property(cont, identifier, PROP_POINTER, PROP_NONE);
2498         RNA_def_property_struct_type(prop, type);
2499         RNA_def_property_ui_text(prop, ui_name, ui_description);
2500
2501         return prop;
2502 }
2503
2504 PropertyRNA *RNA_def_pointer_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type,
2505         const char *ui_name, const char *ui_description)
2506 {
2507         ContainerRNA *cont = cont_;
2508         PropertyRNA *prop;
2509         
2510         prop = RNA_def_property(cont, identifier, PROP_POINTER, PROP_NONE);
2511         RNA_def_property_struct_runtime(prop, type);
2512         RNA_def_property_ui_text(prop, ui_name, ui_description);
2513
2514         return prop;
2515 }
2516
2517 PropertyRNA *RNA_def_collection(StructOrFunctionRNA *cont_, const char *identifier, const char *type,
2518         const char *ui_name, const char *ui_description)
2519 {
2520         ContainerRNA *cont = cont_;
2521         PropertyRNA *prop;
2522         
2523         prop = RNA_def_property(cont, identifier, PROP_COLLECTION, PROP_NONE);
2524         RNA_def_property_struct_type(prop, type);
2525         RNA_def_property_ui_text(prop, ui_name, ui_description);
2526
2527         return prop;
2528 }
2529
2530 PropertyRNA *RNA_def_collection_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type,
2531         const char *ui_name, const char *ui_description)
2532 {
2533         ContainerRNA *cont = cont_;
2534         PropertyRNA *prop;
2535         
2536         prop = RNA_def_property(cont, identifier, PROP_COLLECTION, PROP_NONE);
2537         RNA_def_property_struct_runtime(prop, type);
2538         RNA_def_property_ui_text(prop, ui_name, ui_description);
2539
2540         return prop;
2541 }
2542
2543 /* Function */
2544
2545 static FunctionRNA *rna_def_function(StructRNA *srna, const char *identifier)
2546 {
2547         FunctionRNA *func;
2548         StructDefRNA *dsrna;
2549         FunctionDefRNA *dfunc;
2550
2551         if (DefRNA.preprocess) {
2552                 char error[512];
2553
2554                 if (rna_validate_identifier(identifier, error, 0) == 0) {
2555                         fprintf(stderr, "%s: function identifier \"%s\" - %s\n", __func__, identifier, error);
2556                         DefRNA.error = 1;
2557                 }
2558         }
2559
2560         func = MEM_callocN(sizeof(FunctionRNA), "FunctionRNA");
2561         func->identifier = identifier;
2562         func->description = identifier;
2563
2564         rna_addtail(&srna->functions, func);
2565
2566         if (DefRNA.preprocess) {
2567                 dsrna = rna_find_struct_def(srna);
2568                 dfunc = MEM_callocN(sizeof(FunctionDefRNA), "FunctionDefRNA");
2569                 rna_addtail(&dsrna->functions, dfunc);
2570                 dfunc->func = func;
2571         }
2572         else
2573                 func->flag |= FUNC_RUNTIME;
2574
2575         return func;
2576 }
2577
2578 FunctionRNA *RNA_def_function(StructRNA *srna, const char *identifier, const char *call)
2579 {
2580         FunctionRNA *func;
2581         FunctionDefRNA *dfunc;
2582
2583         func = rna_def_function(srna, identifier);
2584
2585         if (!DefRNA.preprocess) {
2586                 fprintf(stderr, "%s: only at preprocess time.\n", __func__);
2587                 return func;
2588         }
2589
2590         dfunc = rna_find_function_def(func);
2591         dfunc->call = call;
2592
2593         return func;
2594 }
2595
2596 FunctionRNA *RNA_def_function_runtime(StructRNA *srna, const char *identifier, CallFunc call)
2597 {
2598         FunctionRNA *func;
2599
2600         func = rna_def_function(srna, identifier);
2601
2602         if (DefRNA.preprocess) {
2603                 fprintf(stderr, "%s: only at runtime.\n", __func__);
2604                 return func;
2605         }
2606
2607         func->call = call;
2608
2609
2610         return func;
2611 }
2612
2613 /* C return value only!, multiple RNA returns can be done with RNA_def_function_output */
2614 void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret)
2615 {
2616         if (ret->flag & PROP_DYNAMIC) {
2617                 fprintf(stderr, "%s: \"%s.%s\", dynamic values are not allowed as strict returns, use RNA_def_function_output instead.\n", __func__, func->identifier, ret->identifier);
2618                 return;
2619         }
2620         else if (ret->arraydimension) {
2621                 fprintf(stderr, "%s: \"%s.%s\", arrays are not allowed as strict returns, use RNA_def_function_output instead.\n", __func__, func->identifier, ret->identifier);
2622                 return;
2623         }
2624
2625         func->c_ret = ret;
2626
2627         RNA_def_function_output(func, ret);
2628 }
2629
2630 void RNA_def_function_output(FunctionRNA *UNUSED(func), PropertyRNA *ret)
2631 {
2632         ret->flag |= PROP_OUTPUT;
2633 }
2634
2635 void RNA_def_function_flag(FunctionRNA *func, int flag)
2636 {
2637         func->flag |= flag;
2638 }
2639
2640 void RNA_def_function_ui_description(FunctionRNA *func, const char *description)
2641 {
2642         func->description = description;
2643 }
2644
2645 int rna_parameter_size(PropertyRNA *parm)
2646 {
2647         PropertyType ptype = parm->type;
2648         int len = parm->totarraylength; /* only supports fixed length at the moment */
2649
2650         if (len > 0) {
2651                 /* XXX in other parts is mentioned that strings can be dynamic as well */
2652                 if (parm->flag & PROP_DYNAMIC)
2653                         return sizeof(void *);
2654
2655                 switch (ptype) {
2656                         case PROP_BOOLEAN:
2657                         case PROP_INT:
2658                                 return sizeof(int)*len;
2659                         case PROP_FLOAT:
2660                                 return sizeof(float)*len;
2661                         default:
2662                                 break;
2663                 }
2664         }
2665         else {
2666                 switch (ptype) {
2667                         case PROP_BOOLEAN:
2668                         case PROP_INT:
2669                         case PROP_ENUM:
2670                                 return sizeof(int);
2671                         case PROP_FLOAT:
2672                                 return sizeof(float);
2673                         case PROP_STRING:
2674                                 /* return values don't store a pointer to the original */
2675                                 if (parm->flag & PROP_THICK_WRAP) {
2676                                         StringPropertyRNA *sparm = (StringPropertyRNA*)parm;
2677                                         return sizeof(char) * sparm->maxlength;
2678                                 } else
2679                                         return sizeof(char *);
2680                         case PROP_POINTER: {
2681 #ifdef RNA_RUNTIME
2682                                 if (parm->flag & PROP_RNAPTR)
2683                                         return sizeof(PointerRNA);
2684                                 else
2685                                         return sizeof(void *);
2686 #else
2687                                 if (parm->flag & PROP_RNAPTR)
2688                                         return sizeof(PointerRNA);
2689                                 else
2690                                         return sizeof(void *);
2691 #endif
2692                         }
2693                         case PROP_COLLECTION:
2694                                 return sizeof(ListBase);
2695                 }
2696         }
2697
2698         return sizeof(void *);
2699 }
2700
2701 /* this function returns the size of the memory allocated for the parameter,
2702  * useful for instance for memory alignment or for storing additional information */
2703 int rna_parameter_size_alloc(PropertyRNA *parm)
2704 {
2705         int size = rna_parameter_size(parm);
2706
2707         if (parm->flag & PROP_DYNAMIC)
2708                 size += sizeof(((ParameterDynAlloc *)NULL)->array_tot);
2709
2710         return size;
2711 }
2712
2713 /* Dynamic Enums */
2714
2715 void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
2716 {
2717         EnumPropertyItem *newitems;
2718         int tot = *totitem;
2719
2720         if (tot == 0) {
2721                 *items = MEM_callocN(sizeof(EnumPropertyItem)*8, "RNA_enum_items_add");
2722         }
2723         else if (tot >= 8 && (tot&(tot-1)) == 0){
2724                 /* power of two > 8 */
2725                 newitems = MEM_callocN(sizeof(EnumPropertyItem)*tot*2, "RNA_enum_items_add");
2726                 memcpy(newitems, *items, sizeof(EnumPropertyItem)*tot);
2727                 MEM_freeN(*items);
2728                 *items = newitems;
2729         }
2730
2731         (*items)[tot] = *item;
2732         *totitem = tot+1;
2733 }
2734
2735 void RNA_enum_item_add_separator(EnumPropertyItem **items, int *totitem)
2736 {
2737         static EnumPropertyItem sepr = {0, "", 0, NULL, NULL};
2738         RNA_enum_item_add(items, totitem, &sepr);
2739 }
2740
2741 void RNA_enum_items_add(EnumPropertyItem **items, int *totitem, EnumPropertyItem *item)
2742 {
2743         for (; item->identifier; item++)
2744                 RNA_enum_item_add(items, totitem, item);
2745 }
2746
2747 void RNA_enum_items_add_value(EnumPropertyItem **items, int *totitem, EnumPropertyItem *item, int value)
2748 {
2749         for (; item->identifier; item++) {
2750                 if (item->value == value) {
2751                         RNA_enum_item_add(items, totitem, item);
2752                         break; /* break on first match - does this break anything? (is quick hack to get object->parent_type working ok for armature/lattice) */
2753                 }
2754         }
2755 }
2756
2757 void RNA_enum_item_end(EnumPropertyItem **items, int *totitem)
2758 {
2759         static EnumPropertyItem empty = {0, NULL, 0, NULL, NULL};
2760         RNA_enum_item_add(items, totitem, &empty);
2761 }
2762
2763 /* Memory management */
2764
2765 #ifdef RNA_RUNTIME
2766 void RNA_def_struct_duplicate_pointers(StructRNA *srna)
2767 {
2768         if (srna->identifier) srna->identifier = BLI_strdup(srna->identifier);
2769         if (srna->name) srna->name = BLI_strdup(srna->name);
2770         if (srna->description) srna->description = BLI_strdup(srna->description);
2771
2772         srna->flag |= STRUCT_FREE_POINTERS;
2773 }
2774
2775 void RNA_def_struct_free_pointers(StructRNA *srna)
2776 {
2777         if (srna->flag & STRUCT_FREE_POINTERS) {
2778                 if (srna->identifier) MEM_freeN((void*)srna->identifier);
2779                 if (srna->name) MEM_freeN((void*)srna->name);
2780                 if (srna->description) MEM_freeN((void*)srna->description);
2781         }
2782 }
2783
2784 void RNA_def_func_duplicate_pointers(FunctionRNA *func)
2785 {
2786         if (func->identifier) func->identifier = BLI_strdup(func->identifier);
2787         if (func->description) func->description = BLI_strdup(func->description);
2788
2789         func->flag |= FUNC_FREE_POINTERS;
2790 }
2791
2792 void RNA_def_func_free_pointers(FunctionRNA *func)
2793 {
2794         if (func->flag & FUNC_FREE_POINTERS) {
2795                 if (func->identifier) MEM_freeN((void*)func->identifier);
2796                 if (func->description) MEM_freeN((void*)func->description);
2797         }
2798 }
2799
2800 void RNA_def_property_duplicate_pointers(StructOrFunctionRNA *cont_, PropertyRNA *prop)
2801 {
2802         ContainerRNA *cont = cont_;
2803         EnumPropertyItem *earray;
2804         float *farray;
2805         int *iarray;
2806         int a;
2807
2808         /* annoying since we just added this to a hash, could make this add the correct key to the hash in the first place */
2809         if (prop->identifier) {
2810                 if (cont->prophash) {
2811                         BLI_ghash_remove(cont->prophash, (void*)prop->identifier, NULL, NULL);
2812                         prop->identifier = BLI_strdup(prop->identifier);
2813                         BLI_ghash_insert(cont->prophash, (void*)prop->identifier, prop);
2814                 }
2815                 else {
2816                         prop->identifier = BLI_strdup(prop->identifier);
2817                 }
2818         }
2819
2820         if (prop->name) prop->name = BLI_strdup(prop->name);
2821         if (prop->description) prop->description = BLI_strdup(prop->description);
2822
2823         switch (prop->type) {
2824                 case PROP_BOOLEAN: {
2825                         BoolPropertyRNA *bprop = (BoolPropertyRNA*)prop;
2826
2827                         if (bprop->defaultarray) {
2828                                 iarray = MEM_callocN(sizeof(int)*prop->totarraylength, "RNA_def_property_store");
2829                                 memcpy(iarray, bprop->defaultarray, sizeof(int)*prop->totarraylength);
2830                                 bprop->defaultarray = iarray;
2831                         }
2832                         break;
2833                 }
2834                 case PROP_INT: {
2835                         IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
2836
2837                         if (iprop->defaultarray) {
2838                                 iarray = MEM_callocN(sizeof(int)*prop->totarraylength, "RNA_def_property_store");
2839                                 memcpy(iarray, iprop->defaultarray, sizeof(int)*prop->totarraylength);
2840                                 iprop->defaultarray = iarray;
2841                         }
2842                         break;
2843                 }
2844                 case PROP_ENUM: {
2845                         EnumPropertyRNA *eprop = (EnumPropertyRNA*)prop;
2846
2847                         if (eprop->item) {
2848                                 earray = MEM_callocN(sizeof(EnumPropertyItem)*(eprop->totitem+1), "RNA_def_property_store"),
2849                                 memcpy(earray, eprop->item, sizeof(EnumPropertyItem)*(eprop->totitem+1));
2850                                 eprop->item = earray;
2851
2852                                 for (a = 0; a<eprop->totitem; a++) {
2853                                         if (eprop->item[a].identifier) eprop->item[a].identifier = BLI_strdup(eprop->item[a].identifier);
2854                                         if (eprop->item[a].name) eprop->item[a].name = BLI_strdup(eprop->item[a].name);
2855                                         if (eprop->item[a].description) eprop->item[a].description = BLI_strdup(eprop->item[a].description);
2856                                 }
2857                         }
2858                         break;
2859                 }
2860                 case PROP_FLOAT: {
2861                         FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
2862
2863                         if (fprop->defaultarray) {
2864                                 farray = MEM_callocN(sizeof(float)*prop->totarraylength, "RNA_def_property_store");
2865                                 memcpy(farray, fprop->defaultarray, sizeof(float)*prop->totarraylength);
2866                                 fprop->defaultarray = farray;
2867                         }
2868                         break;
2869                 }
2870                 case PROP_STRING: {
2871                         StringPropertyRNA *sprop = (StringPropertyRNA*)prop;
2872                         if (sprop->defaultvalue) sprop->defaultvalue = BLI_strdup(sprop->defaultvalue);
2873                         break;
2874                 }
2875                 default:
2876                         break;
2877         }
2878
2879         prop->flag |= PROP_FREE_POINTERS;
2880 }
2881
2882 void RNA_def_property_free_pointers(PropertyRNA *prop)
2883 {
2884         if (prop->flag & PROP_FREE_POINTERS) {
2885                 int a;
2886
2887                 if (prop->identifier) MEM_freeN((void*)prop->identifier);
2888                 if (prop->name) MEM_freeN((void*)prop->name);
2889                 if (prop->description) MEM_freeN((void*)prop->description);
2890                 if (prop->py_data) MEM_freeN(prop->py_data);
2891
2892                 switch (prop->type) {
2893                         case PROP_BOOLEAN: {
2894                                 BoolPropertyRNA *bprop = (BoolPropertyRNA*)prop;
2895                                 if (bprop->defaultarray) MEM_freeN((void*)bprop->defaultarray);
2896                                 break;
2897                         }
2898                         case PROP_INT: {
2899                                 IntPropertyRNA *iprop = (IntPropertyRNA*)prop;
2900                                 if (iprop->defaultarray) MEM_freeN((void*)iprop->defaultarray);
2901                                 break;
2902                         }
2903                         case PROP_FLOAT: {
2904                                 FloatPropertyRNA *fprop = (FloatPropertyRNA*)prop;
2905                                 if (fprop->defaultarray) MEM_freeN((void*)fprop->defaultarray);
2906                                 break;
2907                         }
2908                         case PROP_ENUM: {
2909                                 EnumPropertyRNA *eprop = (EnumPropertyRNA*)prop;
2910
2911                                 for (a = 0; a<eprop->totitem; a++) {
2912                                         if (eprop->item[a].identifier) MEM_freeN((void*)eprop->item[a].identifier);
2913                                         if (eprop->item[a].name) MEM_freeN((void*)eprop->item[a].name);
2914                                         if (eprop->item[a].description) MEM_freeN((void*)eprop->item[a].description);
2915                                 }
2916
2917                                 if (eprop->item) MEM_freeN((void*)eprop->item);
2918                                 break;
2919                         }
2920                         case PROP_STRING: {
2921                                 StringPropertyRNA *sprop = (StringPropertyRNA*)prop;
2922                                 if (sprop->defaultvalue) MEM_freeN((void*)sprop->defaultvalue);
2923                                 break;
2924                         }
2925                         default:
2926                                 break;
2927                 }
2928         }
2929 }
2930
2931 static void rna_def_property_free(StructOrFunctionRNA *cont_, PropertyRNA *prop)
2932 {
2933         ContainerRNA *cont = cont_;
2934         
2935         if (prop->flag & PROP_RUNTIME) {
2936                 if (cont->prophash)
2937                         BLI_ghash_remove(cont->prophash, (void*)prop->identifier, NULL, NULL);
2938
2939                 RNA_def_property_free_pointers(prop);
2940                 rna_freelinkN(&cont->properties, prop);
2941         }
2942         else {
2943                 RNA_def_property_free_pointers(prop);
2944         }
2945 }
2946
2947 /* note: only intended for removing dynamic props */
2948 int RNA_def_property_free_identifier(StructOrFunctionRNA *cont_, const char *identifier)
2949 {
2950         ContainerRNA *cont = cont_;
2951         PropertyRNA *prop;
2952         
2953         for (prop = cont->properties.first; prop; prop = prop->next) {
2954                 if (strcmp(prop->identifier, identifier) == 0) {
2955                         if (prop->flag & PROP_RUNTIME) {
2956                                 rna_def_property_free(cont_, prop);
2957                                 return 1;
2958                         }
2959                         else {
2960                                 return -1;
2961                         }
2962                 }
2963         }
2964         return 0;
2965 }
2966 #endif
2967
2968 const char *RNA_property_typename(PropertyType type)
2969 {
2970         switch (type) {
2971                 case PROP_BOOLEAN: return "PROP_BOOLEAN";
2972                 case PROP_INT: return "PROP_INT";
2973                 case PROP_FLOAT: return "PROP_FLOAT";
2974                 case PROP_STRING: return "PROP_STRING";
2975                 case PROP_ENUM: return "PROP_ENUM";
2976                 case PROP_POINTER: return "PROP_POINTER";
2977                 case PROP_COLLECTION: return "PROP_COLLECTION";
2978         }
2979
2980         return "PROP_UNKNOWN";
2981 }