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         rna_def_builtin_properties(srna);
215
216         return srna;
217 }
218
219 void RNA_def_struct_sdna(StructRNA *srna, const char *structname)
220 {
221         StructDefRNA *ds= DefRNA.structs.last;
222
223         if(!DNA_struct_find_nr(DefRNA.sdna, structname)) {
224                 if(!DefRNA.silent) {
225                         fprintf(stderr, "RNA_def_struct_sdna: %s not found.\n", structname);
226                         DefRNA.error= 1;
227                 }
228                 return;
229         }
230
231         ds->dnaname= structname;
232 }
233
234 void RNA_def_struct_name_property(struct StructRNA *srna, struct PropertyRNA *prop)
235 {
236         if(prop->type != PROP_STRING) {
237                 fprintf(stderr, "RNA_def_struct_name_property: %s.%s, must be a string property.\n", srna->cname, prop->cname);
238                 DefRNA.error= 1;
239         }
240         else
241                 srna->nameproperty= prop;
242 }
243
244 void RNA_def_struct_flag(StructRNA *srna, int flag)
245 {
246         srna->flag= flag;
247 }
248
249 /* Property Definition */
250
251 PropertyRNA *RNA_def_property(StructRNA *srna, const char *cname, int type, int subtype)
252 {
253         StructDefRNA *ds;
254         PropertyDefRNA *dp;
255         PropertyRNA *prop;
256
257         ds= DefRNA.structs.last;
258         dp= MEM_callocN(sizeof(PropertyDefRNA), "PropertyDefRNA");
259         rna_addtail(&ds->properties, dp);
260
261         switch(type) {
262                 case PROP_BOOLEAN:
263                         prop= MEM_callocN(sizeof(BooleanPropertyRNA), "BooleanPropertyRNA");
264                         break;
265                 case PROP_INT: {
266                         IntPropertyRNA *iprop;
267                         iprop= MEM_callocN(sizeof(IntPropertyRNA), "IntPropertyRNA");
268                         prop= &iprop->property;
269
270                         iprop->hardmin= (subtype == PROP_UNSIGNED)? 0: INT_MIN;
271                         iprop->hardmax= INT_MAX;
272
273                         iprop->softmin= (subtype == PROP_UNSIGNED)? 0: -10000; /* rather arbitrary .. */
274                         iprop->softmax= 10000;
275                         iprop->step= 1;
276                         break;
277                 }
278                 case PROP_FLOAT: {
279                         FloatPropertyRNA *fprop;
280                         fprop= MEM_callocN(sizeof(FloatPropertyRNA), "FloatPropertyRNA");
281                         prop= &fprop->property;
282
283                         fprop->hardmin= (subtype == PROP_UNSIGNED)? 0.0f: -FLT_MAX;
284                         fprop->hardmax= FLT_MAX;
285
286                         fprop->softmin= (subtype == PROP_UNSIGNED)? 0.0f: -10000.0f; /* rather arbitrary .. */
287                         fprop->softmax= 10000.0f;
288                         fprop->step= 10;
289                         fprop->precision= 3;
290                         break;
291                 }
292                 case PROP_STRING: {
293                         StringPropertyRNA *sprop;
294                         sprop= MEM_callocN(sizeof(StringPropertyRNA), "StringPropertyRNA");
295                         prop= &sprop->property;
296
297                         sprop->defaultvalue= "";
298                         sprop->maxlength= 0;
299                         break;
300                 }
301                 case PROP_ENUM:
302                         prop= MEM_callocN(sizeof(EnumPropertyRNA), "EnumPropertyRNA");
303                         break;
304                 case PROP_POINTER:
305                         prop= MEM_callocN(sizeof(PointerPropertyRNA), "PointerPropertyRNA");
306                         break;
307                 case PROP_COLLECTION:
308                         prop= MEM_callocN(sizeof(CollectionPropertyRNA), "CollectionPropertyRNA");
309                         break;
310                 default:
311                         fprintf(stderr, "RNA_def_property: %s.%s, invalid property type.\n", ds->srna->cname, cname);
312                         DefRNA.error= 1;
313                         return NULL;
314         }
315
316         dp->srna= srna;
317         dp->prop= prop;
318
319         prop->cname= cname;
320         prop->type= type;
321         prop->subtype= subtype;
322         prop->name= cname;
323         prop->description= "";
324
325         if(type == PROP_COLLECTION)
326                 prop->flag= PROP_NOT_EDITABLE|PROP_NOT_DRIVEABLE;
327         else if(type == PROP_POINTER)
328                 prop->flag= PROP_NOT_DRIVEABLE;
329
330         switch(type) {
331                 case PROP_BOOLEAN:
332                         DefRNA.silent= 1;
333                         RNA_def_property_boolean_sdna(prop, srna->cname, cname, 0);
334                         DefRNA.silent= 0;
335                         break;
336                 case PROP_INT: {
337                         DefRNA.silent= 1;
338                         RNA_def_property_int_sdna(prop, srna->cname, cname);
339                         DefRNA.silent= 0;
340                         break;
341                 }
342                 case PROP_FLOAT: {
343                         DefRNA.silent= 1;
344                         RNA_def_property_float_sdna(prop, srna->cname, cname);
345                         DefRNA.silent= 0;
346                         break;
347                 }
348                 case PROP_STRING: {
349                         DefRNA.silent= 1;
350                         RNA_def_property_string_sdna(prop, srna->cname, cname);
351                         DefRNA.silent= 0;
352                         break;
353                 }
354                 case PROP_ENUM:
355                         DefRNA.silent= 1;
356                         RNA_def_property_enum_sdna(prop, srna->cname, cname);
357                         DefRNA.silent= 0;
358                         break;
359                 case PROP_POINTER:
360                         DefRNA.silent= 1;
361                         RNA_def_property_pointer_sdna(prop, srna->cname, cname);
362                         DefRNA.silent= 0;
363                         break;
364                 case PROP_COLLECTION:
365                         DefRNA.silent= 1;
366                         RNA_def_property_collection_sdna(prop, srna->cname, cname, NULL);
367                         DefRNA.silent= 0;
368                         break;
369         }
370
371         rna_addtail(&srna->properties, prop);
372
373         return prop;
374 }
375
376 void RNA_def_property_flag(PropertyRNA *prop, int flag)
377 {
378 #if 0
379         StructDefRNA *ds= DefRNA.structs.last;
380 #endif
381
382         prop->flag |= flag;
383
384 #if 0
385         if(prop->type != PROP_POINTER && prop->type != PROP_COLLECTION) {
386                 if(flag & (PROP_EVALUATE_DEPENDENCY|PROP_INVERSE_EVALUATE_DEPENDENCY|PROP_RENDER_DEPENDENCY|PROP_INVERSE_RENDER_DEPENDENCY)) {
387                         fprintf(stderr, "RNA_def_property_flag: %s.%s, only pointer and collection types can create dependencies.\n", ds->srna->cname, prop->cname);
388                         DefRNA.error= 1;
389                 }
390         }
391 #endif
392 }
393
394 void RNA_def_property_array(PropertyRNA *prop, int arraylength)
395 {
396         StructDefRNA *ds= DefRNA.structs.last;
397
398         switch(prop->type) {
399                 case PROP_BOOLEAN:
400                 case PROP_INT:
401                 case PROP_FLOAT:
402                         prop->arraylength= arraylength;
403                         break;
404                 default:
405                         fprintf(stderr, "RNA_def_property_array: %s.%s, only boolean/int/float can be array.\n", ds->srna->cname, prop->cname);
406                         DefRNA.error= 1;
407                         break;
408         }
409 }
410
411 void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
412 {
413         prop->name= name;
414         prop->description= description;
415 }
416
417 void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, double precision)
418 {
419         StructDefRNA *ds= DefRNA.structs.last;
420
421         switch(prop->type) {
422                 case PROP_INT: {
423                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
424                         iprop->softmin= (int)min;
425                         iprop->softmax= (int)max;
426                         iprop->step= (int)step;
427                         break;
428                 }
429                 case PROP_FLOAT: {
430                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
431                         fprop->softmin= (float)min;
432                         fprop->softmax= (float)max;
433                         fprop->step= (float)step;
434                         fprop->precision= (float)precision;
435                         break;
436                 }
437                 default:
438                         fprintf(stderr, "RNA_def_property_ui_range: %s.%s, invalid type for ui range.\n", ds->srna->cname, prop->cname);
439                         DefRNA.error= 1;
440                         break;
441         }
442 }
443
444 void RNA_def_property_range(PropertyRNA *prop, double min, double max)
445 {
446         StructDefRNA *ds= DefRNA.structs.last;
447
448         switch(prop->type) {
449                 case PROP_INT: {
450                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
451                         iprop->hardmin= (int)min;
452                         iprop->hardmax= (int)max;
453                         iprop->softmin= MAX2((int)min, iprop->hardmin);
454                         iprop->softmax= MIN2((int)max, iprop->hardmax);
455                         break;
456                 }
457                 case PROP_FLOAT: {
458                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
459                         fprop->hardmin= (float)min;
460                         fprop->hardmax= (float)max;
461                         fprop->softmin= MAX2((float)min, fprop->hardmin);
462                         fprop->softmax= MIN2((float)max, fprop->hardmax);
463                         break;
464                 }
465                 default:
466                         fprintf(stderr, "RNA_def_property_range: %s.%s, invalid type for range.\n", ds->srna->cname, prop->cname);
467                         DefRNA.error= 1;
468                         break;
469         }
470 }
471
472 void RNA_def_property_struct_type(PropertyRNA *prop, const char *type)
473 {
474         StructDefRNA *ds= DefRNA.structs.last;
475
476         switch(prop->type) {
477                 case PROP_POINTER: {
478                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
479                         pprop->structtype = (StructRNA*)type;
480                         break;
481                 }
482                 case PROP_COLLECTION: {
483                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
484                         cprop->structtype = (StructRNA*)type;
485                         break;
486                 }
487                 default:
488                         fprintf(stderr, "RNA_def_property_struct_type: %s.%s, invalid type for struct type.\n", ds->srna->cname, prop->cname);
489                         DefRNA.error= 1;
490                         break;
491         }
492 }
493
494 void RNA_def_property_enum_items(PropertyRNA *prop, const PropertyEnumItem *item)
495 {
496         StructDefRNA *ds= DefRNA.structs.last;
497         int i;
498
499         switch(prop->type) {
500                 case PROP_ENUM: {
501                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
502                         eprop->item= item;
503                         eprop->totitem= 0;
504                         for(i=0; item[i].cname; i++)
505                                 eprop->totitem++;
506
507                         break;
508                 }
509                 default:
510                         fprintf(stderr, "RNA_def_property_struct_type: %s.%s, invalid type for struct type.\n", ds->srna->cname, prop->cname);
511                         DefRNA.error= 1;
512                         break;
513         }
514 }
515
516 void RNA_def_property_string_maxlength(PropertyRNA *prop, int maxlength)
517 {
518         StructDefRNA *ds= DefRNA.structs.last;
519
520         switch(prop->type) {
521                 case PROP_STRING: {
522                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
523                         sprop->maxlength= maxlength;
524                         break;
525                 }
526                 default:
527                         fprintf(stderr, "RNA_def_property_string_maxlength: %s.%s, type is not string.\n", ds->srna->cname, prop->cname);
528                         DefRNA.error= 1;
529                         break;
530         }
531 }
532
533 void RNA_def_property_boolean_default(PropertyRNA *prop, int value)
534 {
535         StructDefRNA *ds= DefRNA.structs.last;
536
537         switch(prop->type) {
538                 case PROP_BOOLEAN: {
539                         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
540                         bprop->defaultvalue= value;
541                         break;
542                 }
543                 default:
544                         fprintf(stderr, "RNA_def_property_boolean_default: %s.%s, type is not boolean.\n", ds->srna->cname, prop->cname);
545                         DefRNA.error= 1;
546                         break;
547         }
548 }
549
550 void RNA_def_property_boolean_array_default(PropertyRNA *prop, const int *array)
551 {
552         StructDefRNA *ds= DefRNA.structs.last;
553
554         switch(prop->type) {
555                 case PROP_BOOLEAN: {
556                         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
557                         bprop->defaultarray= array;
558                         break;
559                 }
560                 default:
561                         fprintf(stderr, "RNA_def_property_boolean_default: %s.%s, type is not boolean.\n", ds->srna->cname, prop->cname);
562                         DefRNA.error= 1;
563                         break;
564         }
565 }
566
567 void RNA_def_property_int_default(PropertyRNA *prop, int value)
568 {
569         StructDefRNA *ds= DefRNA.structs.last;
570
571         switch(prop->type) {
572                 case PROP_INT: {
573                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
574                         iprop->defaultvalue= value;
575                         break;
576                 }
577                 default:
578                         fprintf(stderr, "RNA_def_property_int_default: %s.%s, type is not int.\n", ds->srna->cname, prop->cname);
579                         DefRNA.error= 1;
580                         break;
581         }
582 }
583
584 void RNA_def_property_int_array_default(PropertyRNA *prop, const int *array)
585 {
586         StructDefRNA *ds= DefRNA.structs.last;
587
588         switch(prop->type) {
589                 case PROP_INT: {
590                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
591                         iprop->defaultarray= array;
592                         break;
593                 }
594                 default:
595                         fprintf(stderr, "RNA_def_property_int_default: %s.%s, type is not int.\n", ds->srna->cname, prop->cname);
596                         DefRNA.error= 1;
597                         break;
598         }
599 }
600
601 void RNA_def_property_float_default(PropertyRNA *prop, float value)
602 {
603         StructDefRNA *ds= DefRNA.structs.last;
604
605         switch(prop->type) {
606                 case PROP_FLOAT: {
607                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
608                         fprop->defaultvalue= value;
609                         break;
610                 }
611                 default:
612                         fprintf(stderr, "RNA_def_property_float_default: %s.%s, type is not float.\n", ds->srna->cname, prop->cname);
613                         DefRNA.error= 1;
614                         break;
615         }
616 }
617
618 void RNA_def_property_float_array_default(PropertyRNA *prop, const float *array)
619 {
620         StructDefRNA *ds= DefRNA.structs.last;
621
622         switch(prop->type) {
623                 case PROP_FLOAT: {
624                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
625                         fprop->defaultarray= array;
626                         break;
627                 }
628                 default:
629                         fprintf(stderr, "RNA_def_property_float_default: %s.%s, type is not float.\n", ds->srna->cname, prop->cname);
630                         DefRNA.error= 1;
631                         break;
632         }
633 }
634
635 void RNA_def_property_string_default(PropertyRNA *prop, const char *value)
636 {
637         StructDefRNA *ds= DefRNA.structs.last;
638
639         switch(prop->type) {
640                 case PROP_STRING: {
641                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
642                         sprop->defaultvalue= value;
643                         break;
644                 }
645                 default:
646                         fprintf(stderr, "RNA_def_property_string_default: %s.%s, type is not string.\n", ds->srna->cname, prop->cname);
647                         DefRNA.error= 1;
648                         break;
649         }
650 }
651
652 void RNA_def_property_enum_default(PropertyRNA *prop, int value)
653 {
654         StructDefRNA *ds= DefRNA.structs.last;
655
656         switch(prop->type) {
657                 case PROP_ENUM: {
658                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
659                         eprop->defaultvalue= value;
660                         break;
661                 }
662                 default:
663                         fprintf(stderr, "RNA_def_property_enum_default: %s.%s, type is not enum.\n", ds->srna->cname, prop->cname);
664                         DefRNA.error= 1;
665                         break;
666         }
667 }
668
669 /* SDNA */
670
671 static PropertyDefRNA *rna_def_property_sdna(PropertyRNA *prop, const char *structname, const char *propname)
672 {
673         DNAStructMember smember;
674         StructDefRNA *ds= DefRNA.structs.last;
675         PropertyDefRNA *dp= ds->properties.last;
676
677         if(!structname)
678                 structname= ds->dnaname;
679         if(!propname)
680                 propname= prop->cname;
681
682         if(!rna_find_sdna_member(DefRNA.sdna, structname, propname, &smember)) {
683                 if(!DefRNA.silent) {
684                         fprintf(stderr, "rna_def_property_sdna: %s.%s not found.\n", structname, propname);
685                         DefRNA.error= 1;
686                 }
687                 return NULL;
688         }
689
690         if(smember.arraylength > 1)
691                 prop->arraylength= smember.arraylength;
692         else
693                 prop->arraylength= 0;
694         
695         dp->dnastructname= structname;
696         dp->dnaname= propname;
697         dp->dnatype= smember.type;
698         dp->dnaarraylength= smember.arraylength;
699
700         return dp;
701 }
702
703 void RNA_def_property_boolean_sdna(PropertyRNA *prop, const char *structname, const char *propname, int bit)
704 {
705         PropertyDefRNA *dp;
706         
707         if((dp=rna_def_property_sdna(prop, structname, propname)))
708                 dp->booleanbit= bit;
709 }
710
711 void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const char *propname)
712 {
713         PropertyDefRNA *dp;
714         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
715         
716         if((dp= rna_def_property_sdna(prop, structname, propname))) {
717                 /* SDNA doesn't pass us unsigned unfortunately .. */
718                 if(strcmp(dp->dnatype, "char") == 0) {
719                         iprop->hardmin= iprop->softmin= CHAR_MIN;
720                         iprop->hardmax= iprop->softmax= CHAR_MAX;
721                 }
722                 else if(strcmp(dp->dnatype, "short") == 0) {
723                         iprop->hardmin= iprop->softmin= SHRT_MIN;
724                         iprop->hardmax= iprop->softmax= SHRT_MAX;
725                 }
726                 else if(strcmp(dp->dnatype, "int") == 0) {
727                         iprop->hardmin= INT_MIN;
728                         iprop->hardmax= INT_MAX;
729
730                         iprop->softmin= -10000; /* rather arbitrary .. */
731                         iprop->softmax= 10000;
732                 }
733
734                 if(prop->subtype == PROP_UNSIGNED)
735                         iprop->hardmin= iprop->softmin= 0;
736         }
737 }
738
739 void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, const char *propname)
740 {
741         rna_def_property_sdna(prop, structname, propname);
742 }
743
744 void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const char *propname)
745 {
746         PropertyDefRNA *dp;
747         
748         if((dp=rna_def_property_sdna(prop, structname, propname))) {
749                 if(prop->arraylength) {
750                         prop->arraylength= 0;
751                         if(!DefRNA.silent) {
752                                 fprintf(stderr, "RNA_def_property_enum_sdna: %s.%s, array not supported for enum type.\n", structname, propname);
753                                 DefRNA.error= 1;
754                         }
755                 }
756         }
757 }
758
759 void RNA_def_property_string_sdna(PropertyRNA *prop, const char *structname, const char *propname)
760 {
761         PropertyDefRNA *dp;
762         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
763
764         if((dp=rna_def_property_sdna(prop, structname, propname))) {
765                 if(prop->arraylength) {
766                         sprop->maxlength= prop->arraylength;
767                         prop->arraylength= 0;
768                 }
769         }
770 }
771
772 void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, const char *propname)
773 {
774         PropertyDefRNA *dp;
775         
776         if((dp=rna_def_property_sdna(prop, structname, propname))) {
777                 if(prop->arraylength) {
778                         prop->arraylength= 0;
779                         if(!DefRNA.silent) {
780                                 fprintf(stderr, "RNA_def_property_pointer_sdna: %s.%s, array not supported for pointer type.\n", structname, propname);
781                                 DefRNA.error= 1;
782                         }
783                 }
784         }
785 }
786
787 void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, const char *propname, const char *lengthpropname)
788 {
789         PropertyDefRNA *dp;
790         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
791         
792         if((dp=rna_def_property_sdna(prop, structname, propname))) {
793                 if(prop->arraylength) {
794                         prop->arraylength= 0;
795
796                         if(!DefRNA.silent) {
797                                 fprintf(stderr, "RNA_def_property_collection_sdna: %s.%s, array not supported for collection type.\n", structname, propname);
798                                 DefRNA.error= 1;
799                         }
800                 }
801
802                 if(strcmp(dp->dnatype, "ListBase") == 0) {
803                         cprop->next= (PropCollectionNextFunc)"rna_iterator_listbase_next";
804                         cprop->get= (PropCollectionGetFunc)"rna_iterator_listbase_get";
805                 }
806         }
807
808         if(dp && lengthpropname) {
809                 DNAStructMember smember;
810                 StructDefRNA *ds= DefRNA.structs.last;
811
812                 if(!structname)
813                         structname= ds->dnaname;
814
815                 if(!rna_find_sdna_member(DefRNA.sdna, structname, lengthpropname, &smember)) {
816                         if(!DefRNA.silent) {
817                                 fprintf(stderr, "RNA_def_property_collection_sdna: %s.%s not found.\n", structname, lengthpropname);
818                                 DefRNA.error= 1;
819                         }
820                 }
821                 else {
822                         dp->dnalengthstructname= structname;
823                         dp->dnalengthname= lengthpropname;
824
825                         cprop->next= (PropCollectionNextFunc)"rna_iterator_array_next";
826                         cprop->get= (PropCollectionGetFunc)"rna_iterator_array_get";
827                         cprop->end= (PropCollectionEndFunc)"rna_iterator_array_end";
828                 }
829         }
830 }
831
832 /* Functions */
833
834 void RNA_def_property_notify_func(PropertyRNA *prop, const char *notify)
835 {
836         if(notify) prop->notify= (PropNotifyFunc)notify;
837 }
838
839 void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set)
840 {
841         StructDefRNA *ds= DefRNA.structs.last;
842
843         switch(prop->type) {
844                 case PROP_BOOLEAN: {
845                         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
846
847                         if(prop->arraylength) {
848                                 if(get) bprop->getarray= (PropBooleanArrayGetFunc)get;
849                                 if(set) bprop->setarray= (PropBooleanArraySetFunc)set;
850                         }
851                         else {
852                                 if(get) bprop->get= (PropBooleanGetFunc)get;
853                                 if(set) bprop->set= (PropBooleanSetFunc)set;
854                         }
855                         break;
856                 }
857                 default:
858                         fprintf(stderr, "RNA_def_property_boolean_funcs: %s.%s, type is not boolean.\n", ds->srna->cname, prop->cname);
859                         DefRNA.error= 1;
860                         break;
861         }
862 }
863
864 void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set)
865 {
866         StructDefRNA *ds= DefRNA.structs.last;
867
868         switch(prop->type) {
869                 case PROP_INT: {
870                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
871
872                         if(prop->arraylength) {
873                                 if(get) iprop->getarray= (PropIntArrayGetFunc)get;
874                                 if(set) iprop->setarray= (PropIntArraySetFunc)set;
875                         }
876                         else {
877                                 if(get) iprop->get= (PropIntGetFunc)get;
878                                 if(set) iprop->set= (PropIntSetFunc)set;
879                         }
880                         break;
881                 }
882                 default:
883                         fprintf(stderr, "RNA_def_property_int_funcs: %s.%s, type is not int.\n", ds->srna->cname, prop->cname);
884                         DefRNA.error= 1;
885                         break;
886         }
887 }
888
889 void RNA_def_property_float_funcs(PropertyRNA *prop, const char *get, const char *set)
890 {
891         StructDefRNA *ds= DefRNA.structs.last;
892
893         switch(prop->type) {
894                 case PROP_FLOAT: {
895                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
896
897                         if(prop->arraylength) {
898                                 if(get) fprop->getarray= (PropFloatArrayGetFunc)get;
899                                 if(set) fprop->setarray= (PropFloatArraySetFunc)set;
900                         }
901                         else {
902                                 if(get) fprop->get= (PropFloatGetFunc)get;
903                                 if(set) fprop->set= (PropFloatSetFunc)set;
904                         }
905                         break;
906                 }
907                 default:
908                         fprintf(stderr, "RNA_def_property_float_funcs: %s.%s, type is not float.\n", ds->srna->cname, prop->cname);
909                         DefRNA.error= 1;
910                         break;
911         }
912 }
913
914 void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set)
915 {
916         StructDefRNA *ds= DefRNA.structs.last;
917
918         switch(prop->type) {
919                 case PROP_ENUM: {
920                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
921
922                         if(get) eprop->get= (PropEnumGetFunc)get;
923                         if(set) eprop->set= (PropEnumSetFunc)set;
924                         break;
925                 }
926                 default:
927                         fprintf(stderr, "RNA_def_property_enum_funcs: %s.%s, type is not enum.\n", ds->srna->cname, prop->cname);
928                         DefRNA.error= 1;
929                         break;
930         }
931 }
932
933 void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set)
934 {
935         StructDefRNA *ds= DefRNA.structs.last;
936
937         switch(prop->type) {
938                 case PROP_STRING: {
939                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
940
941                         if(get) sprop->get= (PropStringGetFunc)get;
942                         if(length) sprop->length= (PropStringLengthFunc)length;
943                         if(set) sprop->set= (PropStringSetFunc)set;
944                         break;
945                 }
946                 default:
947                         fprintf(stderr, "RNA_def_property_string_funcs: %s.%s, type is not string.\n", ds->srna->cname, prop->cname);
948                         DefRNA.error= 1;
949                         break;
950         }
951 }
952
953 void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *type, const char *set)
954 {
955         StructDefRNA *ds= DefRNA.structs.last;
956
957         switch(prop->type) {
958                 case PROP_POINTER: {
959                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
960
961                         if(get) pprop->get= (PropPointerGetFunc)get;
962                         if(type) pprop->type= (PropPointerTypeFunc)type;
963                         if(set) pprop->set= (PropPointerSetFunc)set;
964                         break;
965                 }
966                 default:
967                         fprintf(stderr, "RNA_def_property_pointer_funcs: %s.%s, type is not pointer.\n", ds->srna->cname, prop->cname);
968                         DefRNA.error= 1;
969                         break;
970         }
971 }
972
973 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)
974 {
975         StructDefRNA *ds= DefRNA.structs.last;
976
977         switch(prop->type) {
978                 case PROP_COLLECTION: {
979                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
980
981                         if(begin) cprop->begin= (PropCollectionBeginFunc)begin;
982                         if(next) cprop->next= (PropCollectionNextFunc)next;
983                         if(end) cprop->end= (PropCollectionEndFunc)end;
984                         if(get) cprop->get= (PropCollectionGetFunc)get;
985                         if(type) cprop->type= (PropCollectionTypeFunc)type;
986                         if(length) cprop->length= (PropCollectionLengthFunc)length;
987                         if(lookupint) cprop->lookupint= (PropCollectionLookupIntFunc)lookupint;
988                         if(lookupstring) cprop->lookupstring= (PropCollectionLookupStringFunc)lookupstring;
989                         break;
990                 }
991                 default:
992                         fprintf(stderr, "RNA_def_property_collection_funcs: %s.%s, type is not collection.\n", ds->srna->cname, prop->cname);
993                         DefRNA.error= 1;
994                         break;
995         }
996 }
997