RNA
[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
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;
45
46 /* Duplicated code since we can't link in blenkernel or blenlib */
47
48 #define MIN2(x,y) ((x)<(y)? (x): (y))
49 #define MAX2(x,y) ((x)>(y)? (x): (y))
50
51 void rna_addtail(ListBase *listbase, void *vlink)
52 {
53         Link *link= vlink;
54
55         link->next = NULL;
56         link->prev = listbase->last;
57
58         if (listbase->last) ((Link *)listbase->last)->next = link;
59         if (listbase->first == 0) listbase->first = link;
60         listbase->last = link;
61 }
62
63 void rna_freelistN(ListBase *listbase)
64 {
65         Link *link, *next;
66         
67         for(link=listbase->first; link; link=next) {
68                 next= link->next;
69                 MEM_freeN(link);
70         }
71         
72         listbase->first= listbase->last= NULL;
73 }
74
75 /* DNA utility function for looking up members */
76
77 typedef struct DNAStructMember {
78         char *type;
79         char *name;
80         int arraylength;
81 } DNAStructMember;
82
83 static int rna_member_cmp(const char *name, const char *oname)
84 {
85         int a=0;
86         
87         /* compare without pointer or array part */
88         while(name[0]=='*')
89                 name++;
90         while(oname[0]=='*')
91                 oname++;
92         
93         while(1) {
94                 if(name[a]=='[' && oname[a]==0) return 1;
95                 if(name[a]==0) break;
96                 if(name[a] != oname[a]) return 0;
97                 a++;
98         }
99         if(name[a]==0 && oname[a] == '.') return 2;
100         if(name[a]==0 && oname[a] == '-' && oname[a+1] == '>') return 3;
101
102         return (name[a] == oname[a]);
103 }
104
105 static int rna_find_sdna_member(SDNA *sdna, const char *structname, const char *membername, DNAStructMember *smember)
106 {
107         char *dnaname;
108         short *sp;
109         int a, structnr, totmember, cmp;
110
111         structnr= DNA_struct_find_nr(sdna, structname);
112         if(structnr == -1)
113                 return 0;
114
115         sp= sdna->structs[structnr];
116         totmember= sp[1];
117         sp+= 2;
118
119         for(a=0; a<totmember; a++, sp+=2) {
120                 dnaname= sdna->names[sp[1]];
121
122                 cmp= rna_member_cmp(dnaname, membername);
123
124                 if(cmp == 1) {
125                         smember->type= sdna->types[sp[0]];
126                         smember->name= dnaname;
127                         smember->arraylength= DNA_elem_array_size(smember->name, strlen(smember->name));
128                         return 1;
129                 }
130                 else if(cmp == 2) {
131                         membername= strstr(membername, ".") + strlen(".");
132                         return rna_find_sdna_member(sdna, sdna->types[sp[0]], membername, smember);
133                 }
134                 else if(cmp == 3) {
135                         membername= strstr(membername, "->") + strlen("->");
136                         return rna_find_sdna_member(sdna, sdna->types[sp[0]], membername, smember);
137                 }
138         }
139
140         return 0;
141 }
142
143 /* Blender Data Definition */
144
145 BlenderRNA *RNA_create()
146 {
147         BlenderRNA *brna;
148
149         brna= MEM_callocN(sizeof(BlenderRNA), "BlenderRNA");
150
151         DefRNA.sdna= DNA_sdna_from_data(DNAstr,  DNAlen, 0);
152         DefRNA.structs.first= DefRNA.structs.last= NULL;
153         DefRNA.error= 0;
154
155         return brna;
156 }
157
158 void RNA_define_free(BlenderRNA *brna)
159 {
160         StructDefRNA *srna;
161         AllocDefRNA *alloc;
162
163         for(alloc=DefRNA.allocs.first; alloc; alloc=alloc->next)
164                 MEM_freeN(alloc->mem);
165         rna_freelistN(&DefRNA.allocs);
166
167         for(srna=DefRNA.structs.first; srna; srna=srna->next)
168                 rna_freelistN(&srna->properties);
169
170         rna_freelistN(&DefRNA.structs);
171
172         if(DefRNA.sdna) {
173                 DNA_sdna_free(DefRNA.sdna);
174                 DefRNA.sdna= NULL;
175         }
176
177         DefRNA.error= 0;
178 }
179
180 void RNA_free(BlenderRNA *brna)
181 {
182         StructRNA *srna;
183
184         RNA_define_free(brna);
185
186         for(srna=brna->structs.first; srna; srna=srna->next)
187                 rna_freelistN(&srna->properties);
188
189         rna_freelistN(&brna->structs);
190         
191         MEM_freeN(brna);
192 }
193
194 /* Struct Definition */
195
196 StructRNA *RNA_def_struct(BlenderRNA *brna, const char *cname, const char *name)
197 {
198         StructRNA *srna;
199         StructDefRNA *ds;
200
201         ds= MEM_callocN(sizeof(StructDefRNA), "StructDefRNA");
202         rna_addtail(&DefRNA.structs, ds);
203
204         srna= MEM_callocN(sizeof(StructRNA), "StructRNA");
205         srna->cname= cname;
206         srna->name= name;
207
208         ds->srna= srna;
209
210         rna_addtail(&brna->structs, srna);
211
212         RNA_def_struct_sdna(srna, srna->cname);
213
214         return srna;
215 }
216
217 void RNA_def_struct_sdna(StructRNA *srna, const char *structname)
218 {
219         StructDefRNA *ds= DefRNA.structs.last;
220
221         if(!DNA_struct_find_nr(DefRNA.sdna, structname)) {
222                 if(!DefRNA.silent) {
223                         fprintf(stderr, "RNA_def_struct_sdna: %s not found.\n", structname);
224                         DefRNA.error= 1;
225                 }
226                 return;
227         }
228
229         ds->dnaname= structname;
230 }
231
232 void RNA_def_struct_name_property(struct StructRNA *srna, struct PropertyRNA *prop)
233 {
234         if(prop->type != PROP_STRING) {
235                 fprintf(stderr, "RNA_def_struct_name_property: %s.%s, must be a string property.\n", srna->cname, prop->cname);
236                 DefRNA.error= 1;
237         }
238         else
239                 srna->nameproperty= prop;
240 }
241
242 void RNA_def_struct_flag(StructRNA *srna, int flag)
243 {
244         srna->flag= flag;
245 }
246
247 /* Property Definition */
248
249 PropertyRNA *RNA_def_property(StructRNA *srna, const char *cname, int type, int subtype)
250 {
251         StructDefRNA *ds;
252         PropertyDefRNA *dp;
253         PropertyRNA *prop;
254
255         ds= DefRNA.structs.last;
256         dp= MEM_callocN(sizeof(PropertyDefRNA), "PropertyDefRNA");
257         rna_addtail(&ds->properties, dp);
258
259         switch(type) {
260                 case PROP_BOOLEAN:
261                         prop= MEM_callocN(sizeof(BooleanPropertyRNA), "BooleanPropertyRNA");
262                         break;
263                 case PROP_INT: {
264                         IntPropertyRNA *iprop;
265                         iprop= MEM_callocN(sizeof(IntPropertyRNA), "IntPropertyRNA");
266                         prop= &iprop->property;
267
268                         iprop->hardmin= (subtype == PROP_UNSIGNED)? 0: INT_MIN;
269                         iprop->hardmax= INT_MAX;
270
271                         iprop->softmin= (subtype == PROP_UNSIGNED)? 0: -10000; /* rather arbitrary .. */
272                         iprop->softmax= 10000;
273                         break;
274                 }
275                 case PROP_FLOAT: {
276                         FloatPropertyRNA *fprop;
277                         fprop= MEM_callocN(sizeof(FloatPropertyRNA), "FloatPropertyRNA");
278                         prop= &fprop->property;
279
280                         fprop->hardmin= (subtype == PROP_UNSIGNED)? 0.0f: -FLT_MAX;
281                         fprop->hardmax= FLT_MAX;
282
283                         fprop->softmin= (subtype == PROP_UNSIGNED)? 0.0f: -10000.0f; /* rather arbitrary .. */
284                         fprop->softmax= 10000.0f;
285                         break;
286                 }
287                 case PROP_STRING: {
288                         StringPropertyRNA *sprop;
289                         sprop= MEM_callocN(sizeof(StringPropertyRNA), "StringPropertyRNA");
290                         prop= &sprop->property;
291
292                         sprop->defaultvalue= "";
293                         sprop->maxlength= 0;
294                         break;
295                 }
296                 case PROP_ENUM:
297                         prop= MEM_callocN(sizeof(EnumPropertyRNA), "EnumPropertyRNA");
298                         break;
299                 case PROP_POINTER:
300                         prop= MEM_callocN(sizeof(PointerPropertyRNA), "PointerPropertyRNA");
301                         break;
302                 case PROP_COLLECTION:
303                         prop= MEM_callocN(sizeof(CollectionPropertyRNA), "CollectionPropertyRNA");
304                         break;
305                 default:
306                         fprintf(stderr, "RNA_def_property: %s.%s, invalid property type.\n", ds->srna->cname, cname);
307                         DefRNA.error= 1;
308                         return NULL;
309         }
310
311         dp->srna= srna;
312         dp->prop= prop;
313
314         prop->cname= cname;
315         prop->type= type;
316         prop->subtype= subtype;
317         prop->name= cname;
318         prop->description= "";
319
320         if(type == PROP_COLLECTION)
321                 prop->flag= 0;
322         else if(type == PROP_POINTER)
323                 prop->flag= PROP_EDITABLE;
324         else
325                 prop->flag= PROP_EDITABLE|PROP_DRIVEABLE;
326
327         switch(type) {
328                 case PROP_BOOLEAN:
329                         DefRNA.silent= 1;
330                         RNA_def_property_boolean_sdna(prop, srna->cname, cname, 0);
331                         DefRNA.silent= 0;
332                         break;
333                 case PROP_INT: {
334                         DefRNA.silent= 1;
335                         RNA_def_property_int_sdna(prop, srna->cname, cname);
336                         DefRNA.silent= 0;
337                         break;
338                 }
339                 case PROP_FLOAT: {
340                         DefRNA.silent= 1;
341                         RNA_def_property_float_sdna(prop, srna->cname, cname);
342                         DefRNA.silent= 0;
343                         break;
344                 }
345                 case PROP_STRING: {
346                         DefRNA.silent= 1;
347                         RNA_def_property_string_sdna(prop, srna->cname, cname);
348                         DefRNA.silent= 0;
349                         break;
350                 }
351                 case PROP_ENUM:
352                         DefRNA.silent= 1;
353                         RNA_def_property_enum_sdna(prop, srna->cname, cname);
354                         DefRNA.silent= 0;
355                         break;
356                 case PROP_POINTER:
357                         DefRNA.silent= 1;
358                         RNA_def_property_pointer_sdna(prop, srna->cname, cname);
359                         DefRNA.silent= 0;
360                         break;
361                 case PROP_COLLECTION:
362                         DefRNA.silent= 1;
363                         RNA_def_property_collection_sdna(prop, srna->cname, cname, NULL);
364                         DefRNA.silent= 0;
365                         break;
366         }
367
368         rna_addtail(&srna->properties, prop);
369
370         return prop;
371 }
372
373 void RNA_def_property_flag(PropertyRNA *prop, int flag)
374 {
375         StructDefRNA *ds= DefRNA.structs.last;
376
377         prop->flag= flag;
378
379         if(prop->type != PROP_POINTER && prop->type != PROP_COLLECTION) {
380                 if(flag & (PROP_EVALUATE_DEPENDENCY|PROP_INVERSE_EVALUATE_DEPENDENCY|PROP_RENDER_DEPENDENCY|PROP_INVERSE_RENDER_DEPENDENCY)) {
381                         fprintf(stderr, "RNA_def_property_flag: %s.%s, only pointer and collection types can create dependencies.\n", ds->srna->cname, prop->cname);
382                         DefRNA.error= 1;
383                 }
384         }
385 }
386
387 void RNA_def_property_array(PropertyRNA *prop, int arraylength)
388 {
389         StructDefRNA *ds= DefRNA.structs.last;
390
391         switch(prop->type) {
392                 case PROP_BOOLEAN:
393                 case PROP_INT:
394                 case PROP_FLOAT:
395                         prop->arraylength= arraylength;
396                         break;
397                 default:
398                         fprintf(stderr, "RNA_def_property_array: %s.%s, only boolean/int/float can be array.\n", ds->srna->cname, prop->cname);
399                         DefRNA.error= 1;
400                         break;
401         }
402 }
403
404 void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
405 {
406         prop->name= name;
407         prop->description= description;
408 }
409
410 void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, double precision)
411 {
412         StructDefRNA *ds= DefRNA.structs.last;
413
414         switch(prop->type) {
415                 case PROP_INT: {
416                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
417                         iprop->softmin= (int)min;
418                         iprop->softmax= (int)max;
419                         iprop->step= (int)step;
420                         break;
421                 }
422                 case PROP_FLOAT: {
423                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
424                         fprop->softmin= (float)min;
425                         fprop->softmax= (float)max;
426                         fprop->step= (float)step;
427                         fprop->precision= (float)precision;
428                         break;
429                 }
430                 default:
431                         fprintf(stderr, "RNA_def_property_ui_range: %s.%s, invalid type for ui range.\n", ds->srna->cname, prop->cname);
432                         DefRNA.error= 1;
433                         break;
434         }
435 }
436
437 void RNA_def_property_range(PropertyRNA *prop, double min, double max)
438 {
439         StructDefRNA *ds= DefRNA.structs.last;
440
441         switch(prop->type) {
442                 case PROP_INT: {
443                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
444                         iprop->hardmin= (int)min;
445                         iprop->hardmax= (int)max;
446                         iprop->softmin= MAX2((int)min, iprop->hardmin);
447                         iprop->softmax= MIN2((int)max, iprop->hardmax);
448                         break;
449                 }
450                 case PROP_FLOAT: {
451                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
452                         fprop->hardmin= (float)min;
453                         fprop->hardmax= (float)max;
454                         fprop->softmin= MAX2((float)min, fprop->hardmin);
455                         fprop->softmax= MIN2((float)max, fprop->hardmax);
456                         break;
457                 }
458                 default:
459                         fprintf(stderr, "RNA_def_property_range: %s.%s, invalid type for range.\n", ds->srna->cname, prop->cname);
460                         DefRNA.error= 1;
461                         break;
462         }
463 }
464
465 void RNA_def_property_struct_type(PropertyRNA *prop, const char *type)
466 {
467         StructDefRNA *ds= DefRNA.structs.last;
468
469         switch(prop->type) {
470                 case PROP_POINTER: {
471                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
472                         pprop->structtype = (StructRNA*)type;
473                         break;
474                 }
475                 case PROP_COLLECTION: {
476                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
477                         cprop->structtype = (StructRNA*)type;
478                         break;
479                 }
480                 default:
481                         fprintf(stderr, "RNA_def_property_struct_type: %s.%s, invalid type for struct type.\n", ds->srna->cname, prop->cname);
482                         DefRNA.error= 1;
483                         break;
484         }
485 }
486
487 void RNA_def_property_enum_items(PropertyRNA *prop, const PropertyEnumItem *item)
488 {
489         StructDefRNA *ds= DefRNA.structs.last;
490         int i;
491
492         switch(prop->type) {
493                 case PROP_ENUM: {
494                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
495                         eprop->item= item;
496                         eprop->totitem= 0;
497                         for(i=0; item[i].cname; i++)
498                                 eprop->totitem++;
499
500                         break;
501                 }
502                 default:
503                         fprintf(stderr, "RNA_def_property_struct_type: %s.%s, invalid type for struct type.\n", ds->srna->cname, prop->cname);
504                         DefRNA.error= 1;
505                         break;
506         }
507 }
508
509 void RNA_def_property_string_maxlength(PropertyRNA *prop, int maxlength)
510 {
511         StructDefRNA *ds= DefRNA.structs.last;
512
513         switch(prop->type) {
514                 case PROP_STRING: {
515                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
516                         sprop->maxlength= maxlength;
517                         break;
518                 }
519                 default:
520                         fprintf(stderr, "RNA_def_property_string_maxlength: %s.%s, type is not string.\n", ds->srna->cname, prop->cname);
521                         DefRNA.error= 1;
522                         break;
523         }
524 }
525
526 void RNA_def_property_boolean_default(PropertyRNA *prop, int value)
527 {
528         StructDefRNA *ds= DefRNA.structs.last;
529
530         switch(prop->type) {
531                 case PROP_BOOLEAN: {
532                         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
533                         bprop->defaultvalue= value;
534                         break;
535                 }
536                 default:
537                         fprintf(stderr, "RNA_def_property_boolean_default: %s.%s, type is not boolean.\n", ds->srna->cname, prop->cname);
538                         DefRNA.error= 1;
539                         break;
540         }
541 }
542
543 void RNA_def_property_boolean_array_default(PropertyRNA *prop, const int *array)
544 {
545         StructDefRNA *ds= DefRNA.structs.last;
546
547         switch(prop->type) {
548                 case PROP_BOOLEAN: {
549                         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
550                         bprop->defaultarray= array;
551                         break;
552                 }
553                 default:
554                         fprintf(stderr, "RNA_def_property_boolean_default: %s.%s, type is not boolean.\n", ds->srna->cname, prop->cname);
555                         DefRNA.error= 1;
556                         break;
557         }
558 }
559
560 void RNA_def_property_int_default(PropertyRNA *prop, int value)
561 {
562         StructDefRNA *ds= DefRNA.structs.last;
563
564         switch(prop->type) {
565                 case PROP_INT: {
566                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
567                         iprop->defaultvalue= value;
568                         break;
569                 }
570                 default:
571                         fprintf(stderr, "RNA_def_property_int_default: %s.%s, type is not int.\n", ds->srna->cname, prop->cname);
572                         DefRNA.error= 1;
573                         break;
574         }
575 }
576
577 void RNA_def_property_int_array_default(PropertyRNA *prop, const int *array)
578 {
579         StructDefRNA *ds= DefRNA.structs.last;
580
581         switch(prop->type) {
582                 case PROP_INT: {
583                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
584                         iprop->defaultarray= array;
585                         break;
586                 }
587                 default:
588                         fprintf(stderr, "RNA_def_property_int_default: %s.%s, type is not int.\n", ds->srna->cname, prop->cname);
589                         DefRNA.error= 1;
590                         break;
591         }
592 }
593
594 void RNA_def_property_float_default(PropertyRNA *prop, float value)
595 {
596         StructDefRNA *ds= DefRNA.structs.last;
597
598         switch(prop->type) {
599                 case PROP_FLOAT: {
600                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
601                         fprop->defaultvalue= value;
602                         break;
603                 }
604                 default:
605                         fprintf(stderr, "RNA_def_property_float_default: %s.%s, type is not float.\n", ds->srna->cname, prop->cname);
606                         DefRNA.error= 1;
607                         break;
608         }
609 }
610
611 void RNA_def_property_float_array_default(PropertyRNA *prop, const float *array)
612 {
613         StructDefRNA *ds= DefRNA.structs.last;
614
615         switch(prop->type) {
616                 case PROP_FLOAT: {
617                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
618                         fprop->defaultarray= array;
619                         break;
620                 }
621                 default:
622                         fprintf(stderr, "RNA_def_property_float_default: %s.%s, type is not float.\n", ds->srna->cname, prop->cname);
623                         DefRNA.error= 1;
624                         break;
625         }
626 }
627
628 void RNA_def_property_string_default(PropertyRNA *prop, const char *value)
629 {
630         StructDefRNA *ds= DefRNA.structs.last;
631
632         switch(prop->type) {
633                 case PROP_STRING: {
634                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
635                         sprop->defaultvalue= value;
636                         break;
637                 }
638                 default:
639                         fprintf(stderr, "RNA_def_property_string_default: %s.%s, type is not string.\n", ds->srna->cname, prop->cname);
640                         DefRNA.error= 1;
641                         break;
642         }
643 }
644
645 void RNA_def_property_enum_default(PropertyRNA *prop, int value)
646 {
647         StructDefRNA *ds= DefRNA.structs.last;
648
649         switch(prop->type) {
650                 case PROP_ENUM: {
651                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
652                         eprop->defaultvalue= value;
653                         break;
654                 }
655                 default:
656                         fprintf(stderr, "RNA_def_property_enum_default: %s.%s, type is not enum.\n", ds->srna->cname, prop->cname);
657                         DefRNA.error= 1;
658                         break;
659         }
660 }
661
662 /* SDNA */
663
664 static PropertyDefRNA *rna_def_property_sdna(PropertyRNA *prop, const char *structname, const char *propname)
665 {
666         DNAStructMember smember;
667         StructDefRNA *ds= DefRNA.structs.last;
668         PropertyDefRNA *dp= ds->properties.last;
669
670         if(!structname)
671                 structname= ds->dnaname;
672         if(!propname)
673                 propname= prop->cname;
674
675         if(!rna_find_sdna_member(DefRNA.sdna, structname, propname, &smember)) {
676                 if(!DefRNA.silent) {
677                         fprintf(stderr, "rna_def_property_sdna: %s.%s not found.\n", structname, propname);
678                         DefRNA.error= 1;
679                 }
680                 return NULL;
681         }
682
683         if(smember.arraylength > 1)
684                 prop->arraylength= smember.arraylength;
685         else
686                 prop->arraylength= 0;
687         
688         dp->dnastructname= structname;
689         dp->dnaname= propname;
690         dp->dnatype= smember.type;
691         dp->dnaarraylength= smember.arraylength;
692
693         return dp;
694 }
695
696 void RNA_def_property_boolean_sdna(PropertyRNA *prop, const char *structname, const char *propname, int bit)
697 {
698         PropertyDefRNA *dp;
699         
700         if((dp=rna_def_property_sdna(prop, structname, propname)))
701                 dp->booleanbit= bit;
702 }
703
704 void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const char *propname)
705 {
706         PropertyDefRNA *dp;
707         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
708         
709         if((dp= rna_def_property_sdna(prop, structname, propname))) {
710                 /* SDNA doesn't pass us unsigned unfortunately .. */
711                 if(strcmp(dp->dnatype, "char") == 0) {
712                         iprop->hardmin= iprop->softmin= CHAR_MIN;
713                         iprop->hardmax= iprop->softmax= CHAR_MAX;
714                 }
715                 else if(strcmp(dp->dnatype, "short") == 0) {
716                         iprop->hardmin= iprop->softmin= SHRT_MIN;
717                         iprop->hardmax= iprop->softmax= SHRT_MAX;
718                 }
719                 else if(strcmp(dp->dnatype, "int") == 0) {
720                         iprop->hardmin= INT_MIN;
721                         iprop->hardmax= INT_MAX;
722
723                         iprop->softmin= -10000; /* rather arbitrary .. */
724                         iprop->softmax= 10000;
725                 }
726
727                 if(prop->subtype == PROP_UNSIGNED)
728                         iprop->hardmin= iprop->softmin= 0;
729         }
730 }
731
732 void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, const char *propname)
733 {
734         rna_def_property_sdna(prop, structname, propname);
735 }
736
737 void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const char *propname)
738 {
739         PropertyDefRNA *dp;
740         
741         if((dp=rna_def_property_sdna(prop, structname, propname))) {
742                 if(prop->arraylength) {
743                         prop->arraylength= 0;
744                         if(!DefRNA.silent) {
745                                 fprintf(stderr, "RNA_def_property_enum_sdna: %s.%s, array not supported for enum type.\n", structname, propname);
746                                 DefRNA.error= 1;
747                         }
748                 }
749         }
750 }
751
752 void RNA_def_property_string_sdna(PropertyRNA *prop, const char *structname, const char *propname)
753 {
754         PropertyDefRNA *dp;
755         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
756
757         if((dp=rna_def_property_sdna(prop, structname, propname))) {
758                 if(prop->arraylength) {
759                         sprop->maxlength= prop->arraylength;
760                         prop->arraylength= 0;
761                 }
762         }
763 }
764
765 void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, const char *propname)
766 {
767         PropertyDefRNA *dp;
768         
769         if((dp=rna_def_property_sdna(prop, structname, propname))) {
770                 if(prop->arraylength) {
771                         prop->arraylength= 0;
772                         if(!DefRNA.silent) {
773                                 fprintf(stderr, "RNA_def_property_pointer_sdna: %s.%s, array not supported for pointer type.\n", structname, propname);
774                                 DefRNA.error= 1;
775                         }
776                 }
777         }
778 }
779
780 void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, const char *propname, const char *lengthpropname)
781 {
782         PropertyDefRNA *dp;
783         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
784         
785         if((dp=rna_def_property_sdna(prop, structname, propname))) {
786                 if(prop->arraylength) {
787                         prop->arraylength= 0;
788
789                         if(!DefRNA.silent) {
790                                 fprintf(stderr, "RNA_def_property_collection_sdna: %s.%s, array not supported for collection type.\n", structname, propname);
791                                 DefRNA.error= 1;
792                         }
793                 }
794
795                 if(strcmp(dp->dnatype, "ListBase") == 0) {
796                         cprop->next= (PropCollectionNextFunc)"rna_iterator_listbase_next";
797                         cprop->get= (PropCollectionGetFunc)"rna_iterator_listbase_get";
798                 }
799         }
800
801         if(dp && lengthpropname) {
802                 DNAStructMember smember;
803                 StructDefRNA *ds= DefRNA.structs.last;
804
805                 if(!structname)
806                         structname= ds->dnaname;
807
808                 if(!rna_find_sdna_member(DefRNA.sdna, structname, lengthpropname, &smember)) {
809                         if(!DefRNA.silent) {
810                                 fprintf(stderr, "RNA_def_property_collection_sdna: %s.%s not found.\n", structname, lengthpropname);
811                                 DefRNA.error= 1;
812                         }
813                 }
814                 else {
815                         dp->dnalengthstructname= structname;
816                         dp->dnalengthname= lengthpropname;
817
818                         cprop->next= (PropCollectionNextFunc)"rna_iterator_array_next";
819                         cprop->get= (PropCollectionGetFunc)"rna_iterator_array_get";
820                         cprop->end= (PropCollectionEndFunc)"rna_iterator_array_end";
821                 }
822         }
823 }
824
825 /* Functions */
826
827 void RNA_def_property_notify_func(PropertyRNA *prop, const char *notify)
828 {
829         if(notify) prop->notify= (PropNotifyFunc)notify;
830 }
831
832 void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set)
833 {
834         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
835
836         if(prop->arraylength) {
837                 if(get) bprop->getarray= (PropBooleanArrayGetFunc)get;
838                 if(set) bprop->setarray= (PropBooleanArraySetFunc)set;
839         }
840         else {
841                 if(get) bprop->get= (PropBooleanGetFunc)get;
842                 if(set) bprop->set= (PropBooleanSetFunc)set;
843         }
844 }
845
846 void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set)
847 {
848         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
849
850         if(prop->arraylength) {
851                 if(get) iprop->getarray= (PropIntArrayGetFunc)get;
852                 if(set) iprop->setarray= (PropIntArraySetFunc)set;
853         }
854         else {
855                 if(get) iprop->get= (PropIntGetFunc)get;
856                 if(set) iprop->set= (PropIntSetFunc)set;
857         }
858 }
859
860 void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char *set)
861 {
862         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
863
864         if(prop->arraylength) {
865                 if(get) fprop->getarray= (PropFloatArrayGetFunc)get;
866                 if(set) fprop->setarray= (PropFloatArraySetFunc)set;
867         }
868         else {
869                 if(get) fprop->get= (PropFloatGetFunc)get;
870                 if(set) fprop->set= (PropFloatSetFunc)set;
871         }
872 }
873
874 void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set)
875 {
876         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
877
878         if(get) eprop->get= (PropEnumGetFunc)get;
879         if(set) eprop->set= (PropEnumSetFunc)set;
880 }
881
882 void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set)
883 {
884         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
885
886         if(get) sprop->get= (PropStringGetFunc)get;
887         if(length) sprop->length= (PropStringLengthFunc)length;
888         if(set) sprop->set= (PropStringSetFunc)set;
889 }
890
891 void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *type, const char *set)
892 {
893         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
894
895         if(get) pprop->get= (PropPointerGetFunc)get;
896         if(type) pprop->type= (PropPointerTypeFunc)type;
897         if(set) pprop->set= (PropPointerSetFunc)set;
898 }
899
900 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)
901 {
902         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
903
904         if(begin) cprop->begin= (PropCollectionBeginFunc)begin;
905         if(next) cprop->next= (PropCollectionNextFunc)next;
906         if(end) cprop->end= (PropCollectionEndFunc)end;
907         if(get) cprop->get= (PropCollectionGetFunc)get;
908         if(type) cprop->type= (PropCollectionTypeFunc)type;
909         if(length) cprop->length= (PropCollectionLengthFunc)length;
910         if(lookupint) cprop->lookupint= (PropCollectionLookupIntFunc)lookupint;
911         if(lookupstring) cprop->lookupstring= (PropCollectionLookupStringFunc)lookupstring;
912 }
913