svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r22668:22701
[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                                 for(i=0; item[i].identifier; i++) {
1178                                         if(item[i].identifier[0]) {
1179                                                 eprop->defaultvalue= item[i].value;
1180                                                 break;
1181                                         }
1182                                 }
1183                         }
1184
1185                         break;
1186                 }
1187                 default:
1188                         fprintf(stderr, "RNA_def_property_enum_items: %s.%s, invalid type for struct type.\n", srna->identifier, prop->identifier);
1189                         DefRNA.error= 1;
1190                         break;
1191         }
1192 }
1193
1194 void RNA_def_property_string_maxlength(PropertyRNA *prop, int maxlength)
1195 {
1196         StructRNA *srna= DefRNA.laststruct;
1197
1198         switch(prop->type) {
1199                 case PROP_STRING: {
1200                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1201                         sprop->maxlength= maxlength;
1202                         break;
1203                 }
1204                 default:
1205                         fprintf(stderr, "RNA_def_property_string_maxlength: %s.%s, type is not string.\n", srna->identifier, prop->identifier);
1206                         DefRNA.error= 1;
1207                         break;
1208         }
1209 }
1210
1211 void RNA_def_property_boolean_default(PropertyRNA *prop, int value)
1212 {
1213         StructRNA *srna= DefRNA.laststruct;
1214
1215         switch(prop->type) {
1216                 case PROP_BOOLEAN: {
1217                         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1218                         bprop->defaultvalue= value;
1219                         break;
1220                 }
1221                 default:
1222                         fprintf(stderr, "RNA_def_property_boolean_default: %s.%s, type is not boolean.\n", srna->identifier, prop->identifier);
1223                         DefRNA.error= 1;
1224                         break;
1225         }
1226 }
1227
1228 void RNA_def_property_boolean_array_default(PropertyRNA *prop, const int *array)
1229 {
1230         StructRNA *srna= DefRNA.laststruct;
1231
1232         switch(prop->type) {
1233                 case PROP_BOOLEAN: {
1234                         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1235                         bprop->defaultarray= array;
1236                         break;
1237                 }
1238                 default:
1239                         fprintf(stderr, "RNA_def_property_boolean_default: %s.%s, type is not boolean.\n", srna->identifier, prop->identifier);
1240                         DefRNA.error= 1;
1241                         break;
1242         }
1243 }
1244
1245 void RNA_def_property_int_default(PropertyRNA *prop, int value)
1246 {
1247         StructRNA *srna= DefRNA.laststruct;
1248
1249         switch(prop->type) {
1250                 case PROP_INT: {
1251                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1252                         iprop->defaultvalue= value;
1253                         break;
1254                 }
1255                 default:
1256                         fprintf(stderr, "RNA_def_property_int_default: %s.%s, type is not int.\n", srna->identifier, prop->identifier);
1257                         DefRNA.error= 1;
1258                         break;
1259         }
1260 }
1261
1262 void RNA_def_property_int_array_default(PropertyRNA *prop, const int *array)
1263 {
1264         StructRNA *srna= DefRNA.laststruct;
1265
1266         switch(prop->type) {
1267                 case PROP_INT: {
1268                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1269                         iprop->defaultarray= array;
1270                         break;
1271                 }
1272                 default:
1273                         fprintf(stderr, "RNA_def_property_int_default: %s.%s, type is not int.\n", srna->identifier, prop->identifier);
1274                         DefRNA.error= 1;
1275                         break;
1276         }
1277 }
1278
1279 void RNA_def_property_float_default(PropertyRNA *prop, float value)
1280 {
1281         StructRNA *srna= DefRNA.laststruct;
1282
1283         switch(prop->type) {
1284                 case PROP_FLOAT: {
1285                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1286                         fprop->defaultvalue= value;
1287                         break;
1288                 }
1289                 default:
1290                         fprintf(stderr, "RNA_def_property_float_default: %s.%s, type is not float.\n", srna->identifier, prop->identifier);
1291                         DefRNA.error= 1;
1292                         break;
1293         }
1294 }
1295 /* array must remain valid after this function finishes */
1296 void RNA_def_property_float_array_default(PropertyRNA *prop, const float *array)
1297 {
1298         StructRNA *srna= DefRNA.laststruct;
1299
1300         switch(prop->type) {
1301                 case PROP_FLOAT: {
1302                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1303                         fprop->defaultarray= array; /* WARNING, this array must not come from the stack and lost */
1304                         break;
1305                 }
1306                 default:
1307                         fprintf(stderr, "RNA_def_property_float_default: %s.%s, type is not float.\n", srna->identifier, prop->identifier);
1308                         DefRNA.error= 1;
1309                         break;
1310         }
1311 }
1312
1313 void RNA_def_property_string_default(PropertyRNA *prop, const char *value)
1314 {
1315         StructRNA *srna= DefRNA.laststruct;
1316
1317         switch(prop->type) {
1318                 case PROP_STRING: {
1319                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1320                         sprop->defaultvalue= value;
1321                         break;
1322                 }
1323                 default:
1324                         fprintf(stderr, "RNA_def_property_string_default: %s.%s, type is not string.\n", srna->identifier, prop->identifier);
1325                         DefRNA.error= 1;
1326                         break;
1327         }
1328 }
1329
1330 void RNA_def_property_enum_default(PropertyRNA *prop, int value)
1331 {
1332         StructRNA *srna= DefRNA.laststruct;
1333         int i, defaultfound= 0;
1334
1335         switch(prop->type) {
1336                 case PROP_ENUM: {
1337                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
1338                         eprop->defaultvalue= value;
1339
1340                         for(i=0; i<eprop->totitem; i++) {
1341                                 if(eprop->item[i].identifier[0] && eprop->item[i].value == eprop->defaultvalue)
1342                                         defaultfound= 1;
1343                         }
1344
1345                         if(!defaultfound && eprop->totitem) {
1346                                 if(value == 0) {
1347                                         eprop->defaultvalue= eprop->item[0].value;
1348                                 }
1349                                 else {
1350                                         fprintf(stderr, "RNA_def_property_enum_default: %s.%s, default is not in items.\n", srna->identifier, prop->identifier);
1351                                         DefRNA.error= 1;
1352                                 }
1353                         }
1354
1355                         break;
1356                 }
1357                 default:
1358                         fprintf(stderr, "RNA_def_property_enum_default: %s.%s, type is not enum.\n", srna->identifier, prop->identifier);
1359                         DefRNA.error= 1;
1360                         break;
1361         }
1362 }
1363
1364 /* SDNA */
1365
1366 static PropertyDefRNA *rna_def_property_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1367 {
1368         DNAStructMember smember;
1369         StructDefRNA *ds;
1370         PropertyDefRNA *dp;
1371
1372         dp= rna_find_struct_property_def(DefRNA.laststruct, prop);
1373         if (dp==NULL) return NULL;
1374
1375         ds= rna_find_struct_def((StructRNA*)dp->cont);
1376
1377         if(!structname)
1378                 structname= ds->dnaname;
1379         if(!propname)
1380                 propname= prop->identifier;
1381
1382         if(!rna_find_sdna_member(DefRNA.sdna, structname, propname, &smember)) {
1383                 if(DefRNA.silent) {
1384                         return NULL;
1385                 }
1386                 else if(!DefRNA.verify) {
1387                         /* some basic values to survive even with sdna info */
1388                         dp->dnastructname= structname;
1389                         dp->dnaname= propname;
1390                         if(prop->type == PROP_BOOLEAN)
1391                                 dp->dnaarraylength= 1;
1392                         if(prop->type == PROP_POINTER)
1393                                 dp->dnapointerlevel= 1;
1394                         return dp;
1395                 }
1396                 else {
1397                         fprintf(stderr, "rna_def_property_sdna: %s.%s not found.\n", structname, propname);
1398                         DefRNA.error= 1;
1399                         return NULL;
1400                 }
1401         }
1402
1403         if(smember.arraylength > 1)
1404                 prop->arraylength= smember.arraylength;
1405         else
1406                 prop->arraylength= 0;
1407         
1408         dp->dnastructname= structname;
1409         dp->dnastructfromname= ds->dnafromname;
1410         dp->dnastructfromprop= ds->dnafromprop;
1411         dp->dnaname= propname;
1412         dp->dnatype= smember.type;
1413         dp->dnaarraylength= smember.arraylength;
1414         dp->dnapointerlevel= smember.pointerlevel;
1415
1416         return dp;
1417 }
1418
1419 void RNA_def_property_boolean_sdna(PropertyRNA *prop, const char *structname, const char *propname, int bit)
1420 {
1421         PropertyDefRNA *dp;
1422         StructRNA *srna= DefRNA.laststruct;
1423         
1424         if(!DefRNA.preprocess) {
1425                 fprintf(stderr, "RNA_def_property_*_sdna: only during preprocessing.\n");
1426                 return;
1427         }
1428
1429         if(prop->type != PROP_BOOLEAN) {
1430                 fprintf(stderr, "RNA_def_property_boolean_sdna: %s.%s, type is not boolean.\n", srna->identifier, prop->identifier);
1431                 DefRNA.error= 1;
1432                 return;
1433         }
1434
1435         if((dp=rna_def_property_sdna(prop, structname, propname)))
1436                 dp->booleanbit= bit;
1437 }
1438
1439 void RNA_def_property_boolean_negative_sdna(PropertyRNA *prop, const char *structname, const char *propname, int booleanbit)
1440 {
1441         PropertyDefRNA *dp;
1442
1443         RNA_def_property_boolean_sdna(prop, structname, propname, booleanbit);
1444
1445         dp= rna_find_struct_property_def(DefRNA.laststruct, prop);
1446
1447         if(dp)
1448                 dp->booleannegative= 1;
1449 }
1450
1451 void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1452 {
1453         PropertyDefRNA *dp;
1454         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1455         StructRNA *srna= DefRNA.laststruct;
1456         
1457         if(!DefRNA.preprocess) {
1458                 fprintf(stderr, "RNA_def_property_*_sdna: only during preprocessing.\n");
1459                 return;
1460         }
1461
1462         if(prop->type != PROP_INT) {
1463                 fprintf(stderr, "RNA_def_property_int_sdna: %s.%s, type is not int.\n", srna->identifier, prop->identifier);
1464                 DefRNA.error= 1;
1465                 return;
1466         }
1467
1468         if((dp= rna_def_property_sdna(prop, structname, propname))) {
1469                 /* SDNA doesn't pass us unsigned unfortunately .. */
1470                 if(dp->dnatype && strcmp(dp->dnatype, "char") == 0) {
1471                         iprop->hardmin= iprop->softmin= CHAR_MIN;
1472                         iprop->hardmax= iprop->softmax= CHAR_MAX;
1473                 }
1474                 else if(dp->dnatype && strcmp(dp->dnatype, "short") == 0) {
1475                         iprop->hardmin= iprop->softmin= SHRT_MIN;
1476                         iprop->hardmax= iprop->softmax= SHRT_MAX;
1477                 }
1478                 else if(dp->dnatype && strcmp(dp->dnatype, "int") == 0) {
1479                         iprop->hardmin= INT_MIN;
1480                         iprop->hardmax= INT_MAX;
1481
1482                         iprop->softmin= -10000; /* rather arbitrary .. */
1483                         iprop->softmax= 10000;
1484                 }
1485
1486                 if(prop->subtype == PROP_UNSIGNED || prop->subtype == PROP_PERCENTAGE)
1487                         iprop->hardmin= iprop->softmin= 0;
1488         }
1489 }
1490
1491 void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1492 {
1493         StructRNA *srna= DefRNA.laststruct;
1494
1495         if(!DefRNA.preprocess) {
1496                 fprintf(stderr, "RNA_def_property_*_sdna: only during preprocessing.\n");
1497                 return;
1498         }
1499
1500         if(prop->type != PROP_FLOAT) {
1501                 fprintf(stderr, "RNA_def_property_float_sdna: %s.%s, type is not float.\n", srna->identifier, prop->identifier);
1502                 DefRNA.error= 1;
1503                 return;
1504         }
1505
1506         rna_def_property_sdna(prop, structname, propname);
1507 }
1508
1509 void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1510 {
1511         PropertyDefRNA *dp;
1512         StructRNA *srna= DefRNA.laststruct;
1513         
1514         if(!DefRNA.preprocess) {
1515                 fprintf(stderr, "RNA_def_property_*_sdna: only during preprocessing.\n");
1516                 return;
1517         }
1518
1519         if(prop->type != PROP_ENUM) {
1520                 fprintf(stderr, "RNA_def_property_enum_sdna: %s.%s, type is not enum.\n", srna->identifier, prop->identifier);
1521                 DefRNA.error= 1;
1522                 return;
1523         }
1524
1525         if((dp=rna_def_property_sdna(prop, structname, propname))) {
1526                 if(prop->arraylength) {
1527                         prop->arraylength= 0;
1528                         if(!DefRNA.silent) {
1529                                 fprintf(stderr, "RNA_def_property_enum_sdna: %s.%s, array not supported for enum type.\n", structname, propname);
1530                                 DefRNA.error= 1;
1531                         }
1532                 }
1533         }
1534 }
1535
1536 void RNA_def_property_enum_bitflag_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1537 {
1538         PropertyDefRNA *dp;
1539
1540         RNA_def_property_enum_sdna(prop, structname, propname);
1541
1542         dp= rna_find_struct_property_def(DefRNA.laststruct, prop);
1543
1544         if(dp)
1545                 dp->enumbitflags= 1;
1546 }
1547
1548 void RNA_def_property_string_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1549 {
1550         PropertyDefRNA *dp;
1551         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1552         StructRNA *srna= DefRNA.laststruct;
1553
1554         if(!DefRNA.preprocess) {
1555                 fprintf(stderr, "RNA_def_property_*_sdna: only during preprocessing.\n");
1556                 return;
1557         }
1558
1559         if(prop->type != PROP_STRING) {
1560                 fprintf(stderr, "RNA_def_property_string_sdna: %s.%s, type is not string.\n", srna->identifier, prop->identifier);
1561                 DefRNA.error= 1;
1562                 return;
1563         }
1564
1565         if((dp=rna_def_property_sdna(prop, structname, propname))) {
1566                 if(prop->arraylength) {
1567                         sprop->maxlength= prop->arraylength;
1568                         prop->arraylength= 0;
1569                 }
1570         }
1571 }
1572
1573 void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, const char *propname)
1574 {
1575         PropertyDefRNA *dp;
1576         StructRNA *srna= DefRNA.laststruct;
1577         
1578         if(!DefRNA.preprocess) {
1579                 fprintf(stderr, "RNA_def_property_*_sdna: only during preprocessing.\n");
1580                 return;
1581         }
1582
1583         if(prop->type != PROP_POINTER) {
1584                 fprintf(stderr, "RNA_def_property_pointer_sdna: %s.%s, type is not pointer.\n", srna->identifier, prop->identifier);
1585                 DefRNA.error= 1;
1586                 return;
1587         }
1588
1589         if((dp=rna_def_property_sdna(prop, structname, propname))) {
1590                 if(prop->arraylength) {
1591                         prop->arraylength= 0;
1592                         if(!DefRNA.silent) {
1593                                 fprintf(stderr, "RNA_def_property_pointer_sdna: %s.%s, array not supported for pointer type.\n", structname, propname);
1594                                 DefRNA.error= 1;
1595                         }
1596                 }
1597         }
1598 }
1599
1600 void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, const char *propname, const char *lengthpropname)
1601 {
1602         PropertyDefRNA *dp;
1603         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1604         StructRNA *srna= DefRNA.laststruct;
1605
1606         if(!DefRNA.preprocess) {
1607                 fprintf(stderr, "RNA_def_property_*_sdna: only during preprocessing.\n");
1608                 return;
1609         }
1610
1611         if(prop->type != PROP_COLLECTION) {
1612                 fprintf(stderr, "RNA_def_property_collection_sdna: %s.%s, type is not collection.\n", srna->identifier, prop->identifier);
1613                 DefRNA.error= 1;
1614                 return;
1615         }
1616
1617         if((dp=rna_def_property_sdna(prop, structname, propname))) {
1618                 if(prop->arraylength && !lengthpropname) {
1619                         prop->arraylength= 0;
1620
1621                         if(!DefRNA.silent) {
1622                                 fprintf(stderr, "RNA_def_property_collection_sdna: %s.%s, array of collections not supported.\n", structname, propname);
1623                                 DefRNA.error= 1;
1624                         }
1625                 }
1626
1627                 if(dp->dnatype && strcmp(dp->dnatype, "ListBase") == 0) {
1628                         cprop->next= (PropCollectionNextFunc)"rna_iterator_listbase_next";
1629                         cprop->get= (PropCollectionGetFunc)"rna_iterator_listbase_get";
1630                         cprop->end= (PropCollectionEndFunc)"rna_iterator_listbase_end";
1631                 }
1632         }
1633
1634         if(dp && lengthpropname) {
1635                 DNAStructMember smember;
1636                 StructDefRNA *ds= rna_find_struct_def((StructRNA*)dp->cont);
1637
1638                 if(!structname)
1639                         structname= ds->dnaname;
1640
1641                 if(lengthpropname[0] == 0 || rna_find_sdna_member(DefRNA.sdna, structname, lengthpropname, &smember)) {
1642                         if(lengthpropname[0] == 0) {
1643                                 dp->dnalengthfixed= prop->arraylength;
1644                                 prop->arraylength= 0;
1645                         }
1646                         else {
1647                                 dp->dnalengthstructname= structname;
1648                                 dp->dnalengthname= lengthpropname;
1649                         }
1650
1651                         cprop->next= (PropCollectionNextFunc)"rna_iterator_array_next";
1652                         cprop->end= (PropCollectionEndFunc)"rna_iterator_array_end";
1653
1654                         if(dp->dnapointerlevel >= 2) 
1655                                 cprop->get= (PropCollectionGetFunc)"rna_iterator_array_dereference_get";
1656                         else
1657                                 cprop->get= (PropCollectionGetFunc)"rna_iterator_array_get";
1658                 }
1659                 else {
1660                         if(!DefRNA.silent) {
1661                                 fprintf(stderr, "RNA_def_property_collection_sdna: %s.%s not found.\n", structname, lengthpropname);
1662                                 DefRNA.error= 1;
1663                         }
1664                 }
1665         }
1666 }
1667
1668 /* Functions */
1669
1670 void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable)
1671 {
1672         if(!DefRNA.preprocess) {
1673                 fprintf(stderr, "RNA_def_property_editable_func: only during preprocessing.\n");
1674                 return;
1675         }
1676
1677         if(editable) prop->editable= (EditableFunc)editable;
1678 }
1679
1680 void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *func)
1681 {
1682         if(!DefRNA.preprocess) {
1683                 fprintf(stderr, "RNA_def_struct_refine_func: only during preprocessing.\n");
1684                 return;
1685         }
1686
1687         prop->noteflag= noteflag;
1688         prop->update= (UpdateFunc)func;
1689 }
1690
1691 void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set)
1692 {
1693         StructRNA *srna= DefRNA.laststruct;
1694
1695         if(!DefRNA.preprocess) {
1696                 fprintf(stderr, "RNA_def_property_*_funcs: only during preprocessing.\n");
1697                 return;
1698         }
1699
1700         switch(prop->type) {
1701                 case PROP_BOOLEAN: {
1702                         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1703
1704                         if(prop->arraylength) {
1705                                 if(get) bprop->getarray= (PropBooleanArrayGetFunc)get;
1706                                 if(set) bprop->setarray= (PropBooleanArraySetFunc)set;
1707                         }
1708                         else {
1709                                 if(get) bprop->get= (PropBooleanGetFunc)get;
1710                                 if(set) bprop->set= (PropBooleanSetFunc)set;
1711                         }
1712                         break;
1713                 }
1714                 default:
1715                         fprintf(stderr, "RNA_def_property_boolean_funcs: %s.%s, type is not boolean.\n", srna->identifier, prop->identifier);
1716                         DefRNA.error= 1;
1717                         break;
1718         }
1719 }
1720
1721 void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
1722 {
1723         StructRNA *srna= DefRNA.laststruct;
1724
1725         if(!DefRNA.preprocess) {
1726                 fprintf(stderr, "RNA_def_property_*_funcs: only during preprocessing.\n");
1727                 return;
1728         }
1729
1730         switch(prop->type) {
1731                 case PROP_INT: {
1732                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1733
1734                         if(prop->arraylength) {
1735                                 if(get) iprop->getarray= (PropIntArrayGetFunc)get;
1736                                 if(set) iprop->setarray= (PropIntArraySetFunc)set;
1737                         }
1738                         else {
1739                                 if(get) iprop->get= (PropIntGetFunc)get;
1740                                 if(set) iprop->set= (PropIntSetFunc)set;
1741                         }
1742                         if(range) iprop->range= (PropIntRangeFunc)range;
1743                         break;
1744                 }
1745                 default:
1746                         fprintf(stderr, "RNA_def_property_int_funcs: %s.%s, type is not int.\n", srna->identifier, prop->identifier);
1747                         DefRNA.error= 1;
1748                         break;
1749         }
1750 }
1751
1752 void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
1753 {
1754         StructRNA *srna= DefRNA.laststruct;
1755
1756         if(!DefRNA.preprocess) {
1757                 fprintf(stderr, "RNA_def_property_*_funcs: only during preprocessing.\n");
1758                 return;
1759         }
1760
1761         switch(prop->type) {
1762                 case PROP_FLOAT: {
1763                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1764
1765                         if(prop->arraylength) {
1766                                 if(get) fprop->getarray= (PropFloatArrayGetFunc)get;
1767                                 if(set) fprop->setarray= (PropFloatArraySetFunc)set;
1768                         }
1769                         else {
1770                                 if(get) fprop->get= (PropFloatGetFunc)get;
1771                                 if(set) fprop->set= (PropFloatSetFunc)set;
1772                         }
1773                         if(range) fprop->range= (PropFloatRangeFunc)range;
1774                         break;
1775                 }
1776                 default:
1777                         fprintf(stderr, "RNA_def_property_float_funcs: %s.%s, type is not float.\n", srna->identifier, prop->identifier);
1778                         DefRNA.error= 1;
1779                         break;
1780         }
1781 }
1782
1783 void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set, const char *item)
1784 {
1785         StructRNA *srna= DefRNA.laststruct;
1786
1787         if(!DefRNA.preprocess) {
1788                 fprintf(stderr, "RNA_def_property_*_funcs: only during preprocessing.\n");
1789                 return;
1790         }
1791
1792         switch(prop->type) {
1793                 case PROP_ENUM: {
1794                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
1795
1796                         if(get) eprop->get= (PropEnumGetFunc)get;
1797                         if(set) eprop->set= (PropEnumSetFunc)set;
1798                         if(item) eprop->itemf= (PropEnumItemFunc)item;
1799                         break;
1800                 }
1801                 default:
1802                         fprintf(stderr, "RNA_def_property_enum_funcs: %s.%s, type is not enum.\n", srna->identifier, prop->identifier);
1803                         DefRNA.error= 1;
1804                         break;
1805         }
1806 }
1807
1808 void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set)
1809 {
1810         StructRNA *srna= DefRNA.laststruct;
1811
1812         if(!DefRNA.preprocess) {
1813                 fprintf(stderr, "RNA_def_property_*_funcs: only during preprocessing.\n");
1814                 return;
1815         }
1816
1817         switch(prop->type) {
1818                 case PROP_STRING: {
1819                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1820
1821                         if(get) sprop->get= (PropStringGetFunc)get;
1822                         if(length) sprop->length= (PropStringLengthFunc)length;
1823                         if(set) sprop->set= (PropStringSetFunc)set;
1824                         break;
1825                 }
1826                 default:
1827                         fprintf(stderr, "RNA_def_property_string_funcs: %s.%s, type is not string.\n", srna->identifier, prop->identifier);
1828                         DefRNA.error= 1;
1829                         break;
1830         }
1831 }
1832
1833 void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set, const char *typef)
1834 {
1835         StructRNA *srna= DefRNA.laststruct;
1836
1837         if(!DefRNA.preprocess) {
1838                 fprintf(stderr, "RNA_def_property_*_funcs: only during preprocessing.\n");
1839                 return;
1840         }
1841
1842         switch(prop->type) {
1843                 case PROP_POINTER: {
1844                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
1845
1846                         if(get) pprop->get= (PropPointerGetFunc)get;
1847                         if(set) pprop->set= (PropPointerSetFunc)set;
1848                         if(typef) pprop->typef= (PropPointerTypeFunc)typef;
1849                         break;
1850                 }
1851                 default:
1852                         fprintf(stderr, "RNA_def_property_pointer_funcs: %s.%s, type is not pointer.\n", srna->identifier, prop->identifier);
1853                         DefRNA.error= 1;
1854                         break;
1855         }
1856 }
1857
1858 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)
1859 {
1860         StructRNA *srna= DefRNA.laststruct;
1861
1862         if(!DefRNA.preprocess) {
1863                 fprintf(stderr, "RNA_def_property_*_funcs: only during preprocessing.\n");
1864                 return;
1865         }
1866
1867         switch(prop->type) {
1868                 case PROP_COLLECTION: {
1869                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1870
1871                         if(begin) cprop->begin= (PropCollectionBeginFunc)begin;
1872                         if(next) cprop->next= (PropCollectionNextFunc)next;
1873                         if(end) cprop->end= (PropCollectionEndFunc)end;
1874                         if(get) cprop->get= (PropCollectionGetFunc)get;
1875                         if(length) cprop->length= (PropCollectionLengthFunc)length;
1876                         if(lookupint) cprop->lookupint= (PropCollectionLookupIntFunc)lookupint;
1877                         if(lookupstring) cprop->lookupstring= (PropCollectionLookupStringFunc)lookupstring;
1878                         if(add) cprop->add= (FunctionRNA*)add;
1879                         if(remove) cprop->remove= (FunctionRNA*)remove;
1880                         break;
1881                 }
1882                 default:
1883                         fprintf(stderr, "RNA_def_property_collection_funcs: %s.%s, type is not collection.\n", srna->identifier, prop->identifier);
1884                         DefRNA.error= 1;
1885                         break;
1886         }
1887 }
1888
1889 /* Compact definitions */
1890
1891 PropertyRNA *RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, int default_value, const char *ui_name, const char *ui_description)
1892 {
1893         ContainerRNA *cont= cont_;
1894         PropertyRNA *prop;
1895         
1896         prop= RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_NONE);
1897         RNA_def_property_boolean_default(prop, default_value);
1898         RNA_def_property_ui_text(prop, ui_name, ui_description);
1899
1900         return prop;
1901 }
1902
1903 PropertyRNA *RNA_def_boolean_array(StructOrFunctionRNA *cont_, const char *identifier, int len, int *default_value, 
1904         const char *ui_name, const char *ui_description)
1905 {
1906         ContainerRNA *cont= cont_;
1907         PropertyRNA *prop;
1908         
1909         prop= RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_NONE);
1910         if(len != 0) RNA_def_property_array(prop, len);
1911         if(default_value) RNA_def_property_boolean_array_default(prop, default_value);
1912         RNA_def_property_ui_text(prop, ui_name, ui_description);
1913
1914         return prop;
1915 }
1916
1917 PropertyRNA *RNA_def_boolean_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, int *default_value, 
1918         const char *ui_name, const char *ui_description)
1919 {
1920         ContainerRNA *cont= cont_;
1921         PropertyRNA *prop;
1922         
1923         prop= RNA_def_property(cont, identifier, PROP_BOOLEAN, PROP_XYZ); // XXX
1924         if(len != 0) RNA_def_property_array(prop, len);
1925         if(default_value) RNA_def_property_boolean_array_default(prop, default_value);
1926         RNA_def_property_ui_text(prop, ui_name, ui_description);
1927
1928         return prop;
1929 }
1930
1931 PropertyRNA *RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, 
1932         const char *ui_name, const char *ui_description, int softmin, int softmax)
1933 {
1934         ContainerRNA *cont= cont_;
1935         PropertyRNA *prop;
1936         
1937         prop= RNA_def_property(cont, identifier, PROP_INT, PROP_NONE);
1938         RNA_def_property_int_default(prop, default_value);
1939         if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
1940         RNA_def_property_ui_text(prop, ui_name, ui_description);
1941         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
1942
1943         return prop;
1944 }
1945
1946 PropertyRNA *RNA_def_int_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, const int *default_value, 
1947         int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
1948 {
1949         ContainerRNA *cont= cont_;
1950         PropertyRNA *prop;
1951         
1952         prop= RNA_def_property(cont, identifier, PROP_INT, PROP_XYZ); // XXX
1953         if(len != 0) RNA_def_property_array(prop, len);
1954         if(default_value) RNA_def_property_int_array_default(prop, default_value);
1955         if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
1956         RNA_def_property_ui_text(prop, ui_name, ui_description);
1957         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
1958
1959         return prop;
1960 }
1961
1962 PropertyRNA *RNA_def_int_array(StructOrFunctionRNA *cont_, const char *identifier, int len, const int *default_value, 
1963         int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
1964 {
1965         ContainerRNA *cont= cont_;
1966         PropertyRNA *prop;
1967         
1968         prop= RNA_def_property(cont, identifier, PROP_INT, PROP_NONE);
1969         if(len != 0) RNA_def_property_array(prop, len);
1970         if(default_value) RNA_def_property_int_array_default(prop, default_value);
1971         if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
1972         RNA_def_property_ui_text(prop, ui_name, ui_description);
1973         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
1974
1975         return prop;
1976 }
1977
1978 PropertyRNA *RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, 
1979         const char *ui_name, const char *ui_description)
1980 {
1981         ContainerRNA *cont= cont_;
1982         PropertyRNA *prop;
1983         
1984         prop= RNA_def_property(cont, identifier, PROP_STRING, PROP_NONE);
1985         if(maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen);
1986         if(default_value) RNA_def_property_string_default(prop, default_value);
1987         RNA_def_property_ui_text(prop, ui_name, ui_description);
1988
1989         return prop;
1990 }
1991
1992 PropertyRNA *RNA_def_string_file_path(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, 
1993         const char *ui_name, const char *ui_description)
1994 {
1995         ContainerRNA *cont= cont_;
1996         PropertyRNA *prop;
1997         
1998         prop= RNA_def_property(cont, identifier, PROP_STRING, PROP_FILEPATH);
1999         if(maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen);
2000         if(default_value) RNA_def_property_string_default(prop, default_value);
2001         RNA_def_property_ui_text(prop, ui_name, ui_description);
2002
2003         return prop;
2004 }
2005
2006 PropertyRNA *RNA_def_string_dir_path(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, 
2007         const char *ui_name, const char *ui_description)
2008 {
2009         ContainerRNA *cont= cont_;
2010         PropertyRNA *prop;
2011         
2012         prop= RNA_def_property(cont, identifier, PROP_STRING, PROP_DIRPATH);
2013         if(maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen);
2014         if(default_value) RNA_def_property_string_default(prop, default_value);
2015         RNA_def_property_ui_text(prop, ui_name, ui_description);
2016
2017         return prop;
2018 }
2019
2020 PropertyRNA *RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, 
2021         const char *ui_name, const char *ui_description)
2022 {
2023         ContainerRNA *cont= cont_;
2024         PropertyRNA *prop;
2025         
2026         prop= RNA_def_property(cont, identifier, PROP_ENUM, PROP_NONE);
2027         if(items) RNA_def_property_enum_items(prop, items);
2028         RNA_def_property_enum_default(prop, default_value);
2029         RNA_def_property_ui_text(prop, ui_name, ui_description);
2030
2031         return prop;
2032 }
2033
2034 void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
2035 {
2036         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
2037         eprop->itemf= itemfunc;
2038 }
2039
2040 PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, 
2041         float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
2042 {
2043         ContainerRNA *cont= cont_;
2044         PropertyRNA *prop;
2045         
2046         prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE);
2047         RNA_def_property_float_default(prop, default_value);
2048         if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2049         RNA_def_property_ui_text(prop, ui_name, ui_description);
2050         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2051
2052         return prop;
2053 }
2054
2055 PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, 
2056         float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
2057 {
2058         ContainerRNA *cont= cont_;
2059         PropertyRNA *prop;
2060         
2061         prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_XYZ);
2062         if(len != 0) RNA_def_property_array(prop, len);
2063         if(default_value) RNA_def_property_float_array_default(prop, default_value);
2064         if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2065         RNA_def_property_ui_text(prop, ui_name, ui_description);
2066         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2067
2068         return prop;
2069 }
2070
2071 PropertyRNA *RNA_def_float_color(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, 
2072         float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
2073 {
2074         ContainerRNA *cont= cont_;
2075         PropertyRNA *prop;
2076         
2077         prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_COLOR);
2078         if(len != 0) RNA_def_property_array(prop, len);
2079         if(default_value) RNA_def_property_float_array_default(prop, default_value);
2080         if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2081         RNA_def_property_ui_text(prop, ui_name, ui_description);
2082         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2083
2084         return prop;
2085 }
2086
2087
2088 PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value, 
2089         float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
2090 {
2091         ContainerRNA *cont= cont_;
2092         PropertyRNA *prop;
2093         
2094         prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_MATRIX);
2095         if(len != 0) RNA_def_property_array(prop, len);
2096         if(default_value) RNA_def_property_float_array_default(prop, default_value);
2097         if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2098         RNA_def_property_ui_text(prop, ui_name, ui_description);
2099         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2100
2101         return prop;
2102 }
2103
2104 PropertyRNA *RNA_def_float_rotation(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value,
2105         float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
2106 {
2107         ContainerRNA *cont= cont_;
2108         PropertyRNA *prop;
2109         
2110         prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_EULER); // XXX
2111         if(len != 0) RNA_def_property_array(prop, len);
2112         if(default_value) RNA_def_property_float_array_default(prop, default_value);
2113         if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2114         RNA_def_property_ui_text(prop, ui_name, ui_description);
2115         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2116
2117         return prop;
2118 }
2119
2120 PropertyRNA *RNA_def_float_array(StructOrFunctionRNA *cont_, const char *identifier, int len, const float *default_value,
2121         float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
2122 {
2123         ContainerRNA *cont= cont_;
2124         PropertyRNA *prop;
2125         
2126         prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE);
2127         if(len != 0) RNA_def_property_array(prop, len);
2128         if(default_value) RNA_def_property_float_array_default(prop, default_value);
2129         if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2130         RNA_def_property_ui_text(prop, ui_name, ui_description);
2131         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2132
2133         return prop;
2134 }
2135
2136 PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont_, const char *identifier, float default_value,
2137         float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
2138 {
2139         ContainerRNA *cont= cont_;
2140         PropertyRNA *prop;
2141         
2142         prop= RNA_def_property(cont, identifier, PROP_FLOAT, PROP_PERCENTAGE);
2143         RNA_def_property_float_default(prop, default_value);
2144         if(hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax);
2145         RNA_def_property_ui_text(prop, ui_name, ui_description);
2146         RNA_def_property_ui_range(prop, softmin, softmax, 1, 3);
2147
2148         return prop;
2149 }
2150
2151 PropertyRNA *RNA_def_pointer(StructOrFunctionRNA *cont_, const char *identifier, const char *type,
2152         const char *ui_name, const char *ui_description)
2153 {
2154         ContainerRNA *cont= cont_;
2155         PropertyRNA *prop;
2156         
2157         prop= RNA_def_property(cont, identifier, PROP_POINTER, PROP_NONE);
2158         RNA_def_property_struct_type(prop, type);
2159         RNA_def_property_ui_text(prop, ui_name, ui_description);
2160
2161         return prop;
2162 }
2163
2164 PropertyRNA *RNA_def_pointer_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type,
2165         const char *ui_name, const char *ui_description)
2166 {
2167         ContainerRNA *cont= cont_;
2168         PropertyRNA *prop;
2169         
2170         prop= RNA_def_property(cont, identifier, PROP_POINTER, PROP_NONE);
2171         RNA_def_property_struct_runtime(prop, type);
2172         RNA_def_property_ui_text(prop, ui_name, ui_description);
2173
2174         return prop;
2175 }
2176
2177 PropertyRNA *RNA_def_collection(StructOrFunctionRNA *cont_, const char *identifier, const char *type,
2178         const char *ui_name, const char *ui_description)
2179 {
2180         ContainerRNA *cont= cont_;
2181         PropertyRNA *prop;
2182         
2183         prop= RNA_def_property(cont, identifier, PROP_COLLECTION, PROP_NONE);
2184         RNA_def_property_struct_type(prop, type);
2185         RNA_def_property_ui_text(prop, ui_name, ui_description);
2186
2187         return prop;
2188 }
2189
2190 PropertyRNA *RNA_def_collection_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type,
2191         const char *ui_name, const char *ui_description)
2192 {
2193         ContainerRNA *cont= cont_;
2194         PropertyRNA *prop;
2195         
2196         prop= RNA_def_property(cont, identifier, PROP_COLLECTION, PROP_NONE);
2197         RNA_def_property_struct_runtime(prop, type);
2198         RNA_def_property_ui_text(prop, ui_name, ui_description);
2199
2200         return prop;
2201 }
2202
2203 /* Function */
2204
2205 static FunctionRNA *rna_def_function(StructRNA *srna, const char *identifier)
2206 {
2207         FunctionRNA *func;
2208         StructDefRNA *dsrna;
2209         FunctionDefRNA *dfunc;
2210
2211         if(DefRNA.preprocess) {
2212                 char error[512];
2213
2214                 if (rna_validate_identifier(identifier, error, 0) == 0) {
2215                         fprintf(stderr, "RNA_def_function: function identifier \"%s\" - %s\n", identifier, error);
2216                         DefRNA.error= 1;
2217                 }
2218         }
2219
2220         func= MEM_callocN(sizeof(FunctionRNA), "FunctionRNA");
2221         func->identifier= identifier;
2222         func->description= identifier;
2223
2224         rna_addtail(&srna->functions, func);
2225
2226         if(DefRNA.preprocess) {
2227                 dsrna= rna_find_struct_def(srna);
2228                 dfunc= MEM_callocN(sizeof(FunctionDefRNA), "FunctionDefRNA");
2229                 rna_addtail(&dsrna->functions, dfunc);
2230                 dfunc->func= func;
2231         }
2232         else
2233                 func->flag|= FUNC_RUNTIME;
2234
2235         return func;
2236 }
2237
2238 FunctionRNA *RNA_def_function(StructRNA *srna, const char *identifier, const char *call)
2239 {
2240         FunctionRNA *func;
2241         FunctionDefRNA *dfunc;
2242
2243         func= rna_def_function(srna, identifier);
2244
2245         if(!DefRNA.preprocess) {
2246                 fprintf(stderr, "RNA_def_function: only at preprocess time.\n");
2247                 return func;
2248         }
2249
2250         dfunc= rna_find_function_def(func);
2251         dfunc->call= call;
2252
2253         return func;
2254 }
2255
2256 FunctionRNA *RNA_def_function_runtime(StructRNA *srna, const char *identifier, CallFunc call)
2257 {
2258         FunctionRNA *func;
2259
2260         func= rna_def_function(srna, identifier);
2261
2262         if(DefRNA.preprocess) {
2263                 fprintf(stderr, "RNA_def_function_call_runtime: only at runtime.\n");
2264                 return func;
2265         }
2266
2267         func->call= call;
2268
2269
2270         return func;
2271 }
2272
2273 void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret)
2274 {
2275         func->ret= ret;
2276         ret->flag|=PROP_RETURN;
2277 }
2278
2279 void RNA_def_function_flag(FunctionRNA *func, int flag)
2280 {
2281         func->flag|= flag;
2282 }
2283
2284 void RNA_def_function_ui_description(FunctionRNA *func, const char *description)
2285 {
2286         func->description= description;
2287 }
2288
2289 int rna_parameter_size(PropertyRNA *parm)
2290 {
2291         PropertyType ptype= parm->type;
2292         int len= parm->arraylength;
2293
2294         if(len > 0) {
2295                 switch (ptype) {
2296                         case PROP_BOOLEAN:
2297                         case PROP_INT:
2298                                 return sizeof(int)*len;
2299                         case PROP_FLOAT:
2300                                 return sizeof(float)*len;
2301                         default:
2302                                 break;
2303                 }
2304         }
2305         else {
2306                 switch (ptype) {
2307                         case PROP_BOOLEAN:
2308                         case PROP_INT:
2309                         case PROP_ENUM:
2310                                 return sizeof(int);
2311                         case PROP_FLOAT:
2312                                 return sizeof(float);
2313                         case PROP_STRING:
2314                                 return sizeof(char *);
2315                         case PROP_POINTER: {
2316 #ifdef RNA_RUNTIME
2317                                 if(parm->flag & PROP_RNAPTR)
2318                                         return sizeof(PointerRNA);
2319                                 else
2320                                         return sizeof(void *);
2321 #else
2322                                 if(parm->flag & PROP_RNAPTR)
2323                                         return sizeof(PointerRNA);
2324                                 else
2325                                         return sizeof(void *);
2326 #endif
2327                         }
2328                         case PROP_COLLECTION:
2329                                 return sizeof(ListBase);
2330                 }
2331         }
2332
2333         return sizeof(void *);
2334 }
2335
2336 /* Dynamic Enums */
2337
2338 void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, EnumPropertyItem *item)
2339 {
2340         EnumPropertyItem *newitems;
2341         int tot= *totitem;
2342
2343         if(tot == 0) {
2344                 *items= MEM_callocN(sizeof(EnumPropertyItem)*8, "RNA_enum_items_add");
2345         }
2346         else if(tot >= 8 && (tot&(tot-1)) == 0){
2347                 /* power of two > 8 */
2348                 newitems= MEM_callocN(sizeof(EnumPropertyItem)*tot*2, "RNA_enum_items_add");
2349                 memcpy(newitems, *items, sizeof(EnumPropertyItem)*tot);
2350                 MEM_freeN(*items);
2351                 *items= newitems;
2352         }
2353
2354         (*items)[tot]= *item;
2355         *totitem= tot+1;
2356 }
2357
2358 void RNA_enum_item_add_separator(EnumPropertyItem **items, int *totitem)
2359 {
2360         static EnumPropertyItem sepr = {0, "", 0, NULL, NULL};
2361         RNA_enum_item_add(items, totitem, &sepr);
2362 }
2363
2364 void RNA_enum_items_add(EnumPropertyItem **items, int *totitem, EnumPropertyItem *item)
2365 {
2366         for(; item->identifier; item++)
2367                 RNA_enum_item_add(items, totitem, item);
2368 }
2369
2370 void RNA_enum_items_add_value(EnumPropertyItem **items, int *totitem, EnumPropertyItem *item, int value)
2371 {
2372         for(; item->identifier; item++) {
2373                 if(item->value == value) {
2374                         RNA_enum_item_add(items, totitem, item);
2375                         break; // break on first match - does this break anything? (is quick hack to get object->parent_type working ok for armature/lattice)
2376                 }
2377         }
2378 }
2379
2380 void RNA_enum_item_end(EnumPropertyItem **items, int *totitem)
2381 {
2382         static EnumPropertyItem empty = {0, NULL, 0, NULL, NULL};
2383         RNA_enum_item_add(items, totitem, &empty);
2384 }
2385
2386 /* Memory management */
2387
2388 #ifdef RNA_RUNTIME
2389 void RNA_def_struct_duplicate_pointers(StructRNA *srna)
2390 {
2391         if(srna->identifier) srna->identifier= BLI_strdup(srna->identifier);
2392         if(srna->name) srna->name= BLI_strdup(srna->name);
2393         if(srna->description) srna->description= BLI_strdup(srna->description);
2394
2395         srna->flag |= STRUCT_FREE_POINTERS;
2396 }
2397
2398 void RNA_def_struct_free_pointers(StructRNA *srna)
2399 {
2400         if(srna->flag & STRUCT_FREE_POINTERS) {
2401                 if(srna->identifier) MEM_freeN((void*)srna->identifier);
2402                 if(srna->name) MEM_freeN((void*)srna->name);
2403                 if(srna->description) MEM_freeN((void*)srna->description);
2404         }
2405 }
2406
2407 void RNA_def_func_duplicate_pointers(FunctionRNA *func)
2408 {
2409         if(func->identifier) func->identifier= BLI_strdup(func->identifier);
2410         if(func->description) func->description= BLI_strdup(func->description);
2411
2412         func->flag |= FUNC_FREE_POINTERS;
2413 }
2414
2415 void RNA_def_func_free_pointers(FunctionRNA *func)
2416 {
2417         if(func->flag & FUNC_FREE_POINTERS) {
2418                 if(func->identifier) MEM_freeN((void*)func->identifier);
2419                 if(func->description) MEM_freeN((void*)func->description);
2420         }
2421 }
2422
2423 void RNA_def_property_duplicate_pointers(PropertyRNA *prop)
2424 {
2425         EnumPropertyItem *earray;
2426         float *farray;
2427         int *iarray;
2428         int a;
2429
2430         if(prop->identifier) prop->identifier= BLI_strdup(prop->identifier);
2431         if(prop->name) prop->name= BLI_strdup(prop->name);
2432         if(prop->description) prop->description= BLI_strdup(prop->description);
2433
2434         switch(prop->type) {
2435                 case PROP_BOOLEAN: {
2436                         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
2437
2438                         if(bprop->defaultarray) {
2439                                 iarray= MEM_callocN(sizeof(int)*prop->arraylength, "RNA_def_property_store");
2440                                 memcpy(iarray, bprop->defaultarray, sizeof(int)*prop->arraylength);
2441                                 bprop->defaultarray= iarray;
2442                         }
2443                         break;
2444                 }
2445                 case PROP_INT: {
2446                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
2447
2448                         if(iprop->defaultarray) {
2449                                 iarray= MEM_callocN(sizeof(int)*prop->arraylength, "RNA_def_property_store");
2450                                 memcpy(iarray, iprop->defaultarray, sizeof(int)*prop->arraylength);
2451                                 iprop->defaultarray= iarray;
2452                         }
2453                         break;
2454                 }
2455                 case PROP_ENUM: {
2456                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
2457
2458                         if(eprop->item) {
2459                                 earray= MEM_callocN(sizeof(EnumPropertyItem)*(eprop->totitem+1), "RNA_def_property_store"),
2460                                 memcpy(earray, eprop->item, sizeof(EnumPropertyItem)*(eprop->totitem+1));
2461                                 eprop->item= earray;
2462
2463                                 for(a=0; a<eprop->totitem; a++) {
2464                                         if(eprop->item[a].identifier) eprop->item[a].identifier= BLI_strdup(eprop->item[a].identifier);
2465                                         if(eprop->item[a].name) eprop->item[a].name= BLI_strdup(eprop->item[a].name);
2466                                         if(eprop->item[a].description) eprop->item[a].description= BLI_strdup(eprop->item[a].description);
2467                                 }
2468                         }
2469                         break;
2470                 }
2471                 case PROP_FLOAT: {
2472                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
2473
2474                         if(fprop->defaultarray) {
2475                                 farray= MEM_callocN(sizeof(float)*prop->arraylength, "RNA_def_property_store");
2476                                 memcpy(farray, fprop->defaultarray, sizeof(float)*prop->arraylength);
2477                                 fprop->defaultarray= farray;
2478                         }
2479                         break;
2480                 }
2481                 case PROP_STRING: {
2482                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
2483                         if(sprop->defaultvalue) sprop->defaultvalue= BLI_strdup(sprop->defaultvalue);
2484                         break;
2485                 }
2486                 default:
2487                         break;
2488         }
2489
2490         prop->flag |= PROP_FREE_POINTERS;
2491 }
2492
2493 void RNA_def_property_free_pointers(PropertyRNA *prop)
2494 {
2495         if(prop->flag & PROP_FREE_POINTERS) {
2496                 int a;
2497
2498                 if(prop->identifier) MEM_freeN((void*)prop->identifier);
2499                 if(prop->name) MEM_freeN((void*)prop->name);
2500                 if(prop->description) MEM_freeN((void*)prop->description);
2501
2502                 switch(prop->type) {
2503                         case PROP_BOOLEAN: {
2504                                 BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
2505                                 if(bprop->defaultarray) MEM_freeN((void*)bprop->defaultarray);
2506                                 break;
2507                         }
2508                         case PROP_INT: {
2509                                 IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
2510                                 if(iprop->defaultarray) MEM_freeN((void*)iprop->defaultarray);
2511                                 break;
2512                         }
2513                         case PROP_FLOAT: {
2514                                 FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
2515                                 if(fprop->defaultarray) MEM_freeN((void*)fprop->defaultarray);
2516                                 break;
2517                         }
2518                         case PROP_ENUM: {
2519                                 EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
2520                                 if(eprop->item) MEM_freeN((void*)eprop->item);
2521
2522                                 for(a=0; a<eprop->totitem; a++) {
2523                                         if(eprop->item[a].identifier) MEM_freeN((void*)eprop->item[a].identifier);
2524                                         if(eprop->item[a].name) MEM_freeN((void*)eprop->item[a].name);
2525                                         if(eprop->item[a].description) MEM_freeN((void*)eprop->item[a].description);
2526                                 }
2527                                 break;
2528                         }
2529                         case PROP_STRING: {
2530                                 StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
2531                                 if(sprop->defaultvalue) MEM_freeN((void*)sprop->defaultvalue);
2532                                 break;
2533                         }
2534                         default:
2535                                 break;
2536                 }
2537         }
2538 }
2539 #endif
2540