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