RNA
[blender-staging.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
31 #include "MEM_guardedalloc.h"
32
33 #include "DNA_genfile.h"
34 #include "DNA_sdna_types.h"
35
36 #include "RNA_access.h"
37 #include "RNA_define.h"
38 #include "RNA_types.h"
39
40 #include "rna_internal.h"
41
42 /* Global used during defining */
43
44 BlenderDefRNA DefRNA = {0, {0, 0}, {0, 0}, 0, 0, 0};
45
46 /* Duplicated code since we can't link in blenkernel or blenlib */
47
48 #ifndef MIN2
49 #define MIN2(x,y) ((x)<(y)? (x): (y))
50 #define MAX2(x,y) ((x)>(y)? (x): (y))
51 #endif
52
53 void rna_addtail(ListBase *listbase, void *vlink)
54 {
55         Link *link= vlink;
56
57         link->next = NULL;
58         link->prev = listbase->last;
59
60         if (listbase->last) ((Link *)listbase->last)->next = link;
61         if (listbase->first == 0) listbase->first = link;
62         listbase->last = link;
63 }
64
65 void rna_remlink(ListBase *listbase, void *vlink)
66 {
67         Link *link= vlink;
68
69         if (link->next) link->next->prev = link->prev;
70         if (link->prev) link->prev->next = link->next;
71
72         if (listbase->last == link) listbase->last = link->prev;
73         if (listbase->first == link) listbase->first = link->next;
74 }
75
76 void rna_freelinkN(ListBase *listbase, void *vlink)
77 {
78         rna_remlink(listbase, vlink);
79         MEM_freeN(vlink);
80 }
81
82 void rna_freelistN(ListBase *listbase)
83 {
84         Link *link, *next;
85         
86         for(link=listbase->first; link; link=next) {
87                 next= link->next;
88                 MEM_freeN(link);
89         }
90         
91         listbase->first= listbase->last= NULL;
92 }
93
94 /* DNA utility function for looking up members */
95
96 typedef struct DNAStructMember {
97         char *type;
98         char *name;
99         int arraylength;
100 } DNAStructMember;
101
102 static int rna_member_cmp(const char *name, const char *oname)
103 {
104         int a=0;
105         
106         /* compare without pointer or array part */
107         while(name[0]=='*')
108                 name++;
109         while(oname[0]=='*')
110                 oname++;
111         
112         while(1) {
113                 if(name[a]=='[' && oname[a]==0) return 1;
114                 if(name[a]==0) break;
115                 if(name[a] != oname[a]) return 0;
116                 a++;
117         }
118         if(name[a]==0 && oname[a] == '.') return 2;
119         if(name[a]==0 && oname[a] == '-' && oname[a+1] == '>') return 3;
120
121         return (name[a] == oname[a]);
122 }
123
124 static int rna_find_sdna_member(SDNA *sdna, const char *structname, const char *membername, DNAStructMember *smember)
125 {
126         char *dnaname;
127         short *sp;
128         int a, structnr, totmember, cmp;
129
130         structnr= DNA_struct_find_nr(sdna, structname);
131         if(structnr == -1)
132                 return 0;
133
134         sp= sdna->structs[structnr];
135         totmember= sp[1];
136         sp+= 2;
137
138         for(a=0; a<totmember; a++, sp+=2) {
139                 dnaname= sdna->names[sp[1]];
140
141                 cmp= rna_member_cmp(dnaname, membername);
142
143                 if(cmp == 1) {
144                         smember->type= sdna->types[sp[0]];
145                         smember->name= dnaname;
146                         smember->arraylength= DNA_elem_array_size(smember->name, strlen(smember->name));
147                         return 1;
148                 }
149                 else if(cmp == 2) {
150                         membername= strstr(membername, ".") + strlen(".");
151                         return rna_find_sdna_member(sdna, sdna->types[sp[0]], membername, smember);
152                 }
153                 else if(cmp == 3) {
154                         membername= strstr(membername, "->") + strlen("->");
155                         return rna_find_sdna_member(sdna, sdna->types[sp[0]], membername, smember);
156                 }
157         }
158
159         return 0;
160 }
161
162 /* Blender Data Definition */
163
164 BlenderRNA *RNA_create()
165 {
166         BlenderRNA *brna;
167
168         brna= MEM_callocN(sizeof(BlenderRNA), "BlenderRNA");
169
170         DefRNA.sdna= DNA_sdna_from_data(DNAstr,  DNAlen, 0);
171         DefRNA.structs.first= DefRNA.structs.last= NULL;
172         DefRNA.error= 0;
173         DefRNA.preprocess= 1;
174
175         return brna;
176 }
177
178 void RNA_define_free(BlenderRNA *brna)
179 {
180         StructDefRNA *srna;
181         AllocDefRNA *alloc;
182
183         for(alloc=DefRNA.allocs.first; alloc; alloc=alloc->next)
184                 MEM_freeN(alloc->mem);
185         rna_freelistN(&DefRNA.allocs);
186
187         for(srna=DefRNA.structs.first; srna; srna=srna->next)
188                 rna_freelistN(&srna->properties);
189
190         rna_freelistN(&DefRNA.structs);
191
192         if(DefRNA.sdna) {
193                 DNA_sdna_free(DefRNA.sdna);
194                 DefRNA.sdna= NULL;
195         }
196
197         DefRNA.error= 0;
198 }
199
200 void RNA_free(BlenderRNA *brna)
201 {
202         StructRNA *srna, *nextsrna;
203         PropertyRNA *prop, *nextprop;
204
205         if(DefRNA.preprocess) {
206                 RNA_define_free(brna);
207
208                 for(srna=brna->structs.first; srna; srna=srna->next)
209                         rna_freelistN(&srna->properties);
210
211                 rna_freelistN(&brna->structs);
212                 
213                 MEM_freeN(brna);
214         }
215         else {
216                 for(srna=brna->structs.first; srna; srna=nextsrna) {
217                         nextsrna= srna->next;
218
219                         for(prop=srna->properties.first; prop; prop=nextprop) {
220                                 nextprop= prop->next;
221
222                                 if(prop->flag & PROP_RUNTIME)
223                                         rna_freelinkN(&srna->properties, prop);
224                         }
225
226                         if(srna->flag & STRUCT_RUNTIME)
227                                 rna_freelinkN(&brna->structs, srna);
228                 }
229         }
230 }
231
232 static size_t rna_property_type_sizeof(PropertyType type)
233 {
234         switch(type) {
235                 case PROP_BOOLEAN: return sizeof(BooleanPropertyRNA);
236                 case PROP_INT: return sizeof(IntPropertyRNA);
237                 case PROP_FLOAT: return sizeof(FloatPropertyRNA);
238                 case PROP_STRING: return sizeof(StringPropertyRNA);
239                 case PROP_ENUM: return sizeof(EnumPropertyRNA);
240                 case PROP_POINTER: return sizeof(PointerPropertyRNA);
241                 case PROP_COLLECTION: return sizeof(CollectionPropertyRNA);
242                 default: return 0;
243         }
244 }
245
246 /* Struct Definition */
247
248 StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from, const char *name)
249 {
250         StructRNA *srna, *srnafrom= NULL;
251         StructDefRNA *ds;
252         PropertyRNA *prop, *propfrom;
253
254         if(from) {
255                 /* find struct to derive from */
256                 for(srnafrom= brna->structs.first; srnafrom; srnafrom=srnafrom->next)
257                         if(strcmp(srnafrom->identifier, from) == 0)
258                                 break;
259
260                 if(!srnafrom) {
261                         fprintf(stderr, "RNA_def_struct: struct %s not found to define %s.\n", from, identifier);
262                         DefRNA.error= 1;
263                 }
264         }
265
266         srna= MEM_callocN(sizeof(StructRNA), "StructRNA");
267
268         /* copy from struct to derive stuff, a bit clumsy since we can't
269          * use MEM_dupallocN, data structs may not be alloced but builtin */
270         if(srnafrom) {
271                 memcpy(srna, srnafrom, sizeof(StructRNA));
272                 srna->properties.first= srna->properties.last= NULL;
273
274                 if(DefRNA.preprocess)
275                         srna->from= (StructRNA*)from;
276                 else
277                         srna->from= srnafrom;
278
279                 for(propfrom= srnafrom->properties.first; propfrom; propfrom=propfrom->next) {
280                         prop= RNA_def_property(srna, propfrom->identifier, propfrom->type, propfrom->subtype);
281
282                         rna_remlink(&srna->properties, prop);
283                         memcpy(prop, propfrom, rna_property_type_sizeof(propfrom->type));
284
285                         if(!DefRNA.preprocess)
286                                 prop->flag |= PROP_RUNTIME;
287
288                         prop->next= prop->prev= NULL;
289                         rna_addtail(&srna->properties, prop);
290
291                         if(propfrom == srnafrom->nameproperty)
292                                 srna->nameproperty= prop;
293                         if(propfrom == srnafrom->iteratorproperty)
294                                 srna->iteratorproperty= prop;
295                 }
296         }
297
298         srna->identifier= identifier;
299         srna->name= name;
300
301         if(DefRNA.preprocess) {
302                 ds= MEM_callocN(sizeof(StructDefRNA), "StructDefRNA");
303                 ds->srna= srna;
304                 rna_addtail(&DefRNA.structs, ds);
305         }
306
307         rna_addtail(&brna->structs, srna);
308
309         /* in preprocess, try to find sdna */
310         if(DefRNA.preprocess)
311                 RNA_def_struct_sdna(srna, srna->identifier);
312         else
313                 srna->flag |= STRUCT_RUNTIME;
314
315         /* define some builtin properties */
316         if(!srnafrom) {
317                 prop= RNA_def_property(srna, "rna_properties", PROP_COLLECTION, PROP_NONE);
318                 RNA_def_property_flag(prop, PROP_BUILTIN);
319                 RNA_def_property_ui_text(prop, "Properties", "RNA property collection.");
320
321                 if(DefRNA.preprocess) {
322                         RNA_def_property_struct_type(prop, "Property");
323                         RNA_def_property_collection_funcs(prop, "rna_builtin_properties_begin", "rna_builtin_properties_next", "rna_iterator_listbase_end", "rna_builtin_properties_get", 0, 0, 0, 0);
324                 }
325                 else {
326 #ifdef RNA_RUNTIME
327                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
328                         cprop->begin= rna_builtin_properties_begin;
329                         cprop->next= rna_builtin_properties_next;
330                         cprop->next= rna_iterator_listbase_end;
331                         cprop->get= rna_builtin_properties_get;
332                         cprop->structtype= &RNA_Property;
333 #endif
334                 }
335
336                 prop= RNA_def_property(srna, "rna_type", PROP_POINTER, PROP_NONE);
337                 RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
338                 RNA_def_property_ui_text(prop, "RNA", "RNA type definition.");
339
340                 if(DefRNA.preprocess) {
341                         RNA_def_property_struct_type(prop, "Struct");
342                         RNA_def_property_pointer_funcs(prop, "rna_builtin_type_get", NULL, NULL);
343                 }
344                 else {
345 #ifdef RNA_RUNTIME
346                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
347                         pprop->get= rna_builtin_type_get;
348                         pprop->structtype= &RNA_Struct;
349 #endif
350                 }
351         }
352
353         return srna;
354 }
355
356 void RNA_def_struct_sdna(StructRNA *srna, const char *structname)
357 {
358         StructDefRNA *ds= DefRNA.structs.last;
359
360         if(!DefRNA.preprocess) {
361                 fprintf(stderr, "RNA_def_struct_sdna: only during preprocessing.\n");
362                 return;
363         }
364
365         if(!DNA_struct_find_nr(DefRNA.sdna, structname)) {
366                 if(!DefRNA.silent) {
367                         fprintf(stderr, "RNA_def_struct_sdna: %s not found.\n", structname);
368                         DefRNA.error= 1;
369                 }
370                 return;
371         }
372
373         ds->dnaname= structname;
374 }
375
376 void RNA_def_struct_name_property(struct StructRNA *srna, struct PropertyRNA *prop)
377 {
378         if(prop->type != PROP_STRING) {
379                 fprintf(stderr, "RNA_def_struct_name_property: %s.%s, must be a string property.\n", srna->identifier, prop->identifier);
380                 DefRNA.error= 1;
381         }
382         else
383                 srna->nameproperty= prop;
384 }
385
386 void RNA_def_struct_flag(StructRNA *srna, int flag)
387 {
388         srna->flag= flag;
389 }
390
391 void RNA_def_struct_funcs(StructRNA *srna, const char *notify, const char *refine)
392 {
393         if(!DefRNA.preprocess) {
394                 fprintf(stderr, "RNA_def_struct_funcs: only during preprocessing.\n");
395                 return;
396         }
397
398         if(notify) srna->notify= (NotifyFunc)notify;
399         if(refine) srna->refine= (StructRefineFunc)refine;
400 }
401
402
403 void RNA_def_struct_identifier(StructRNA *srna, const char *identifier, const char *name)
404 {
405         if(DefRNA.preprocess) {
406                 fprintf(stderr, "RNA_def_struct_name_runtime: only at runtime.\n");
407                 return;
408         }
409
410         srna->identifier= identifier;
411         srna->name= name;
412 }
413
414 /* Property Definition */
415
416 PropertyRNA *RNA_def_property(StructRNA *srna, const char *identifier, int type, int subtype)
417 {
418         StructDefRNA *ds;
419         PropertyDefRNA *dp= NULL;
420         PropertyRNA *prop;
421
422         if(DefRNA.preprocess) {
423                 ds= DefRNA.structs.last;
424                 dp= MEM_callocN(sizeof(PropertyDefRNA), "PropertyDefRNA");
425                 rna_addtail(&ds->properties, dp);
426         }
427
428         prop= MEM_callocN(rna_property_type_sizeof(type), "PropertyRNA");
429
430         switch(type) {
431                 case PROP_BOOLEAN:
432                         break;
433                 case PROP_INT: {
434                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
435
436                         iprop->hardmin= (subtype == PROP_UNSIGNED)? 0: INT_MIN;
437                         iprop->hardmax= INT_MAX;
438
439                         iprop->softmin= (subtype == PROP_UNSIGNED)? 0: -10000; /* rather arbitrary .. */
440                         iprop->softmax= 10000;
441                         iprop->step= 1;
442                         break;
443                 }
444                 case PROP_FLOAT: {
445                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
446
447                         fprop->hardmin= (subtype == PROP_UNSIGNED)? 0.0f: -FLT_MAX;
448                         fprop->hardmax= FLT_MAX;
449
450                         fprop->softmin= (subtype == PROP_UNSIGNED)? 0.0f: -10000.0f; /* rather arbitrary .. */
451                         fprop->softmax= 10000.0f;
452                         fprop->step= 10;
453                         fprop->precision= 3;
454                         break;
455                 }
456                 case PROP_STRING: {
457                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
458
459                         sprop->defaultvalue= "";
460                         sprop->maxlength= 0;
461                         break;
462                 }
463                 case PROP_ENUM:
464                 case PROP_POINTER:
465                 case PROP_COLLECTION:
466                         break;
467                 default:
468                         fprintf(stderr, "RNA_def_property: %s.%s, invalid property type.\n", srna->identifier, identifier);
469                         DefRNA.error= 1;
470                         return NULL;
471         }
472
473         if(DefRNA.preprocess) {
474                 dp->srna= srna;
475                 dp->prop= prop;
476         }
477
478         prop->magic= RNA_MAGIC;
479         prop->identifier= identifier;
480         prop->type= type;
481         prop->subtype= subtype;
482         prop->name= identifier;
483         prop->description= "";
484
485         if(type == PROP_COLLECTION)
486                 prop->flag= PROP_NOT_EDITABLE|PROP_NOT_DRIVEABLE;
487         else if(type == PROP_POINTER)
488                 prop->flag= PROP_NOT_DRIVEABLE;
489
490         if(DefRNA.preprocess) {
491                 switch(type) {
492                         case PROP_BOOLEAN:
493                                 DefRNA.silent= 1;
494                                 RNA_def_property_boolean_sdna(prop, NULL, identifier, 0);
495                                 DefRNA.silent= 0;
496                                 break;
497                         case PROP_INT: {
498                                 DefRNA.silent= 1;
499                                 RNA_def_property_int_sdna(prop, NULL, identifier);
500                                 DefRNA.silent= 0;
501                                 break;
502                         }
503                         case PROP_FLOAT: {
504                                 DefRNA.silent= 1;
505                                 RNA_def_property_float_sdna(prop, NULL, identifier);
506                                 DefRNA.silent= 0;
507                                 break;
508                         }
509                         case PROP_STRING: {
510                                 DefRNA.silent= 1;
511                                 RNA_def_property_string_sdna(prop, NULL, identifier);
512                                 DefRNA.silent= 0;
513                                 break;
514                         }
515                         case PROP_ENUM:
516                                 DefRNA.silent= 1;
517                                 RNA_def_property_enum_sdna(prop, NULL, identifier);
518                                 DefRNA.silent= 0;
519                                 break;
520                         case PROP_POINTER:
521                                 DefRNA.silent= 1;
522                                 RNA_def_property_pointer_sdna(prop, NULL, identifier);
523                                 DefRNA.silent= 0;
524                                 break;
525                         case PROP_COLLECTION:
526                                 DefRNA.silent= 1;
527                                 RNA_def_property_collection_sdna(prop, NULL, identifier, NULL);
528                                 DefRNA.silent= 0;
529                                 break;
530                 }
531         }
532         else
533                 prop->flag |= PROP_IDPROPERTY|PROP_RUNTIME;
534
535         rna_addtail(&srna->properties, prop);
536
537         return prop;
538 }
539
540 void RNA_def_property_flag(PropertyRNA *prop, int flag)
541 {
542 #if 0
543         StructRNA *srna;
544 #endif
545
546         prop->flag |= flag;
547
548 #if 0
549         if(prop->type != PROP_POINTER && prop->type != PROP_COLLECTION) {
550                 if(flag & (PROP_EVALUATE_DEPENDENCY|PROP_INVERSE_EVALUATE_DEPENDENCY|PROP_RENDER_DEPENDENCY|PROP_INVERSE_RENDER_DEPENDENCY)) {
551                         fprintf(stderr, "RNA_def_property_flag: %s.%s, only pointer and collection types can create dependencies.\n", ds->srna->identifier, prop->identifier);
552                         DefRNA.error= 1;
553                 }
554         }
555 #endif
556 }
557
558 void RNA_def_property_array(PropertyRNA *prop, int arraylength)
559 {
560         StructRNA *srna;
561
562         switch(prop->type) {
563                 case PROP_BOOLEAN:
564                 case PROP_INT:
565                 case PROP_FLOAT:
566                         prop->arraylength= arraylength;
567                         break;
568                 default:
569                         fprintf(stderr, "RNA_def_property_array: %s.%s, only boolean/int/float can be array.\n", srna->identifier, prop->identifier);
570                         DefRNA.error= 1;
571                         break;
572         }
573 }
574
575 void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
576 {
577         prop->name= name;
578         prop->description= description;
579 }
580
581 void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
582 {
583         StructRNA *srna;
584
585         switch(prop->type) {
586                 case PROP_INT: {
587                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
588                         iprop->softmin= (int)min;
589                         iprop->softmax= (int)max;
590                         iprop->step= (int)step;
591                         break;
592                 }
593                 case PROP_FLOAT: {
594                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
595                         fprop->softmin= (float)min;
596                         fprop->softmax= (float)max;
597                         fprop->step= (float)step;
598                         fprop->precision= (int)precision;
599                         break;
600                 }
601                 default:
602                         fprintf(stderr, "RNA_def_property_ui_range: %s.%s, invalid type for ui range.\n", srna->identifier, prop->identifier);
603                         DefRNA.error= 1;
604                         break;
605         }
606 }
607
608 void RNA_def_property_range(PropertyRNA *prop, double min, double max)
609 {
610         StructRNA *srna;
611
612         switch(prop->type) {
613                 case PROP_INT: {
614                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
615                         iprop->hardmin= (int)min;
616                         iprop->hardmax= (int)max;
617                         iprop->softmin= MAX2((int)min, iprop->hardmin);
618                         iprop->softmax= MIN2((int)max, iprop->hardmax);
619                         break;
620                 }
621                 case PROP_FLOAT: {
622                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
623                         fprop->hardmin= (float)min;
624                         fprop->hardmax= (float)max;
625                         fprop->softmin= MAX2((float)min, fprop->hardmin);
626                         fprop->softmax= MIN2((float)max, fprop->hardmax);
627                         break;
628                 }
629                 default:
630                         fprintf(stderr, "RNA_def_property_range: %s.%s, invalid type for range.\n", srna->identifier, prop->identifier);
631                         DefRNA.error= 1;
632                         break;
633         }
634 }
635
636 void RNA_def_property_struct_type(PropertyRNA *prop, const char *type)
637 {
638         StructRNA *srna;
639
640         if(!DefRNA.preprocess) {
641                 fprintf(stderr, "RNA_def_property_struct_type: only during preprocessing.\n");
642                 return;
643         }
644
645         switch(prop->type) {
646                 case PROP_POINTER: {
647                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
648                         pprop->structtype = (StructRNA*)type;
649                         break;
650                 }
651                 case PROP_COLLECTION: {
652                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
653                         cprop->structtype = (StructRNA*)type;
654                         break;
655                 }
656                 default:
657                         fprintf(stderr, "RNA_def_property_struct_type: %s.%s, invalid type for struct type.\n", srna->identifier, prop->identifier);
658                         DefRNA.error= 1;
659                         break;
660         }
661 }
662
663 void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item)
664 {
665         StructRNA *srna;
666         int i;
667
668         switch(prop->type) {
669                 case PROP_ENUM: {
670                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
671                         eprop->item= item;
672                         eprop->totitem= 0;
673                         for(i=0; item[i].identifier; i++)
674                                 eprop->totitem++;
675
676                         break;
677                 }
678                 default:
679                         fprintf(stderr, "RNA_def_property_struct_type: %s.%s, invalid type for struct type.\n", srna->identifier, prop->identifier);
680                         DefRNA.error= 1;
681                         break;
682         }
683 }
684
685 void RNA_def_property_string_maxlength(PropertyRNA *prop, int maxlength)
686 {
687         StructRNA *srna;
688
689         switch(prop->type) {
690                 case PROP_STRING: {
691                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
692                         sprop->maxlength= maxlength;
693                         break;
694                 }
695                 default:
696                         fprintf(stderr, "RNA_def_property_string_maxlength: %s.%s, type is not string.\n", srna->identifier, prop->identifier);
697                         DefRNA.error= 1;
698                         break;
699         }
700 }
701
702 void RNA_def_property_boolean_default(PropertyRNA *prop, int value)
703 {
704         StructRNA *srna;
705
706         switch(prop->type) {
707                 case PROP_BOOLEAN: {
708                         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
709                         bprop->defaultvalue= value;
710                         break;
711                 }
712                 default:
713                         fprintf(stderr, "RNA_def_property_boolean_default: %s.%s, type is not boolean.\n", srna->identifier, prop->identifier);
714                         DefRNA.error= 1;
715                         break;
716         }
717 }
718
719 void RNA_def_property_boolean_array_default(PropertyRNA *prop, const int *array)
720 {
721         StructRNA *srna;
722
723         switch(prop->type) {
724                 case PROP_BOOLEAN: {
725                         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
726                         bprop->defaultarray= array;
727                         break;
728                 }
729                 default:
730                         fprintf(stderr, "RNA_def_property_boolean_default: %s.%s, type is not boolean.\n", srna->identifier, prop->identifier);
731                         DefRNA.error= 1;
732                         break;
733         }
734 }
735
736 void RNA_def_property_int_default(PropertyRNA *prop, int value)
737 {
738         StructRNA *srna;
739
740         switch(prop->type) {
741                 case PROP_INT: {
742                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
743                         iprop->defaultvalue= value;
744                         break;
745                 }
746                 default:
747                         fprintf(stderr, "RNA_def_property_int_default: %s.%s, type is not int.\n", srna->identifier, prop->identifier);
748                         DefRNA.error= 1;
749                         break;
750         }
751 }
752
753 void RNA_def_property_int_array_default(PropertyRNA *prop, const int *array)
754 {
755         StructRNA *srna;
756
757         switch(prop->type) {
758                 case PROP_INT: {
759                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
760                         iprop->defaultarray= array;
761                         break;
762                 }
763                 default:
764                         fprintf(stderr, "RNA_def_property_int_default: %s.%s, type is not int.\n", srna->identifier, prop->identifier);
765                         DefRNA.error= 1;
766                         break;
767         }
768 }
769
770 void RNA_def_property_float_default(PropertyRNA *prop, float value)
771 {
772         StructRNA *srna;
773
774         switch(prop->type) {
775                 case PROP_FLOAT: {
776                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
777                         fprop->defaultvalue= value;
778                         break;
779                 }
780                 default:
781                         fprintf(stderr, "RNA_def_property_float_default: %s.%s, type is not float.\n", srna->identifier, prop->identifier);
782                         DefRNA.error= 1;
783                         break;
784         }
785 }
786
787 void RNA_def_property_float_array_default(PropertyRNA *prop, const float *array)
788 {
789         StructRNA *srna;
790
791         switch(prop->type) {
792                 case PROP_FLOAT: {
793                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
794                         fprop->defaultarray= array;
795                         break;
796                 }
797                 default:
798                         fprintf(stderr, "RNA_def_property_float_default: %s.%s, type is not float.\n", srna->identifier, prop->identifier);
799                         DefRNA.error= 1;
800                         break;
801         }
802 }
803
804 void RNA_def_property_string_default(PropertyRNA *prop, const char *value)
805 {
806         StructRNA *srna;
807
808         switch(prop->type) {
809                 case PROP_STRING: {
810                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
811                         sprop->defaultvalue= value;
812                         break;
813                 }
814                 default:
815                         fprintf(stderr, "RNA_def_property_string_default: %s.%s, type is not string.\n", srna->identifier, prop->identifier);
816                         DefRNA.error= 1;
817                         break;
818         }
819 }
820
821 void RNA_def_property_enum_default(PropertyRNA *prop, int value)
822 {
823         StructRNA *srna;
824
825         switch(prop->type) {
826                 case PROP_ENUM: {
827                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
828                         eprop->defaultvalue= value;
829                         break;
830                 }
831                 default:
832                         fprintf(stderr, "RNA_def_property_enum_default: %s.%s, type is not enum.\n", srna->identifier, prop->identifier);
833                         DefRNA.error= 1;
834                         break;
835         }
836 }
837
838 /* SDNA */
839
840 static PropertyDefRNA *rna_def_property_sdna(PropertyRNA *prop, const char *structname, const char *propname)
841 {
842         DNAStructMember smember;
843         StructDefRNA *ds= DefRNA.structs.last;
844         PropertyDefRNA *dp= ds->properties.last;
845
846         if(!structname)
847                 structname= ds->dnaname;
848         if(!propname)
849                 propname= prop->identifier;
850
851         if(!rna_find_sdna_member(DefRNA.sdna, structname, propname, &smember)) {
852                 if(!DefRNA.silent) {
853                         fprintf(stderr, "rna_def_property_sdna: %s.%s not found.\n", structname, propname);
854                         DefRNA.error= 1;
855                 }
856                 return NULL;
857         }
858
859         if(smember.arraylength > 1)
860                 prop->arraylength= smember.arraylength;
861         else
862                 prop->arraylength= 0;
863         
864         dp->dnastructname= structname;
865         dp->dnaname= propname;
866         dp->dnatype= smember.type;
867         dp->dnaarraylength= smember.arraylength;
868
869         return dp;
870 }
871
872 void RNA_def_property_boolean_sdna(PropertyRNA *prop, const char *structname, const char *propname, int bit)
873 {
874         PropertyDefRNA *dp;
875         
876         if(!DefRNA.preprocess) {
877                 fprintf(stderr, "RNA_def_property_*_sdna: only during preprocessing.\n");
878                 return;
879         }
880
881         if((dp=rna_def_property_sdna(prop, structname, propname)))
882                 dp->booleanbit= bit;
883 }
884
885 void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const char *propname)
886 {
887         PropertyDefRNA *dp;
888         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
889         
890         if(!DefRNA.preprocess) {
891                 fprintf(stderr, "RNA_def_property_*_sdna: only during preprocessing.\n");
892                 return;
893         }
894
895         if((dp= rna_def_property_sdna(prop, structname, propname))) {
896                 /* SDNA doesn't pass us unsigned unfortunately .. */
897                 if(strcmp(dp->dnatype, "char") == 0) {
898                         iprop->hardmin= iprop->softmin= CHAR_MIN;
899                         iprop->hardmax= iprop->softmax= CHAR_MAX;
900                 }
901                 else if(strcmp(dp->dnatype, "short") == 0) {
902                         iprop->hardmin= iprop->softmin= SHRT_MIN;
903                         iprop->hardmax= iprop->softmax= SHRT_MAX;
904                 }
905                 else if(strcmp(dp->dnatype, "int") == 0) {
906                         iprop->hardmin= INT_MIN;
907                         iprop->hardmax= INT_MAX;
908
909                         iprop->softmin= -10000; /* rather arbitrary .. */
910                         iprop->softmax= 10000;
911                 }
912
913                 if(prop->subtype == PROP_UNSIGNED)
914                         iprop->hardmin= iprop->softmin= 0;
915         }
916 }
917
918 void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, const char *propname)
919 {
920         rna_def_property_sdna(prop, structname, propname);
921 }
922
923 void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const char *propname)
924 {
925         PropertyDefRNA *dp;
926         
927         if(!DefRNA.preprocess) {
928                 fprintf(stderr, "RNA_def_property_*_sdna: only during preprocessing.\n");
929                 return;
930         }
931
932         if((dp=rna_def_property_sdna(prop, structname, propname))) {
933                 if(prop->arraylength) {
934                         prop->arraylength= 0;
935                         if(!DefRNA.silent) {
936                                 fprintf(stderr, "RNA_def_property_enum_sdna: %s.%s, array not supported for enum type.\n", structname, propname);
937                                 DefRNA.error= 1;
938                         }
939                 }
940         }
941 }
942
943 void RNA_def_property_string_sdna(PropertyRNA *prop, const char *structname, const char *propname)
944 {
945         PropertyDefRNA *dp;
946         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
947
948         if(!DefRNA.preprocess) {
949                 fprintf(stderr, "RNA_def_property_*_sdna: only during preprocessing.\n");
950                 return;
951         }
952
953         if((dp=rna_def_property_sdna(prop, structname, propname))) {
954                 if(prop->arraylength) {
955                         sprop->maxlength= prop->arraylength;
956                         prop->arraylength= 0;
957                 }
958         }
959 }
960
961 void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, const char *propname)
962 {
963         PropertyDefRNA *dp;
964         
965         if(!DefRNA.preprocess) {
966                 fprintf(stderr, "RNA_def_property_*_sdna: only during preprocessing.\n");
967                 return;
968         }
969
970         if((dp=rna_def_property_sdna(prop, structname, propname))) {
971                 if(prop->arraylength) {
972                         prop->arraylength= 0;
973                         if(!DefRNA.silent) {
974                                 fprintf(stderr, "RNA_def_property_pointer_sdna: %s.%s, array not supported for pointer type.\n", structname, propname);
975                                 DefRNA.error= 1;
976                         }
977                 }
978         }
979 }
980
981 void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, const char *propname, const char *lengthpropname)
982 {
983         PropertyDefRNA *dp;
984         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
985
986         if(!DefRNA.preprocess) {
987                 fprintf(stderr, "RNA_def_property_*_sdna: only during preprocessing.\n");
988                 return;
989         }
990
991         if((dp=rna_def_property_sdna(prop, structname, propname))) {
992                 if(prop->arraylength) {
993                         prop->arraylength= 0;
994
995                         if(!DefRNA.silent) {
996                                 fprintf(stderr, "RNA_def_property_collection_sdna: %s.%s, array not supported for collection type.\n", structname, propname);
997                                 DefRNA.error= 1;
998                         }
999                 }
1000
1001                 if(strcmp(dp->dnatype, "ListBase") == 0) {
1002                         cprop->next= (PropCollectionNextFunc)"rna_iterator_listbase_next";
1003                         cprop->get= (PropCollectionGetFunc)"rna_iterator_listbase_get";
1004                         cprop->end= (PropCollectionEndFunc)"rna_iterator_listbase_end";
1005                 }
1006         }
1007
1008         if(dp && lengthpropname) {
1009                 DNAStructMember smember;
1010                 StructDefRNA *ds= DefRNA.structs.last;
1011
1012                 if(!structname)
1013                         structname= ds->dnaname;
1014
1015                 if(!rna_find_sdna_member(DefRNA.sdna, structname, lengthpropname, &smember)) {
1016                         if(!DefRNA.silent) {
1017                                 fprintf(stderr, "RNA_def_property_collection_sdna: %s.%s not found.\n", structname, lengthpropname);
1018                                 DefRNA.error= 1;
1019                         }
1020                 }
1021                 else {
1022                         dp->dnalengthstructname= structname;
1023                         dp->dnalengthname= lengthpropname;
1024
1025                         cprop->next= (PropCollectionNextFunc)"rna_iterator_array_next";
1026                         cprop->get= (PropCollectionGetFunc)"rna_iterator_array_get";
1027                         cprop->end= (PropCollectionEndFunc)"rna_iterator_array_end";
1028                 }
1029         }
1030 }
1031
1032 /* Functions */
1033
1034 void RNA_def_property_funcs(PropertyRNA *prop, const char *notify)
1035 {
1036         if(!DefRNA.preprocess) {
1037                 fprintf(stderr, "RNA_def_property_funcs: only during preprocessing.\n");
1038                 return;
1039         }
1040
1041         if(notify) prop->notify= (NotifyFunc)notify;
1042 }
1043
1044 void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set)
1045 {
1046         StructRNA *srna;
1047
1048         if(!DefRNA.preprocess) {
1049                 fprintf(stderr, "RNA_def_property_*_funcs: only during preprocessing.\n");
1050                 return;
1051         }
1052
1053         switch(prop->type) {
1054                 case PROP_BOOLEAN: {
1055                         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
1056
1057                         if(prop->arraylength) {
1058                                 if(get) bprop->getarray= (PropBooleanArrayGetFunc)get;
1059                                 if(set) bprop->setarray= (PropBooleanArraySetFunc)set;
1060                         }
1061                         else {
1062                                 if(get) bprop->get= (PropBooleanGetFunc)get;
1063                                 if(set) bprop->set= (PropBooleanSetFunc)set;
1064                         }
1065                         break;
1066                 }
1067                 default:
1068                         fprintf(stderr, "RNA_def_property_boolean_funcs: %s.%s, type is not boolean.\n", srna->identifier, prop->identifier);
1069                         DefRNA.error= 1;
1070                         break;
1071         }
1072 }
1073
1074 void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set)
1075 {
1076         StructRNA *srna;
1077
1078         if(!DefRNA.preprocess) {
1079                 fprintf(stderr, "RNA_def_property_*_funcs: only during preprocessing.\n");
1080                 return;
1081         }
1082
1083         switch(prop->type) {
1084                 case PROP_INT: {
1085                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
1086
1087                         if(prop->arraylength) {
1088                                 if(get) iprop->getarray= (PropIntArrayGetFunc)get;
1089                                 if(set) iprop->setarray= (PropIntArraySetFunc)set;
1090                         }
1091                         else {
1092                                 if(get) iprop->get= (PropIntGetFunc)get;
1093                                 if(set) iprop->set= (PropIntSetFunc)set;
1094                         }
1095                         break;
1096                 }
1097                 default:
1098                         fprintf(stderr, "RNA_def_property_int_funcs: %s.%s, type is not int.\n", srna->identifier, prop->identifier);
1099                         DefRNA.error= 1;
1100                         break;
1101         }
1102 }
1103
1104 void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char *set)
1105 {
1106         StructRNA *srna;
1107
1108         if(!DefRNA.preprocess) {
1109                 fprintf(stderr, "RNA_def_property_*_funcs: only during preprocessing.\n");
1110                 return;
1111         }
1112
1113         switch(prop->type) {
1114                 case PROP_FLOAT: {
1115                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1116
1117                         if(prop->arraylength) {
1118                                 if(get) fprop->getarray= (PropFloatArrayGetFunc)get;
1119                                 if(set) fprop->setarray= (PropFloatArraySetFunc)set;
1120                         }
1121                         else {
1122                                 if(get) fprop->get= (PropFloatGetFunc)get;
1123                                 if(set) fprop->set= (PropFloatSetFunc)set;
1124                         }
1125                         break;
1126                 }
1127                 default:
1128                         fprintf(stderr, "RNA_def_property_float_funcs: %s.%s, type is not float.\n", srna->identifier, prop->identifier);
1129                         DefRNA.error= 1;
1130                         break;
1131         }
1132 }
1133
1134 void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set)
1135 {
1136         StructRNA *srna;
1137
1138         if(!DefRNA.preprocess) {
1139                 fprintf(stderr, "RNA_def_property_*_funcs: only during preprocessing.\n");
1140                 return;
1141         }
1142
1143         switch(prop->type) {
1144                 case PROP_ENUM: {
1145                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
1146
1147                         if(get) eprop->get= (PropEnumGetFunc)get;
1148                         if(set) eprop->set= (PropEnumSetFunc)set;
1149                         break;
1150                 }
1151                 default:
1152                         fprintf(stderr, "RNA_def_property_enum_funcs: %s.%s, type is not enum.\n", srna->identifier, prop->identifier);
1153                         DefRNA.error= 1;
1154                         break;
1155         }
1156 }
1157
1158 void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set)
1159 {
1160         StructRNA *srna;
1161
1162         if(!DefRNA.preprocess) {
1163                 fprintf(stderr, "RNA_def_property_*_funcs: only during preprocessing.\n");
1164                 return;
1165         }
1166
1167         switch(prop->type) {
1168                 case PROP_STRING: {
1169                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1170
1171                         if(get) sprop->get= (PropStringGetFunc)get;
1172                         if(length) sprop->length= (PropStringLengthFunc)length;
1173                         if(set) sprop->set= (PropStringSetFunc)set;
1174                         break;
1175                 }
1176                 default:
1177                         fprintf(stderr, "RNA_def_property_string_funcs: %s.%s, type is not string.\n", srna->identifier, prop->identifier);
1178                         DefRNA.error= 1;
1179                         break;
1180         }
1181 }
1182
1183 void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *type, const char *set)
1184 {
1185         StructRNA *srna;
1186
1187         if(!DefRNA.preprocess) {
1188                 fprintf(stderr, "RNA_def_property_*_funcs: only during preprocessing.\n");
1189                 return;
1190         }
1191
1192         switch(prop->type) {
1193                 case PROP_POINTER: {
1194                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
1195
1196                         if(get) pprop->get= (PropPointerGetFunc)get;
1197                         if(type) pprop->type= (PropPointerTypeFunc)type;
1198                         if(set) pprop->set= (PropPointerSetFunc)set;
1199                         break;
1200                 }
1201                 default:
1202                         fprintf(stderr, "RNA_def_property_pointer_funcs: %s.%s, type is not pointer.\n", srna->identifier, prop->identifier);
1203                         DefRNA.error= 1;
1204                         break;
1205         }
1206 }
1207
1208 void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end, const char *get, const char *type, const char *length, const char *lookupint, const char *lookupstring)
1209 {
1210         StructRNA *srna;
1211
1212         if(!DefRNA.preprocess) {
1213                 fprintf(stderr, "RNA_def_property_*_funcs: only during preprocessing.\n");
1214                 return;
1215         }
1216
1217         switch(prop->type) {
1218                 case PROP_COLLECTION: {
1219                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1220
1221                         if(begin) cprop->begin= (PropCollectionBeginFunc)begin;
1222                         if(next) cprop->next= (PropCollectionNextFunc)next;
1223                         if(end) cprop->end= (PropCollectionEndFunc)end;
1224                         if(get) cprop->get= (PropCollectionGetFunc)get;
1225                         if(type) cprop->type= (PropCollectionTypeFunc)type;
1226                         if(length) cprop->length= (PropCollectionLengthFunc)length;
1227                         if(lookupint) cprop->lookupint= (PropCollectionLookupIntFunc)lookupint;
1228                         if(lookupstring) cprop->lookupstring= (PropCollectionLookupStringFunc)lookupstring;
1229                         break;
1230                 }
1231                 default:
1232                         fprintf(stderr, "RNA_def_property_collection_funcs: %s.%s, type is not collection.\n", srna->identifier, prop->identifier);
1233                         DefRNA.error= 1;
1234                         break;
1235         }
1236 }
1237