RNA / Data API
[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 *strct;
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(strct=DefRNA.structs.first; strct; strct=strct->next)
168                 rna_freelistN(&strct->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 *strct;
183
184         RNA_define_free(brna);
185
186         for(strct=brna->structs.first; strct; strct=strct->next)
187                 rna_freelistN(&strct->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 *strct;
199         StructDefRNA *ds;
200
201         ds= MEM_callocN(sizeof(StructDefRNA), "StructDefRNA");
202         rna_addtail(&DefRNA.structs, ds);
203
204         strct= MEM_callocN(sizeof(StructRNA), "StructRNA");
205         strct->cname= cname;
206         strct->name= name;
207
208         ds->strct= strct;
209
210         rna_addtail(&brna->structs, strct);
211
212         RNA_def_struct_sdna(strct, strct->cname);
213
214         return strct;
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: must be a string property.\n");
236                 DefRNA.error= 1;
237         }
238         else
239                 srna->nameproperty= prop;
240 }
241
242 /* Property Definition */
243
244 PropertyRNA *RNA_def_property(StructRNA *strct, const char *cname, int type, int subtype)
245 {
246         StructDefRNA *ds;
247         PropertyDefRNA *dp;
248         PropertyRNA *prop;
249
250         ds= DefRNA.structs.last;
251         dp= MEM_callocN(sizeof(PropertyDefRNA), "PropertyDefRNA");
252         rna_addtail(&ds->properties, dp);
253
254         switch(type) {
255                 case PROP_BOOLEAN:
256                         prop= MEM_callocN(sizeof(BooleanPropertyRNA), "BooleanPropertyRNA");
257                         break;
258                 case PROP_INT: {
259                         IntPropertyRNA *iprop;
260                         iprop= MEM_callocN(sizeof(IntPropertyRNA), "IntPropertyRNA");
261                         prop= &iprop->property;
262
263                         iprop->hardmin= (subtype == PROP_UNSIGNED)? 0: INT_MIN;
264                         iprop->hardmax= INT_MAX;
265
266                         iprop->softmin= (subtype == PROP_UNSIGNED)? 0: -10000; /* rather arbitrary .. */
267                         iprop->softmax= 10000;
268                         break;
269                 }
270                 case PROP_FLOAT: {
271                         FloatPropertyRNA *fprop;
272                         fprop= MEM_callocN(sizeof(FloatPropertyRNA), "FloatPropertyRNA");
273                         prop= &fprop->property;
274
275                         fprop->hardmin= (subtype == PROP_UNSIGNED)? 0: -FLT_MAX;
276                         fprop->hardmax= FLT_MAX;
277
278                         fprop->softmin= (subtype == PROP_UNSIGNED)? 0: -10000; /* rather arbitrary .. */
279                         fprop->softmax= 10000;
280                         break;
281                 }
282                 case PROP_STRING: {
283                         StringPropertyRNA *sprop;
284                         sprop= MEM_callocN(sizeof(StringPropertyRNA), "StringPropertyRNA");
285                         prop= &sprop->property;
286
287                         sprop->defaultvalue= "";
288                         sprop->maxlength= 0;
289                         break;
290                 }
291                 case PROP_ENUM:
292                         prop= MEM_callocN(sizeof(EnumPropertyRNA), "EnumPropertyRNA");
293                         break;
294                 case PROP_POINTER:
295                         prop= MEM_callocN(sizeof(PointerPropertyRNA), "PointerPropertyRNA");
296                         break;
297                 case PROP_COLLECTION:
298                         prop= MEM_callocN(sizeof(CollectionPropertyRNA), "CollectionPropertyRNA");
299                         break;
300                 default:
301                         fprintf(stderr, "RNA_def_property: invalid property type.\n");
302                         DefRNA.error= 1;
303                         return NULL;
304         }
305
306         dp->strct= strct;
307         dp->prop= prop;
308
309         prop->cname= cname;
310         prop->type= type;
311         prop->subtype= subtype;
312         prop->name= cname;
313         prop->description= "";
314         prop->flag= PROP_EDITABLE|PROP_EVALUATEABLE;
315
316         switch(type) {
317                 case PROP_BOOLEAN:
318                         DefRNA.silent= 1;
319                         RNA_def_property_boolean_sdna(prop, strct->cname, cname, 0);
320                         DefRNA.silent= 0;
321                         break;
322                 case PROP_INT: {
323                         DefRNA.silent= 1;
324                         RNA_def_property_int_sdna(prop, strct->cname, cname);
325                         DefRNA.silent= 0;
326                         break;
327                 }
328                 case PROP_FLOAT: {
329                         DefRNA.silent= 1;
330                         RNA_def_property_float_sdna(prop, strct->cname, cname);
331                         DefRNA.silent= 0;
332                         break;
333                 }
334                 case PROP_STRING: {
335                         DefRNA.silent= 1;
336                         RNA_def_property_string_sdna(prop, strct->cname, cname);
337                         DefRNA.silent= 0;
338                         break;
339                 }
340                 case PROP_ENUM:
341                         DefRNA.silent= 1;
342                         RNA_def_property_enum_sdna(prop, strct->cname, cname);
343                         DefRNA.silent= 0;
344                         break;
345                 case PROP_POINTER:
346                         DefRNA.silent= 1;
347                         RNA_def_property_pointer_sdna(prop, strct->cname, cname);
348                         DefRNA.silent= 0;
349                         break;
350                 case PROP_COLLECTION:
351                         DefRNA.silent= 1;
352                         RNA_def_property_collection_sdna(prop, strct->cname, cname);
353                         DefRNA.silent= 0;
354                         break;
355         }
356
357         rna_addtail(&strct->properties, prop);
358
359         return prop;
360 }
361
362 void RNA_def_property_access(PropertyRNA *prop, int editable, int evaluatable)
363 {
364         if(editable) prop->flag |= PROP_EDITABLE;
365         else prop->flag &= ~PROP_EDITABLE;
366
367         if(evaluatable) prop->flag |= PROP_EVALUATEABLE;
368         else prop->flag &= ~PROP_EVALUATEABLE;
369 }
370
371 void RNA_def_property_array(PropertyRNA *prop, int arraylength)
372 {
373         switch(prop->type) {
374                 case PROP_BOOLEAN:
375                 case PROP_INT:
376                 case PROP_FLOAT:
377                         prop->arraylength= arraylength;
378                         break;
379                 default:
380                         fprintf(stderr, "RNA_def_property_array: only boolean/int/float can be array.\n");
381                         DefRNA.error= 1;
382                         break;
383         }
384 }
385
386 void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
387 {
388         prop->name= name;
389         prop->description= description;
390 }
391
392 void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, double precision)
393 {
394         switch(prop->type) {
395                 case PROP_INT: {
396                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
397                         iprop->softmin= (int)min;
398                         iprop->softmax= (int)max;
399                         iprop->step= (int)step;
400                         break;
401                 }
402                 case PROP_FLOAT: {
403                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
404                         fprop->softmin= (float)min;
405                         fprop->softmax= (float)max;
406                         fprop->step= (float)step;
407                         fprop->precision= (float)precision;
408                         break;
409                 }
410                 default:
411                         fprintf(stderr, "RNA_def_property_ui_range: invalid type for ui range.\n");
412                         DefRNA.error= 1;
413                         break;
414         }
415 }
416
417 void RNA_def_property_range(PropertyRNA *prop, double min, double max)
418 {
419         switch(prop->type) {
420                 case PROP_INT: {
421                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
422                         iprop->hardmin= (int)min;
423                         iprop->hardmax= (int)max;
424                         iprop->softmin= MAX2(min, iprop->hardmin);
425                         iprop->softmax= MIN2(max, iprop->hardmax);
426                         break;
427                 }
428                 case PROP_FLOAT: {
429                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
430                         fprop->hardmin= (float)min;
431                         fprop->hardmax= (float)max;
432                         fprop->softmin= MAX2(min, fprop->hardmin);
433                         fprop->softmax= MIN2(max, fprop->hardmax);
434                         break;
435                 }
436                 default:
437                         fprintf(stderr, "RNA_def_property_range: invalid type for range.\n");
438                         DefRNA.error= 1;
439                         break;
440         }
441 }
442
443 void RNA_def_property_struct_type(PropertyRNA *prop, const char *type)
444 {
445         switch(prop->type) {
446                 case PROP_POINTER: {
447                         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
448                         pprop->structtype = (StructRNA*)type;
449                         break;
450                 }
451                 case PROP_COLLECTION: {
452                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
453                         cprop->structtype = (StructRNA*)type;
454                         break;
455                 }
456                 default:
457                         fprintf(stderr, "RNA_def_property_struct_type: invalid type for struct type.\n");
458                         DefRNA.error= 1;
459                         break;
460         }
461 }
462
463 void RNA_def_property_enum_items(PropertyRNA *prop, const PropertyEnumItem *item)
464 {
465         int i;
466
467         switch(prop->type) {
468                 case PROP_ENUM: {
469                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
470                         eprop->item= item;
471                         eprop->totitem= 0;
472                         for(i=0; item[i].cname; i++)
473                                 eprop->totitem++;
474
475                         break;
476                 }
477                 default:
478                         fprintf(stderr, "RNA_def_property_struct_type: invalid type for struct type.\n");
479                         DefRNA.error= 1;
480                         break;
481         }
482 }
483
484 void RNA_def_property_string_maxlength(PropertyRNA *prop, int maxlength)
485 {
486         switch(prop->type) {
487                 case PROP_STRING: {
488                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
489                         sprop->maxlength= maxlength;
490                         break;
491                 }
492                 default:
493                         fprintf(stderr, "RNA_def_property_string_maxlength: type is not string.\n");
494                         DefRNA.error= 1;
495                         break;
496         }
497 }
498
499 void RNA_def_property_boolean_default(PropertyRNA *prop, int value)
500 {
501         switch(prop->type) {
502                 case PROP_BOOLEAN: {
503                         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
504                         bprop->defaultvalue= value;
505                         break;
506                 }
507                 default:
508                         fprintf(stderr, "RNA_def_property_boolean_default: type is not boolean.\n");
509                         DefRNA.error= 1;
510                         break;
511         }
512 }
513
514 void RNA_def_property_boolean_array_default(PropertyRNA *prop, const int *array)
515 {
516         switch(prop->type) {
517                 case PROP_BOOLEAN: {
518                         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
519                         bprop->defaultarray= array;
520                         break;
521                 }
522                 default:
523                         fprintf(stderr, "RNA_def_property_boolean_default: type is not boolean.\n");
524                         DefRNA.error= 1;
525                         break;
526         }
527 }
528
529 void RNA_def_property_int_default(PropertyRNA *prop, int value)
530 {
531         switch(prop->type) {
532                 case PROP_INT: {
533                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
534                         iprop->defaultvalue= value;
535                         break;
536                 }
537                 default:
538                         fprintf(stderr, "RNA_def_property_int_default: type is not int.\n");
539                         DefRNA.error= 1;
540                         break;
541         }
542 }
543
544 void RNA_def_property_int_array_default(PropertyRNA *prop, const int *array)
545 {
546         switch(prop->type) {
547                 case PROP_INT: {
548                         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
549                         iprop->defaultarray= array;
550                         break;
551                 }
552                 default:
553                         fprintf(stderr, "RNA_def_property_int_default: type is not int.\n");
554                         DefRNA.error= 1;
555                         break;
556         }
557 }
558
559 void RNA_def_property_float_default(PropertyRNA *prop, float value)
560 {
561         switch(prop->type) {
562                 case PROP_FLOAT: {
563                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
564                         fprop->defaultvalue= value;
565                         break;
566                 }
567                 default:
568                         fprintf(stderr, "RNA_def_property_float_default: type is not float.\n");
569                         DefRNA.error= 1;
570                         break;
571         }
572 }
573
574 void RNA_def_property_float_array_default(PropertyRNA *prop, const float *array)
575 {
576         switch(prop->type) {
577                 case PROP_FLOAT: {
578                         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
579                         fprop->defaultarray= array;
580                         break;
581                 }
582                 default:
583                         fprintf(stderr, "RNA_def_property_float_default: type is not float.\n");
584                         DefRNA.error= 1;
585                         break;
586         }
587 }
588
589 void RNA_def_property_string_default(PropertyRNA *prop, const char *value)
590 {
591         switch(prop->type) {
592                 case PROP_STRING: {
593                         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
594                         sprop->defaultvalue= value;
595                         break;
596                 }
597                 default:
598                         fprintf(stderr, "RNA_def_property_string_default: type is not string.\n");
599                         DefRNA.error= 1;
600                         break;
601         }
602 }
603
604 void RNA_def_property_enum_default(PropertyRNA *prop, int value)
605 {
606         switch(prop->type) {
607                 case PROP_ENUM: {
608                         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
609                         eprop->defaultvalue= value;
610                         break;
611                 }
612                 default:
613                         fprintf(stderr, "RNA_def_property_enum_default: type is not enum.\n");
614                         DefRNA.error= 1;
615                         break;
616         }
617 }
618
619 /* SDNA */
620
621 static PropertyDefRNA *rna_def_property_sdna(PropertyRNA *prop, const char *structname, const char *propname)
622 {
623         DNAStructMember smember;
624         StructDefRNA *ds= DefRNA.structs.last;
625         PropertyDefRNA *dp= ds->properties.last;
626
627         if(!structname)
628                 structname= ds->dnaname;
629         if(!propname)
630                 propname= prop->cname;
631
632         if(!rna_find_sdna_member(DefRNA.sdna, structname, propname, &smember)) {
633                 if(!DefRNA.silent) {
634                         fprintf(stderr, "rna_def_property_sdna: %s.%s not found.\n", structname, propname);
635                         DefRNA.error= 1;
636                 }
637                 return NULL;
638         }
639
640         if(smember.arraylength > 1)
641                 prop->arraylength= smember.arraylength;
642         else
643                 prop->arraylength= 0;
644         
645         dp->dnastructname= structname;
646         dp->dnaname= propname;
647         dp->dnatype= smember.type;
648         dp->dnaarraylength= smember.arraylength;
649
650         return dp;
651 }
652
653 void RNA_def_property_boolean_sdna(PropertyRNA *prop, const char *structname, const char *propname, int bit)
654 {
655         PropertyDefRNA *dp;
656         
657         if((dp=rna_def_property_sdna(prop, structname, propname)))
658                 dp->booleanbit= bit;
659 }
660
661 void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const char *propname)
662 {
663         PropertyDefRNA *dp;
664         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
665         
666         if((dp= rna_def_property_sdna(prop, structname, propname))) {
667                 /* SDNA doesn't pass us unsigned unfortunately .. */
668                 if(strcmp(dp->dnatype, "char") == 0) {
669                         iprop->hardmin= iprop->softmin= CHAR_MIN;
670                         iprop->hardmax= iprop->softmax= CHAR_MAX;
671                 }
672                 else if(strcmp(dp->dnatype, "short") == 0) {
673                         iprop->hardmin= iprop->softmin= SHRT_MIN;
674                         iprop->hardmax= iprop->softmax= SHRT_MAX;
675                 }
676                 else if(strcmp(dp->dnatype, "int") == 0) {
677                         iprop->hardmin= INT_MIN;
678                         iprop->hardmax= INT_MAX;
679
680                         iprop->softmin= -10000; /* rather arbitrary .. */
681                         iprop->softmax= 10000;
682                 }
683
684                 if(prop->subtype == PROP_UNSIGNED)
685                         iprop->hardmin= iprop->softmin= 0;
686         }
687 }
688
689 void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, const char *propname)
690 {
691         rna_def_property_sdna(prop, structname, propname);
692 }
693
694 void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const char *propname)
695 {
696         PropertyDefRNA *dp;
697         
698         if((dp=rna_def_property_sdna(prop, structname, propname))) {
699                 if(prop->arraylength) {
700                         prop->arraylength= 0;
701                         if(!DefRNA.silent) {
702                                 fprintf(stderr, "RNA_def_property_enum_sdna: %s.%s, array not supported for enum type.\n", structname, propname);
703                                 DefRNA.error= 1;
704                         }
705                 }
706         }
707 }
708
709 void RNA_def_property_string_sdna(PropertyRNA *prop, const char *structname, const char *propname)
710 {
711         PropertyDefRNA *dp;
712         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
713
714         if((dp=rna_def_property_sdna(prop, structname, propname))) {
715                 if(prop->arraylength) {
716                         sprop->maxlength= prop->arraylength;
717                         prop->arraylength= 0;
718                 }
719         }
720 }
721
722 void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, const char *propname)
723 {
724         PropertyDefRNA *dp;
725         
726         if((dp=rna_def_property_sdna(prop, structname, propname))) {
727                 if(prop->arraylength) {
728                         prop->arraylength= 0;
729                         if(!DefRNA.silent) {
730                                 fprintf(stderr, "RNA_def_property_pointer_sdna: %s.%s, array not supported for pointer type.\n", structname, propname);
731                                 DefRNA.error= 1;
732                         }
733                 }
734         }
735 }
736
737 void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, const char *propname)
738 {
739         PropertyDefRNA *dp;
740         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
741         
742         if((dp=rna_def_property_sdna(prop, structname, propname))) {
743                 if(prop->arraylength) {
744                         prop->arraylength= 0;
745
746                         if(!DefRNA.silent) {
747                                 fprintf(stderr, "RNA_def_property_collection_sdna: %s.%s, array not supported for collection type.\n", structname, propname);
748                                 DefRNA.error= 1;
749                         }
750                 }
751
752                 if(strcmp(dp->dnatype, "ListBase") == 0) {
753                         cprop->next= (PropCollectionNextFunc)"rna_iterator_listbase_next";
754                         cprop->get= (PropCollectionGetFunc)"rna_iterator_listbase_get";
755                 }
756         }
757 }
758
759 /* Functions */
760
761 void RNA_def_property_notify_func(PropertyRNA *prop, char *notify)
762 {
763         if(notify) prop->notify= (PropNotifyFunc)notify;
764 }
765
766 void RNA_def_property_boolean_funcs(PropertyRNA *prop, char *get, char *set)
767 {
768         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
769
770         if(prop->arraylength) {
771                 if(get) bprop->getarray= (PropBooleanArrayGetFunc)get;
772                 if(set) bprop->setarray= (PropBooleanArraySetFunc)set;
773         }
774         else {
775                 if(get) bprop->get= (PropBooleanGetFunc)get;
776                 if(set) bprop->set= (PropBooleanSetFunc)set;
777         }
778 }
779
780 void RNA_def_property_int_funcs(PropertyRNA *prop, char *get, char *set)
781 {
782         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
783
784         if(prop->arraylength) {
785                 if(get) iprop->getarray= (PropIntArrayGetFunc)get;
786                 if(set) iprop->setarray= (PropIntArraySetFunc)set;
787         }
788         else {
789                 if(get) iprop->get= (PropIntGetFunc)get;
790                 if(set) iprop->set= (PropIntSetFunc)set;
791         }
792 }
793
794 void RNA_def_property_float_funcs(PropertyRNA *prop, char *get, char *set)
795 {
796         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
797
798         if(prop->arraylength) {
799                 if(get) fprop->getarray= (PropFloatArrayGetFunc)get;
800                 if(set) fprop->setarray= (PropFloatArraySetFunc)set;
801         }
802         else {
803                 if(get) fprop->get= (PropFloatGetFunc)get;
804                 if(set) fprop->set= (PropFloatSetFunc)set;
805         }
806 }
807
808 void RNA_def_property_enum_funcs(PropertyRNA *prop, char *get, char *set)
809 {
810         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
811
812         if(get) eprop->get= (PropEnumGetFunc)get;
813         if(set) eprop->set= (PropEnumSetFunc)set;
814 }
815
816 void RNA_def_property_string_funcs(PropertyRNA *prop, char *get, char *length, char *set)
817 {
818         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
819
820         if(get) sprop->get= (PropStringGetFunc)get;
821         if(length) sprop->length= (PropStringLengthFunc)length;
822         if(set) sprop->set= (PropStringSetFunc)set;
823 }
824
825 void RNA_def_property_pointer_funcs(PropertyRNA *prop, char *get, char *type, char *set)
826 {
827         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
828
829         if(get) pprop->get= (PropPointerGetFunc)get;
830         if(type) pprop->type= (PropPointerTypeFunc)type;
831         if(set) pprop->set= (PropPointerSetFunc)set;
832 }
833
834 void RNA_def_property_collection_funcs(PropertyRNA *prop, char *begin, char *next, char *end, char *get, char *type, char *length, char *lookupint, char *lookupstring)
835 {
836         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
837
838         if(begin) cprop->begin= (PropCollectionBeginFunc)begin;
839         if(next) cprop->next= (PropCollectionNextFunc)next;
840         if(end) cprop->end= (PropCollectionEndFunc)end;
841         if(get) cprop->get= (PropCollectionGetFunc)get;
842         if(type) cprop->type= (PropCollectionTypeFunc)type;
843         if(length) cprop->length= (PropCollectionLengthFunc)length;
844         if(lookupint) cprop->lookupint= (PropCollectionLookupIntFunc)lookupint;
845         if(lookupstring) cprop->lookupstring= (PropCollectionLookupStringFunc)lookupstring;
846 }
847