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