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