Merge from 2.5 r20991 through r21037
[blender.git] / source / blender / makesrna / intern / rna_access.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 <stdlib.h>
26 #include <string.h>
27
28 #include "MEM_guardedalloc.h"
29
30 #include "DNA_ID.h"
31 #include "DNA_windowmanager_types.h"
32
33 #include "BLI_blenlib.h"
34 #include "BLI_dynstr.h"
35 #include "BLI_ghash.h"
36
37 #include "BKE_context.h"
38 #include "BKE_idprop.h"
39 #include "BKE_report.h"
40 #include "BKE_utildefines.h"
41
42 #include "WM_api.h"
43
44 #include "RNA_access.h"
45 #include "RNA_define.h"
46 #include "RNA_types.h"
47
48 #include "rna_internal.h"
49
50 /* Init/Exit */
51
52 void RNA_init()
53 {
54         StructRNA *srna;
55         PropertyRNA *prop;
56
57         for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
58                 if(!srna->cont.prophash) {
59                         srna->cont.prophash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp);
60
61                         for(prop=srna->cont.properties.first; prop; prop=prop->next)
62                                 if(!(prop->flag & PROP_BUILTIN))
63                                         BLI_ghash_insert(srna->cont.prophash, (void*)prop->identifier, prop);
64                 }
65         }
66 }
67
68 void RNA_exit()
69 {
70         StructRNA *srna;
71
72         for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
73                 if(srna->cont.prophash) {
74                         BLI_ghash_free(srna->cont.prophash, NULL, NULL);
75                         srna->cont.prophash= NULL;
76                 }
77         }
78
79         RNA_free(&BLENDER_RNA);
80 }
81
82 /* Pointer */
83
84 PointerRNA PointerRNA_NULL = {{0}, 0, 0};
85
86 void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr)
87 {
88         r_ptr->id.data= NULL;
89         r_ptr->type= &RNA_Main;
90         r_ptr->data= main;
91 }
92
93 void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
94 {
95         PointerRNA tmp;
96         StructRNA *type, *idtype= NULL;
97
98         if(id) {
99                 memset(&tmp, 0, sizeof(tmp));
100                 tmp.data= id;
101                 idtype= rna_ID_refine(&tmp);
102                 
103                 while(idtype->refine) {
104                         type= idtype->refine(&tmp);
105
106                         if(type == idtype)
107                                 break;
108                         else
109                                 idtype= type;
110                 }
111         }
112         
113         r_ptr->id.data= id;
114         r_ptr->type= idtype;
115         r_ptr->data= id;
116 }
117
118 void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
119 {
120         PointerRNA tmp;
121         StructRNA *idtype= NULL;
122
123         if(id) {
124                 memset(&tmp, 0, sizeof(tmp));
125                 tmp.data= id;
126                 idtype= rna_ID_refine(&tmp);
127         }
128
129         r_ptr->id.data= id;
130         r_ptr->type= type;
131         r_ptr->data= data;
132
133         if(data) {
134                 while(r_ptr->type && r_ptr->type->refine) {
135                         StructRNA *rtype= r_ptr->type->refine(r_ptr);
136
137                         if(rtype == r_ptr->type)
138                                 break;
139                         else
140                                 r_ptr->type= rtype;
141                 }
142         }
143 }
144
145 static void rna_pointer_inherit_id(StructRNA *type, PointerRNA *parent, PointerRNA *ptr)
146 {
147         if(type && type->flag & STRUCT_ID) {
148                 ptr->id.data= ptr->data;
149         }
150         else {
151                 ptr->id.data= parent->id.data;
152         }
153 }
154
155 void RNA_blender_rna_pointer_create(PointerRNA *r_ptr)
156 {
157         r_ptr->id.data= NULL;
158         r_ptr->type= &RNA_BlenderRNA;
159         r_ptr->data= &BLENDER_RNA;
160 }
161
162 PointerRNA rna_pointer_inherit_refine(PointerRNA *ptr, StructRNA *type, void *data)
163 {
164         PointerRNA result;
165
166         if(data) {
167                 result.data= data;
168                 result.type= type;
169                 rna_pointer_inherit_id(type, ptr, &result);
170
171                 while(result.type->refine) {
172                         type= result.type->refine(&result);
173
174                         if(type == result.type)
175                                 break;
176                         else
177                                 result.type= type;
178                 }
179         }
180         else
181                 memset(&result, 0, sizeof(result));
182         
183         return result;
184 }
185
186 /* ID Properties */
187
188 IDProperty *RNA_struct_idproperties(PointerRNA *ptr, int create)
189 {
190         StructRNA *type= ptr->type;
191
192         if(type && type->idproperties)
193                 return type->idproperties(ptr, create);
194         
195         return NULL;
196 }
197
198 static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name)
199 {
200         IDProperty *group= RNA_struct_idproperties(ptr, 0);
201         IDProperty *idprop;
202
203         if(group) {
204                 for(idprop=group->data.group.first; idprop; idprop=idprop->next)
205                         if(strcmp(idprop->name, name) == 0)
206                                 return idprop;
207         }
208         
209         return NULL;
210 }
211
212 static int rna_idproperty_verify_valid(PropertyRNA *prop, IDProperty *idprop)
213 {
214         /* this verifies if the idproperty actually matches the property
215          * description and otherwise removes it. this is to ensure that
216          * rna property access is type safe, e.g. if you defined the rna
217          * to have a certain array length you can count on that staying so */
218         
219         switch(idprop->type) {
220                 case IDP_IDPARRAY:
221                         if(prop->type != PROP_COLLECTION)
222                                 return 0;
223                         break;
224                 case IDP_ARRAY:
225                         if(prop->arraylength != idprop->len)
226                                 return 0;
227
228                         if(idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT)
229                                 return 0;
230                         if(idprop->subtype == IDP_INT && !ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
231                                 return 0;
232
233                         break;
234                 case IDP_INT:
235                         if(!ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
236                                 return 0;
237                         break;
238                 case IDP_FLOAT:
239                 case IDP_DOUBLE:
240                         if(prop->type != PROP_FLOAT)
241                                 return 0;
242                         break;
243                 case IDP_STRING:
244                         if(prop->type != PROP_STRING)
245                                 return 0;
246                         break;
247                 case IDP_GROUP:
248                         if(prop->type != PROP_POINTER)
249                                 return 0;
250                         break;
251                 default:
252                         return 0;
253         }
254
255         return 1;
256 }
257
258 static PropertyRNA *typemap[IDP_NUMTYPES] =
259         {(PropertyRNA*)&rna_IDProperty_string,
260          (PropertyRNA*)&rna_IDProperty_int,
261          (PropertyRNA*)&rna_IDProperty_float,
262          NULL, NULL, NULL,
263          (PropertyRNA*)&rna_IDProperty_group, NULL,
264          (PropertyRNA*)&rna_IDProperty_double};
265
266 static PropertyRNA *arraytypemap[IDP_NUMTYPES] =
267         {NULL, (PropertyRNA*)&rna_IDProperty_int_array,
268          (PropertyRNA*)&rna_IDProperty_float_array,
269          NULL, NULL, NULL,
270          (PropertyRNA*)&rna_IDProperty_collection, NULL,
271          (PropertyRNA*)&rna_IDProperty_double_array};
272
273 IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr)
274 {
275         /* This is quite a hack, but avoids some complexity in the API. we
276          * pass IDProperty structs as PropertyRNA pointers to the outside.
277          * We store some bytes in PropertyRNA structs that allows us to
278          * distinguish it from IDProperty structs. If it is an ID property,
279          * we look up an IDP PropertyRNA based on the type, and set the data
280          * pointer to the IDProperty. */
281
282         if((*prop)->magic == RNA_MAGIC) {
283                 if((*prop)->flag & PROP_IDPROPERTY) {
284                         IDProperty *idprop= rna_idproperty_find(ptr, (*prop)->identifier);
285
286                         if(idprop && !rna_idproperty_verify_valid(*prop, idprop)) {
287                                 IDProperty *group= RNA_struct_idproperties(ptr, 0);
288
289                                 IDP_RemFromGroup(group, idprop);
290                                 IDP_FreeProperty(idprop);
291                                 MEM_freeN(idprop);
292                                 return NULL;
293                         }
294
295                         return idprop;
296                 }
297                 else
298                         return NULL;
299         }
300
301         {
302                 IDProperty *idprop= (IDProperty*)(*prop);
303
304                 if(idprop->type == IDP_ARRAY)
305                         *prop= arraytypemap[(int)(idprop->subtype)];
306                 else 
307                         *prop= typemap[(int)(idprop->type)];
308
309                 return idprop;
310         }
311 }
312
313 PropertyRNA *rna_ensure_property(PropertyRNA *prop)
314 {
315         /* the quick version if we don't need the idproperty */
316
317         if(prop->magic == RNA_MAGIC)
318                 return prop;
319
320         {
321                 IDProperty *idprop= (IDProperty*)prop;
322
323                 if(idprop->type == IDP_ARRAY)
324                         return arraytypemap[(int)(idprop->subtype)];
325                 else 
326                         return typemap[(int)(idprop->type)];
327         }
328 }
329
330 const char *rna_ensure_property_identifier(PropertyRNA *prop)
331 {
332         if(prop->magic == RNA_MAGIC)
333                 return prop->identifier;
334         else
335                 return ((IDProperty*)prop)->name;
336 }
337
338 const char *rna_ensure_property_name(PropertyRNA *prop)
339 {
340         if(prop->magic == RNA_MAGIC)
341                 return prop->name;
342         else
343                 return ((IDProperty*)prop)->name;
344 }
345
346 int rna_ensure_property_array_length(PropertyRNA *prop)
347 {
348         if(prop->magic == RNA_MAGIC)
349                 return prop->arraylength;
350         else {
351                 IDProperty *idprop= (IDProperty*)prop;
352
353                 if(idprop->type == IDP_ARRAY)
354                         return idprop->len;
355                 else
356                         return 0;
357         }
358 }
359
360 /* Structs */
361
362 const char *RNA_struct_identifier(StructRNA *type)
363 {
364         return type->identifier;
365 }
366
367 const char *RNA_struct_ui_name(StructRNA *type)
368 {
369         return type->name;
370 }
371
372 int RNA_struct_ui_icon(StructRNA *type)
373 {
374         if(type)
375                 return type->icon;
376         else
377                 return ICON_DOT;
378 }
379
380 const char *RNA_struct_ui_description(StructRNA *type)
381 {
382         return type->description;
383 }
384
385 PropertyRNA *RNA_struct_name_property(StructRNA *type)
386 {
387         return type->nameproperty;
388 }
389
390 PropertyRNA *RNA_struct_iterator_property(StructRNA *type)
391 {
392         return type->iteratorproperty;
393 }
394
395 int RNA_struct_is_ID(StructRNA *type)
396 {
397         return (type->flag & STRUCT_ID) != 0;
398 }
399
400 int RNA_struct_is_a(StructRNA *type, StructRNA *srna)
401 {
402         StructRNA *base;
403
404         if(!type)
405                 return 0;
406
407         /* ptr->type is always maximally refined */
408         for(base=type; base; base=base->base)
409                 if(base == srna)
410                         return 1;
411         
412         return 0;
413 }
414
415 PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
416 {
417         PropertyRNA *iterprop= RNA_struct_iterator_property(ptr->type);
418         PointerRNA propptr;
419
420         if(RNA_property_collection_lookup_string(ptr, iterprop, identifier, &propptr))
421                 return propptr.data;
422         
423         return NULL;
424 }
425
426 /* Find the property which uses the given nested struct */
427 PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
428 {
429         CollectionPropertyIterator iter;
430         PropertyRNA *iterprop, *prop;
431         int i = 0;
432
433         iterprop= RNA_struct_iterator_property(ptr->type);
434         RNA_property_collection_begin(ptr, iterprop, &iter);
435         prop= NULL;
436
437         for(; iter.valid; RNA_property_collection_next(&iter), i++) {
438                 /* This assumes that there can only be one user of this nested struct */
439                 if (RNA_property_pointer_type(ptr, iter.ptr.data) == srna) {
440                         prop= iter.ptr.data;
441                         break;
442                 }
443         }
444
445         RNA_property_collection_end(&iter);
446
447         return prop;
448 }
449
450 const struct ListBase *RNA_struct_defined_properties(StructRNA *srna)
451 {
452         return &srna->cont.properties;
453 }
454
455 FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier)
456 {
457         PointerRNA tptr;
458         CollectionPropertyIterator iter;
459         PropertyRNA *iterprop;
460         FunctionRNA *func;
461         int i = 0;
462
463         RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr);
464         iterprop= RNA_struct_find_property(&tptr, "functions");
465
466         RNA_property_collection_begin(&tptr, iterprop, &iter);
467         func= NULL;
468
469         for(; iter.valid; RNA_property_collection_next(&iter), i++) {
470                 if(strcmp(identifier, RNA_function_identifier(iter.ptr.data)) == 0) {
471                         func= iter.ptr.data;
472                         break;
473                 }
474         }
475
476         RNA_property_collection_end(&iter);
477
478         return func;
479 }
480
481 const struct ListBase *RNA_struct_defined_functions(StructRNA *srna)
482 {
483         return &srna->functions;
484 }
485
486 StructRegisterFunc RNA_struct_register(StructRNA *type)
487 {
488         return type->reg;
489 }
490
491 StructUnregisterFunc RNA_struct_unregister(StructRNA *type)
492 {
493         do {
494                 if(type->unreg)
495                         return type->unreg;
496         } while((type=type->base));
497
498         return NULL;
499 }
500
501 void *RNA_struct_py_type_get(StructRNA *srna)
502 {
503         return srna->py_type;
504 }
505
506 void RNA_struct_py_type_set(StructRNA *srna, void *py_type)
507 {
508         srna->py_type= py_type;
509 }
510
511 void *RNA_struct_blender_type_get(StructRNA *srna)
512 {
513         return srna->blender_type;
514 }
515
516 void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
517 {
518         srna->blender_type= blender_type;
519 }
520
521 /* Property Information */
522
523 const char *RNA_property_identifier(PropertyRNA *prop)
524 {
525         return rna_ensure_property_identifier(prop);
526 }
527
528 PropertyType RNA_property_type(PropertyRNA *prop)
529 {
530         return rna_ensure_property(prop)->type;
531 }
532
533 PropertySubType RNA_property_subtype(PropertyRNA *prop)
534 {
535         return rna_ensure_property(prop)->subtype;
536 }
537
538 int RNA_property_flag(PropertyRNA *prop)
539 {
540         return rna_ensure_property(prop)->flag;
541 }
542
543 int RNA_property_array_length(PropertyRNA *prop)
544 {
545         return rna_ensure_property_array_length(prop);
546 }
547
548 void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
549 {
550         IntPropertyRNA *iprop= (IntPropertyRNA*)rna_ensure_property(prop);
551
552         if(iprop->range) {
553                 iprop->range(ptr, hardmin, hardmax);
554         }
555         else {
556                 *hardmin= iprop->hardmin;
557                 *hardmax= iprop->hardmax;
558         }
559 }
560
561 void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
562 {
563         IntPropertyRNA *iprop= (IntPropertyRNA*)rna_ensure_property(prop);
564         int hardmin, hardmax;
565         
566         if(iprop->range) {
567                 iprop->range(ptr, &hardmin, &hardmax);
568                 *softmin= MAX2(iprop->softmin, hardmin);
569                 *softmax= MIN2(iprop->softmax, hardmax);
570         }
571         else {
572                 *softmin= iprop->softmin;
573                 *softmax= iprop->softmax;
574         }
575
576         *step= iprop->step;
577 }
578
579 void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
580 {
581         FloatPropertyRNA *fprop= (FloatPropertyRNA*)rna_ensure_property(prop);
582
583         if(fprop->range) {
584                 fprop->range(ptr, hardmin, hardmax);
585         }
586         else {
587                 *hardmin= fprop->hardmin;
588                 *hardmax= fprop->hardmax;
589         }
590 }
591
592 void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision)
593 {
594         FloatPropertyRNA *fprop= (FloatPropertyRNA*)rna_ensure_property(prop);
595         float hardmin, hardmax;
596
597         if(fprop->range) {
598                 fprop->range(ptr, &hardmin, &hardmax);
599                 *softmin= MAX2(fprop->softmin, hardmin);
600                 *softmax= MIN2(fprop->softmax, hardmax);
601         }
602         else {
603                 *softmin= fprop->softmin;
604                 *softmax= fprop->softmax;
605         }
606
607         *step= fprop->step;
608         *precision= (float)fprop->precision;
609 }
610
611 int RNA_property_string_maxlength(PropertyRNA *prop)
612 {
613         StringPropertyRNA *sprop= (StringPropertyRNA*)rna_ensure_property(prop);
614         return sprop->maxlength;
615 }
616
617 StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
618 {
619         prop= rna_ensure_property(prop);
620
621         if(prop->type == PROP_POINTER) {
622                 PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
623
624                 if(pprop->typef)
625                         return pprop->typef(ptr);
626                 else if(pprop->type)
627                         return pprop->type;
628         }
629         else if(prop->type == PROP_COLLECTION) {
630                 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
631
632                 if(cprop->type)
633                         return cprop->type;
634         }
635
636         return &RNA_UnknownType;
637 }
638
639 void RNA_property_enum_items(PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **item, int *totitem)
640 {
641         EnumPropertyRNA *eprop= (EnumPropertyRNA*)rna_ensure_property(prop);
642         int tot;
643
644         if(eprop->itemf) {
645                 *item= eprop->itemf(ptr);
646                 for(tot=0; (*item)[tot].identifier; tot++);
647                 *totitem= tot;
648         }
649         else {
650                 *item= eprop->item;
651                 *totitem= eprop->totitem;
652         }
653 }
654
655 int RNA_property_enum_value(PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value)
656 {       
657         const EnumPropertyItem *item;
658         int totitem, i;
659         
660         RNA_property_enum_items(ptr, prop, &item, &totitem);
661         
662         for(i=0; i<totitem; i++) {
663                 if(strcmp(item[i].identifier, identifier)==0) {
664                         *value = item[i].value;
665                         return 1;
666                 }
667         }
668
669         return 0;
670 }
671
672 int RNA_property_enum_identifier(PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
673 {       
674         const EnumPropertyItem *item;
675         int totitem, i;
676         
677         RNA_property_enum_items(ptr, prop, &item, &totitem);
678         
679         for(i=0; i<totitem; i++) {
680                 if(item[i].value==value) {
681                         *identifier = item[i].identifier;
682                         return 1;
683                 }
684         }
685         
686         return 0;
687 }
688
689 const char *RNA_property_ui_name(PropertyRNA *prop)
690 {
691         return rna_ensure_property_name(prop);
692 }
693
694 const char *RNA_property_ui_description(PropertyRNA *prop)
695 {
696         return rna_ensure_property(prop)->description;
697 }
698
699 int RNA_property_ui_icon(PropertyRNA *prop)
700 {
701         return rna_ensure_property(prop)->icon;
702 }
703
704 int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
705 {
706         ID *id;
707         int flag;
708
709         prop= rna_ensure_property(prop);
710
711         if(prop->editable)
712                 flag= prop->editable(ptr);
713         else
714                 flag= prop->flag;
715         
716         id= ptr->id.data;
717
718         return (flag & PROP_EDITABLE) && (!id || !id->lib);
719 }
720
721 int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
722 {
723         int flag;
724
725         prop= rna_ensure_property(prop);
726
727         if(!(prop->flag & PROP_ANIMATEABLE))
728                 return 0;
729
730         if(prop->editable)
731                 flag= prop->editable(ptr);
732         else
733                 flag= prop->flag;
734
735         return (flag & PROP_EDITABLE);
736 }
737
738 int RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop)
739 {
740         /* would need to ask animation system */
741
742         return 0;
743 }
744
745 void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
746 {
747         prop= rna_ensure_property(prop);
748
749         if(prop->update)
750                 prop->update(C, ptr);
751         if(prop->noteflag)
752                 WM_event_add_notifier(C, prop->noteflag, ptr->id.data);
753 }
754
755 /* Property Data */
756
757 int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
758 {
759         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
760         IDProperty *idprop;
761
762         if((idprop=rna_idproperty_check(&prop, ptr)))
763                 return IDP_Int(idprop);
764         else if(bprop->get)
765                 return bprop->get(ptr);
766         else
767                 return bprop->defaultvalue;
768 }
769
770 void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
771 {
772         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
773         IDProperty *idprop;
774
775         if((idprop=rna_idproperty_check(&prop, ptr)))
776                 IDP_Int(idprop)= value;
777         else if(bprop->set)
778                 bprop->set(ptr, value);
779         else if(prop->flag & PROP_EDITABLE) {
780                 IDPropertyTemplate val = {0};
781                 IDProperty *group;
782
783                 val.i= value;
784
785                 group= RNA_struct_idproperties(ptr, 1);
786                 if(group)
787                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
788         }
789 }
790
791 void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
792 {
793         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
794         IDProperty *idprop;
795
796         if((idprop=rna_idproperty_check(&prop, ptr))) {
797                 if(prop->arraylength == 0)
798                         values[0]= RNA_property_boolean_get(ptr, prop);
799                 else
800                         memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
801         }
802         else if(prop->arraylength == 0)
803                 values[0]= RNA_property_boolean_get(ptr, prop);
804         else if(bprop->getarray)
805                 bprop->getarray(ptr, values);
806         else if(bprop->defaultarray)
807                 memcpy(values, bprop->defaultarray, sizeof(int)*prop->arraylength);
808         else
809                 memset(values, 0, sizeof(int)*prop->arraylength);
810 }
811
812 int RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
813 {
814         int tmp[RNA_MAX_ARRAY];
815
816         RNA_property_boolean_get_array(ptr, prop, tmp);
817         return tmp[index];
818 }
819
820 void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
821 {
822         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
823         IDProperty *idprop;
824
825         if((idprop=rna_idproperty_check(&prop, ptr))) {
826                 if(prop->arraylength == 0)
827                         IDP_Int(idprop)= values[0];
828                 else
829                         memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
830         }
831         else if(prop->arraylength == 0)
832                 RNA_property_boolean_set(ptr, prop, values[0]);
833         else if(bprop->setarray)
834                 bprop->setarray(ptr, values);
835         else if(prop->flag & PROP_EDITABLE) {
836                 IDPropertyTemplate val = {0};
837                 IDProperty *group;
838
839                 val.array.len= prop->arraylength;
840                 val.array.type= IDP_INT;
841
842                 group= RNA_struct_idproperties(ptr, 1);
843                 if(group) {
844                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
845                         IDP_AddToGroup(group, idprop);
846                         memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
847                 }
848         }
849 }
850
851 void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
852 {
853         int tmp[RNA_MAX_ARRAY];
854
855         RNA_property_boolean_get_array(ptr, prop, tmp);
856         tmp[index]= value;
857         RNA_property_boolean_set_array(ptr, prop, tmp);
858 }
859
860 int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
861 {
862         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
863         IDProperty *idprop;
864
865         if((idprop=rna_idproperty_check(&prop, ptr)))
866                 return IDP_Int(idprop);
867         else if(iprop->get)
868                 return iprop->get(ptr);
869         else
870                 return iprop->defaultvalue;
871 }
872
873 void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
874 {
875         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
876         IDProperty *idprop;
877
878         if((idprop=rna_idproperty_check(&prop, ptr)))
879                 IDP_Int(idprop)= value;
880         else if(iprop->set)
881                 iprop->set(ptr, value);
882         else if(prop->flag & PROP_EDITABLE) {
883                 IDPropertyTemplate val = {0};
884                 IDProperty *group;
885
886                 val.i= value;
887
888                 group= RNA_struct_idproperties(ptr, 1);
889                 if(group)
890                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
891         }
892 }
893
894 void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
895 {
896         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
897         IDProperty *idprop;
898
899         if((idprop=rna_idproperty_check(&prop, ptr))) {
900                 if(prop->arraylength == 0)
901                         values[0]= RNA_property_int_get(ptr, prop);
902                 else
903                         memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
904         }
905         else if(prop->arraylength == 0)
906                 values[0]= RNA_property_int_get(ptr, prop);
907         else if(iprop->getarray)
908                 iprop->getarray(ptr, values);
909         else if(iprop->defaultarray)
910                 memcpy(values, iprop->defaultarray, sizeof(int)*prop->arraylength);
911         else
912                 memset(values, 0, sizeof(int)*prop->arraylength);
913 }
914
915 int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
916 {
917         int tmp[RNA_MAX_ARRAY];
918
919         RNA_property_int_get_array(ptr, prop, tmp);
920         return tmp[index];
921 }
922
923 void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
924 {
925         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
926         IDProperty *idprop;
927
928         if((idprop=rna_idproperty_check(&prop, ptr))) {
929                 if(prop->arraylength == 0)
930                         IDP_Int(idprop)= values[0];
931                 else
932                         memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);\
933         }
934         else if(prop->arraylength == 0)
935                 RNA_property_int_set(ptr, prop, values[0]);
936         else if(iprop->setarray)
937                 iprop->setarray(ptr, values);
938         else if(prop->flag & PROP_EDITABLE) {
939                 IDPropertyTemplate val = {0};
940                 IDProperty *group;
941
942                 val.array.len= prop->arraylength;
943                 val.array.type= IDP_INT;
944
945                 group= RNA_struct_idproperties(ptr, 1);
946                 if(group) {
947                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
948                         IDP_AddToGroup(group, idprop);
949                         memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
950                 }
951         }
952 }
953
954 void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
955 {
956         int tmp[RNA_MAX_ARRAY];
957
958         RNA_property_int_get_array(ptr, prop, tmp);
959         tmp[index]= value;
960         RNA_property_int_set_array(ptr, prop, tmp);
961 }
962
963 float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
964 {
965         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
966         IDProperty *idprop;
967
968         if((idprop=rna_idproperty_check(&prop, ptr))) {
969                 if(idprop->type == IDP_FLOAT)
970                         return IDP_Float(idprop);
971                 else
972                         return (float)IDP_Double(idprop);
973         }
974         else if(fprop->get)
975                 return fprop->get(ptr);
976         else
977                 return fprop->defaultvalue;
978 }
979
980 void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
981 {
982         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
983         IDProperty *idprop;
984
985         if((idprop=rna_idproperty_check(&prop, ptr))) {
986                 if(idprop->type == IDP_FLOAT)
987                         IDP_Float(idprop)= value;
988                 else
989                         IDP_Double(idprop)= value;
990         }
991         else if(fprop->set) {
992                 fprop->set(ptr, value);
993         }
994         else if(prop->flag & PROP_EDITABLE) {
995                 IDPropertyTemplate val = {0};
996                 IDProperty *group;
997
998                 val.f= value;
999
1000                 group= RNA_struct_idproperties(ptr, 1);
1001                 if(group)
1002                         IDP_AddToGroup(group, IDP_New(IDP_FLOAT, val, (char*)prop->identifier));
1003         }
1004 }
1005
1006 void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
1007 {
1008         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1009         IDProperty *idprop;
1010         int i;
1011
1012         if((idprop=rna_idproperty_check(&prop, ptr))) {
1013                 if(prop->arraylength == 0)
1014                         values[0]= RNA_property_float_get(ptr, prop);
1015                 else if(idprop->subtype == IDP_FLOAT) {
1016                         memcpy(values, IDP_Array(idprop), sizeof(float)*idprop->len);
1017                 }
1018                 else {
1019                         for(i=0; i<idprop->len; i++)
1020                                 values[i]=  (float)(((double*)IDP_Array(idprop))[i]);
1021                 }
1022         }
1023         else if(prop->arraylength == 0)
1024                 values[0]= RNA_property_float_get(ptr, prop);
1025         else if(fprop->getarray)
1026                 fprop->getarray(ptr, values);
1027         else if(fprop->defaultarray)
1028                 memcpy(values, fprop->defaultarray, sizeof(float)*prop->arraylength);
1029         else
1030                 memset(values, 0, sizeof(float)*prop->arraylength);
1031 }
1032
1033 float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
1034 {
1035         float tmp[RNA_MAX_ARRAY];
1036
1037         RNA_property_float_get_array(ptr, prop, tmp);
1038         return tmp[index];
1039 }
1040
1041 void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
1042 {
1043         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
1044         IDProperty *idprop;
1045         int i;
1046
1047         if((idprop=rna_idproperty_check(&prop, ptr))) {
1048                 if(prop->arraylength == 0)
1049                         IDP_Double(idprop)= values[0];
1050                 else if(idprop->subtype == IDP_FLOAT) {
1051                         memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len);
1052                 }
1053                 else {
1054                         for(i=0; i<idprop->len; i++)
1055                                 ((double*)IDP_Array(idprop))[i]= values[i];
1056                 }
1057         }
1058         else if(prop->arraylength == 0)
1059                 RNA_property_float_set(ptr, prop, values[0]);
1060         else if(fprop->setarray) {
1061                 fprop->setarray(ptr, values);
1062         }
1063         else if(prop->flag & PROP_EDITABLE) {
1064                 IDPropertyTemplate val = {0};
1065                 IDProperty *group;
1066
1067                 val.array.len= prop->arraylength;
1068                 val.array.type= IDP_FLOAT;
1069
1070                 group= RNA_struct_idproperties(ptr, 1);
1071                 if(group) {
1072                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
1073                         IDP_AddToGroup(group, idprop);
1074                         memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len);
1075                 }
1076         }
1077 }
1078
1079 void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
1080 {
1081         float tmp[RNA_MAX_ARRAY];
1082
1083         RNA_property_float_get_array(ptr, prop, tmp);
1084         tmp[index]= value;
1085         RNA_property_float_set_array(ptr, prop, tmp);
1086 }
1087
1088 void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
1089 {
1090         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1091         IDProperty *idprop;
1092
1093         if((idprop=rna_idproperty_check(&prop, ptr)))
1094                 strcpy(value, IDP_String(idprop));
1095         else if(sprop->get)
1096                 sprop->get(ptr, value);
1097         else
1098                 strcpy(value, sprop->defaultvalue);
1099 }
1100
1101 char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen)
1102 {
1103         char *buf;
1104         int length;
1105
1106         length= RNA_property_string_length(ptr, prop);
1107
1108         if(length+1 < fixedlen)
1109                 buf= fixedbuf;
1110         else
1111                 buf= MEM_callocN(sizeof(char)*(length+1), "RNA_string_get_alloc");
1112
1113         RNA_property_string_get(ptr, prop, buf);
1114
1115         return buf;
1116 }
1117
1118 int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
1119 {
1120         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1121         IDProperty *idprop;
1122
1123         if((idprop=rna_idproperty_check(&prop, ptr)))
1124                 return strlen(IDP_String(idprop));
1125         else if(sprop->length)
1126                 return sprop->length(ptr);
1127         else
1128                 return strlen(sprop->defaultvalue);
1129 }
1130
1131 void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
1132 {
1133         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
1134         IDProperty *idprop;
1135
1136         if((idprop=rna_idproperty_check(&prop, ptr)))
1137                 IDP_AssignString(idprop, (char*)value);
1138         else if(sprop->set)
1139                 sprop->set(ptr, value);
1140         else if(prop->flag & PROP_EDITABLE) {
1141                 IDPropertyTemplate val = {0};
1142                 IDProperty *group;
1143
1144                 val.str= (char*)value;
1145
1146                 group= RNA_struct_idproperties(ptr, 1);
1147                 if(group)
1148                         IDP_AddToGroup(group, IDP_New(IDP_STRING, val, (char*)prop->identifier));
1149         }
1150 }
1151
1152 int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
1153 {
1154         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
1155         IDProperty *idprop;
1156
1157         if((idprop=rna_idproperty_check(&prop, ptr)))
1158                 return IDP_Int(idprop);
1159         else if(eprop->get)
1160                 return eprop->get(ptr);
1161         else
1162                 return eprop->defaultvalue;
1163 }
1164
1165
1166 void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
1167 {
1168         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
1169         IDProperty *idprop;
1170
1171         if((idprop=rna_idproperty_check(&prop, ptr)))
1172                 IDP_Int(idprop)= value;
1173         else if(eprop->set) {
1174                 eprop->set(ptr, value);
1175         }
1176         else if(prop->flag & PROP_EDITABLE) {
1177                 IDPropertyTemplate val = {0};
1178                 IDProperty *group;
1179
1180                 val.i= value;
1181
1182                 group= RNA_struct_idproperties(ptr, 1);
1183                 if(group)
1184                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
1185         }
1186 }
1187
1188 PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
1189 {
1190         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
1191         IDProperty *idprop;
1192
1193         if((idprop=rna_idproperty_check(&prop, ptr))) {
1194                 pprop= (PointerPropertyRNA*)prop;
1195
1196                 /* for groups, data is idprop itself */
1197                 return rna_pointer_inherit_refine(ptr, pprop->type, idprop);
1198         }
1199         else if(pprop->get) {
1200                 return pprop->get(ptr);
1201         }
1202         else {
1203                 PointerRNA result;
1204                 memset(&result, 0, sizeof(result));
1205                 return result;
1206         }
1207 }
1208
1209 void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value)
1210 {
1211         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
1212
1213         if(pprop->set)
1214                 pprop->set(ptr, ptr_value);
1215 }
1216
1217 void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop)
1218 {
1219         IDProperty *idprop;
1220
1221         if((idprop=rna_idproperty_check(&prop, ptr))) {
1222                 /* already exists */
1223         }
1224         else if(prop->flag & PROP_IDPROPERTY) {
1225                 IDPropertyTemplate val = {0};
1226                 IDProperty *group;
1227
1228                 val.i= 0;
1229
1230                 group= RNA_struct_idproperties(ptr, 1);
1231                 if(group)
1232                         IDP_AddToGroup(group, IDP_New(IDP_GROUP, val, (char*)prop->identifier));
1233         }
1234         else
1235                 printf("RNA_property_pointer_add %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);
1236 }
1237
1238 void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop)
1239 {
1240         IDProperty *idprop, *group;
1241
1242         if((idprop=rna_idproperty_check(&prop, ptr))) {
1243                 group= RNA_struct_idproperties(ptr, 0);
1244                 
1245                 if(group) {
1246                         IDP_RemFromGroup(group, idprop);
1247                         IDP_FreeProperty(idprop);
1248                         MEM_freeN(idprop);
1249                 }
1250         }
1251         else
1252                 printf("RNA_property_pointer_remove %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);
1253 }
1254
1255 static void rna_property_collection_get_idp(CollectionPropertyIterator *iter)
1256 {
1257         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
1258
1259         iter->ptr.data= rna_iterator_array_get(iter);
1260         iter->ptr.type= cprop->type;
1261         rna_pointer_inherit_id(cprop->type, &iter->parent, &iter->ptr);
1262 }
1263
1264 void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter)
1265 {
1266         IDProperty *idprop;
1267
1268         memset(iter, 0, sizeof(*iter));
1269
1270         if((idprop=rna_idproperty_check(&prop, ptr)) || (prop->flag & PROP_IDPROPERTY)) {
1271                 iter->parent= *ptr;
1272                 iter->prop= prop;
1273
1274                 if(idprop)
1275                         rna_iterator_array_begin(iter, IDP_IDPArray(idprop), sizeof(IDProperty), idprop->len, NULL);
1276                 else
1277                         rna_iterator_array_begin(iter, NULL, sizeof(IDProperty), 0, NULL);
1278
1279                 if(iter->valid)
1280                         rna_property_collection_get_idp(iter);
1281
1282                 iter->idprop= 1;
1283         }
1284         else {
1285                 CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1286                 cprop->begin(iter, ptr);
1287         }
1288 }
1289
1290 void RNA_property_collection_next(CollectionPropertyIterator *iter)
1291 {
1292         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
1293
1294         if(iter->idprop) {
1295                 rna_iterator_array_next(iter);
1296
1297                 if(iter->valid)
1298                         rna_property_collection_get_idp(iter);
1299         }
1300         else
1301                 cprop->next(iter);
1302 }
1303
1304 void RNA_property_collection_end(CollectionPropertyIterator *iter)
1305 {
1306         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
1307
1308         if(iter->idprop)
1309                 rna_iterator_array_end(iter);
1310         else
1311                 cprop->end(iter);
1312 }
1313
1314 int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
1315 {
1316         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1317         IDProperty *idprop;
1318
1319         if((idprop=rna_idproperty_check(&prop, ptr))) {
1320                 return idprop->len;
1321         }
1322         else if(cprop->length) {
1323                 return cprop->length(ptr);
1324         }
1325         else {
1326                 CollectionPropertyIterator iter;
1327                 int length= 0;
1328
1329                 RNA_property_collection_begin(ptr, prop, &iter);
1330                 for(; iter.valid; RNA_property_collection_next(&iter))
1331                         length++;
1332                 RNA_property_collection_end(&iter);
1333
1334                 return length;
1335         }
1336 }
1337
1338 void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
1339 {
1340         IDProperty *idprop;
1341         //CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1342
1343         if((idprop=rna_idproperty_check(&prop, ptr))) {
1344                 IDPropertyTemplate val = {0};
1345                 IDProperty *item;
1346
1347                 item= IDP_New(IDP_GROUP, val, "");
1348                 IDP_AppendArray(idprop, item);
1349                 IDP_FreeProperty(item);
1350                 MEM_freeN(item);
1351         }
1352         else if(prop->flag & PROP_IDPROPERTY) {
1353                 IDProperty *group, *item;
1354                 IDPropertyTemplate val = {0};
1355
1356                 group= RNA_struct_idproperties(ptr, 1);
1357                 if(group) {
1358                         idprop= IDP_NewIDPArray(prop->identifier);
1359                         IDP_AddToGroup(group, idprop);
1360
1361                         item= IDP_New(IDP_GROUP, val, "");
1362                         IDP_AppendArray(idprop, item);
1363                         IDP_FreeProperty(item);
1364                         MEM_freeN(item);
1365                 }
1366         }
1367 #if 0
1368         else if(cprop->add){
1369                 if(!(cprop->add->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
1370                         ParameterList *params= RNA_parameter_list_create(ptr, cprop->add);
1371                         RNA_function_call(NULL, NULL, ptr, cprop->add, params);
1372                         RNA_parameter_list_free(params);
1373                 }
1374         }
1375 #endif
1376         else
1377                 printf("RNA_property_collection_add %s.%s: not implemented for this property.\n", ptr->type->identifier, prop->identifier);
1378
1379         if(r_ptr) {
1380                 if(idprop) {
1381                         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1382
1383                         r_ptr->data= IDP_GetIndexArray(idprop, idprop->len-1);
1384                         r_ptr->type= cprop->type;
1385                         rna_pointer_inherit_id(NULL, ptr, r_ptr);
1386                 }
1387                 else
1388                         memset(r_ptr, 0, sizeof(*r_ptr));
1389         }
1390 }
1391
1392 void RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
1393 {
1394         IDProperty *idprop;
1395         //CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1396
1397         if((idprop=rna_idproperty_check(&prop, ptr))) {
1398                 IDProperty tmp, *array;
1399                 int len;
1400
1401                 len= idprop->len;
1402                 array= IDP_IDPArray(idprop);
1403
1404                 if(key >= 0 && key < len) {
1405                         if(key+1 < len) {
1406                                 /* move element to be removed to the back */
1407                                 memcpy(&tmp, &array[key], sizeof(IDProperty));
1408                                 memmove(array+key, array+key+1, sizeof(IDProperty)*(len-key+1));
1409                                 memcpy(&array[len-1], &tmp, sizeof(IDProperty));
1410                         }
1411
1412                         IDP_ResizeIDPArray(idprop, len-1);
1413                 }
1414         }
1415         else if(prop->flag & PROP_IDPROPERTY);
1416 #if 0
1417         else if(cprop->remove){
1418                 if(!(cprop->remove->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
1419                         ParameterList *params= RNA_parameter_list_create(ptr, cprop->remove);
1420                         RNA_function_call(NULL, NULL, ptr, cprop->remove, params);
1421                         RNA_parameter_list_free(params);
1422                 }
1423         }
1424 #endif
1425         else
1426                 printf("RNA_property_collection_remove %s.%s: only supported for id properties.\n", ptr->type->identifier, prop->identifier);
1427 }
1428
1429 void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
1430 {
1431         IDProperty *idprop;
1432
1433         if((idprop=rna_idproperty_check(&prop, ptr)))
1434                 IDP_ResizeIDPArray(idprop, 0);
1435 }
1436
1437 int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
1438 {
1439         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1440
1441         if(cprop->lookupint) {
1442                 /* we have a callback defined, use it */
1443                 *r_ptr= cprop->lookupint(ptr, key);
1444                 return (r_ptr->data != NULL);
1445         }
1446         else {
1447                 /* no callback defined, just iterate and find the nth item */
1448                 CollectionPropertyIterator iter;
1449                 int i;
1450
1451                 RNA_property_collection_begin(ptr, prop, &iter);
1452                 for(i=0; iter.valid; RNA_property_collection_next(&iter), i++) {
1453                         if(i == key) {
1454                                 *r_ptr= iter.ptr;
1455                                 break;
1456                         }
1457                 }
1458                 RNA_property_collection_end(&iter);
1459
1460                 if(!iter.valid)
1461                         memset(r_ptr, 0, sizeof(*r_ptr));
1462
1463                 return iter.valid;
1464         }
1465 }
1466
1467 int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr)
1468 {
1469         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
1470
1471         if(cprop->lookupstring) {
1472                 /* we have a callback defined, use it */
1473                 *r_ptr= cprop->lookupstring(ptr, key);
1474                 return (r_ptr->data != NULL);
1475         }
1476         else {
1477                 /* no callback defined, compare with name properties if they exist */
1478                 CollectionPropertyIterator iter;
1479                 PropertyRNA *nameprop;
1480                 char name[256], *nameptr;
1481                 int found= 0;
1482
1483                 RNA_property_collection_begin(ptr, prop, &iter);
1484                 for(; iter.valid; RNA_property_collection_next(&iter)) {
1485                         if(iter.ptr.data && iter.ptr.type->nameproperty) {
1486                                 nameprop= iter.ptr.type->nameproperty;
1487
1488                                 nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
1489
1490                                 if(strcmp(nameptr, key) == 0) {
1491                                         *r_ptr= iter.ptr;
1492                                         found= 1;
1493                                 }
1494
1495                                 if((char *)&name != nameptr)
1496                                         MEM_freeN(nameptr);
1497
1498                                 if(found)
1499                                         break;
1500                         }
1501                 }
1502                 RNA_property_collection_end(&iter);
1503
1504                 if(!iter.valid)
1505                         memset(r_ptr, 0, sizeof(*r_ptr));
1506
1507                 return iter.valid;
1508         }
1509 }
1510
1511 /* Standard iterator functions */
1512
1513 void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip)
1514 {
1515         ListBaseIterator *internal;
1516
1517         internal= MEM_callocN(sizeof(ListBaseIterator), "ListBaseIterator");
1518         internal->link= (lb)? lb->first: NULL;
1519         internal->skip= skip;
1520
1521         iter->internal= internal;
1522         iter->valid= (internal->link != NULL);
1523
1524         if(skip && iter->valid && skip(iter, internal->link))
1525                 rna_iterator_listbase_next(iter);
1526 }
1527
1528 void rna_iterator_listbase_next(CollectionPropertyIterator *iter)
1529 {
1530         ListBaseIterator *internal= iter->internal;
1531
1532         if(internal->skip) {
1533                 do {
1534                         internal->link= internal->link->next;
1535                         iter->valid= (internal->link != NULL);
1536                 } while(iter->valid && internal->skip(iter, internal->link));
1537         }
1538         else {
1539                 internal->link= internal->link->next;
1540                 iter->valid= (internal->link != NULL);
1541         }
1542 }
1543
1544 void *rna_iterator_listbase_get(CollectionPropertyIterator *iter)
1545 {
1546         ListBaseIterator *internal= iter->internal;
1547
1548         return internal->link;
1549 }
1550
1551 void rna_iterator_listbase_end(CollectionPropertyIterator *iter)
1552 {
1553         MEM_freeN(iter->internal);
1554         iter->internal= NULL;
1555 }
1556
1557 void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int itemsize, int length, IteratorSkipFunc skip)
1558 {
1559         ArrayIterator *internal;
1560
1561         if(ptr == NULL)
1562                 length= 0;
1563
1564         internal= MEM_callocN(sizeof(ArrayIterator), "ArrayIterator");
1565         internal->ptr= ptr;
1566         internal->endptr= ((char*)ptr)+length*itemsize;
1567         internal->itemsize= itemsize;
1568         internal->skip= skip;
1569
1570         iter->internal= internal;
1571         iter->valid= (internal->ptr != internal->endptr);
1572
1573         if(skip && iter->valid && skip(iter, internal->ptr))
1574                 rna_iterator_array_next(iter);
1575 }
1576
1577 void rna_iterator_array_next(CollectionPropertyIterator *iter)
1578 {
1579         ArrayIterator *internal= iter->internal;
1580
1581         if(internal->skip) {
1582                 do {
1583                         internal->ptr += internal->itemsize;
1584                         iter->valid= (internal->ptr != internal->endptr);
1585                 } while(iter->valid && internal->skip(iter, internal->ptr));
1586         }
1587         else {
1588                 internal->ptr += internal->itemsize;
1589                 iter->valid= (internal->ptr != internal->endptr);
1590         }
1591 }
1592
1593 void *rna_iterator_array_get(CollectionPropertyIterator *iter)
1594 {
1595         ArrayIterator *internal= iter->internal;
1596
1597         return internal->ptr;
1598 }
1599
1600 void *rna_iterator_array_dereference_get(CollectionPropertyIterator *iter)
1601 {
1602         ArrayIterator *internal= iter->internal;
1603
1604         /* for ** arrays */
1605         return *(void**)(internal->ptr);
1606 }
1607
1608 void rna_iterator_array_end(CollectionPropertyIterator *iter)
1609 {
1610         MEM_freeN(iter->internal);
1611         iter->internal= NULL;
1612 }
1613
1614 /* RNA Path - Experiment */
1615
1616 static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int bracket)
1617 {
1618         const char *p;
1619         char *buf;
1620         int i, j, len, escape;
1621
1622         len= 0;
1623
1624         if(bracket) {
1625                 /* get data between [], check escaping ] with \] */
1626                 if(**path == '[') (*path)++;
1627                 else return NULL;
1628
1629                 p= *path;
1630
1631                 escape= 0;
1632                 while(*p && (*p != ']' || escape)) {
1633                         escape= (*p == '\\');
1634                         len++;
1635                         p++;
1636                 }
1637
1638                 if(*p != ']') return NULL;
1639         }
1640         else {
1641                 /* get data until . or [ */
1642                 p= *path;
1643
1644                 while(*p && *p != '.' && *p != '[') {
1645                         len++;
1646                         p++;
1647                 }
1648         }
1649         
1650         /* empty, return */
1651         if(len == 0)
1652                 return NULL;
1653         
1654         /* try to use fixed buffer if possible */
1655         if(len+1 < fixedlen)
1656                 buf= fixedbuf;
1657         else
1658                 buf= MEM_callocN(sizeof(char)*(len+1), "rna_path_token");
1659
1660         /* copy string, taking into account escaped ] */
1661         if(bracket) {
1662                 for(p=*path, i=0, j=0; i<len; i++, p++) {
1663                         if(*p == '\\' && *(p+1) == ']');
1664                         else buf[j++]= *p;
1665                 }
1666
1667                 buf[j]= 0;
1668         }
1669         else {
1670                 memcpy(buf, *path, sizeof(char)*len);
1671                 buf[len]= '\0';
1672         }
1673
1674         /* set path to start of next token */
1675         if(*p == ']') p++;
1676         if(*p == '.') p++;
1677         *path= p;
1678
1679         return buf;
1680 }
1681
1682 int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
1683 {
1684         PropertyRNA *prop;
1685         PointerRNA curptr, nextptr;
1686         char fixedbuf[256], *token;
1687         int len, intkey;
1688
1689         prop= NULL;
1690         curptr= *ptr;
1691
1692         while(*path) {
1693                 /* look up property name in current struct */
1694                 token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 0);
1695
1696                 if(!token)
1697                         return 0;
1698
1699                 prop= RNA_struct_find_property(&curptr, token);
1700
1701                 if(token != fixedbuf)
1702                         MEM_freeN(token);
1703
1704                 if(!prop)
1705                         return 0;
1706
1707                 /* now look up the value of this property if it is a pointer or
1708                  * collection, otherwise return the property rna so that the
1709                  * caller can read the value of the property itself */
1710                 if(RNA_property_type(prop) == PROP_POINTER) {
1711                         nextptr= RNA_property_pointer_get(&curptr, prop);
1712
1713                         if(nextptr.data)
1714                                 curptr= nextptr;
1715                         else
1716                                 return 0;
1717                 }
1718                 else if(RNA_property_type(prop) == PROP_COLLECTION && *path) {
1719                         /* resolve the lookup with [] brackets */
1720                         token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1);
1721
1722                         if(!token)
1723                                 return 0;
1724
1725                         len= strlen(token);
1726                         
1727                         /* check for "" to see if it is a string */
1728                         if(len >= 2 && token[0] == '"' && token[len-1] == '"') {
1729                                 /* strip away "" */
1730                                 token[len-1]= 0;
1731                                 RNA_property_collection_lookup_string(&curptr, prop, token+1, &nextptr);
1732                         }
1733                         else {
1734                                 /* otherwise do int lookup */
1735                                 intkey= atoi(token);
1736                                 RNA_property_collection_lookup_int(&curptr, prop, intkey, &nextptr);
1737                         }
1738
1739                         if(token != fixedbuf)
1740                                 MEM_freeN(token);
1741
1742                         if(nextptr.data)
1743                                 curptr= nextptr;
1744                         else
1745                                 return 0;
1746                 }
1747         }
1748
1749         *r_ptr= curptr;
1750         *r_prop= prop;
1751
1752         return 1;
1753 }
1754
1755 char *RNA_path_append(const char *path, PointerRNA *ptr, PropertyRNA *prop, int intkey, const char *strkey)
1756 {
1757         DynStr *dynstr;
1758         const char *s;
1759         char appendstr[128], *result;
1760         
1761         dynstr= BLI_dynstr_new();
1762
1763         /* add .identifier */
1764         if(path) {
1765                 BLI_dynstr_append(dynstr, (char*)path);
1766                 if(*path)
1767                         BLI_dynstr_append(dynstr, ".");
1768         }
1769
1770         BLI_dynstr_append(dynstr, (char*)RNA_property_identifier(prop));
1771
1772         if(RNA_property_type(prop) == PROP_COLLECTION) {
1773                 /* add ["strkey"] or [intkey] */
1774                 BLI_dynstr_append(dynstr, "[");
1775
1776                 if(strkey) {
1777                         BLI_dynstr_append(dynstr, "\"");
1778                         for(s=strkey; *s; s++) {
1779                                 if(*s == '[') {
1780                                         appendstr[0]= '\\';
1781                                         appendstr[1]= *s;
1782                                         appendstr[2]= 0;
1783                                 }
1784                                 else {
1785                                         appendstr[0]= *s;
1786                                         appendstr[1]= 0;
1787                                 }
1788                                 BLI_dynstr_append(dynstr, appendstr);
1789                         }
1790                         BLI_dynstr_append(dynstr, "\"");
1791                 }
1792                 else {
1793                         sprintf(appendstr, "%d", intkey);
1794                         BLI_dynstr_append(dynstr, appendstr);
1795                 }
1796
1797                 BLI_dynstr_append(dynstr, "]");
1798         }
1799
1800         result= BLI_dynstr_get_cstring(dynstr);
1801         BLI_dynstr_free(dynstr);
1802
1803         return result;
1804 }
1805
1806 char *RNA_path_back(const char *path)
1807 {
1808         char fixedbuf[256];
1809         const char *previous, *current;
1810         char *result, *token;
1811         int i;
1812
1813         if(!path)
1814                 return NULL;
1815
1816         previous= NULL;
1817         current= path;
1818
1819         /* parse token by token until the end, then we back up to the previous
1820          * position and strip of the next token to get the path one step back */
1821         while(*current) {
1822                 token= rna_path_token(&current, fixedbuf, sizeof(fixedbuf), 0);
1823
1824                 if(!token)
1825                         return NULL;
1826                 if(token != fixedbuf)
1827                         MEM_freeN(token);
1828
1829                 /* in case of collection we also need to strip off [] */
1830                 token= rna_path_token(&current, fixedbuf, sizeof(fixedbuf), 1);
1831                 if(token && token != fixedbuf)
1832                         MEM_freeN(token);
1833                 
1834                 if(!*current)
1835                         break;
1836
1837                 previous= current;
1838         }
1839
1840         if(!previous)
1841                 return NULL;
1842
1843         /* copy and strip off last token */
1844         i= previous - path;
1845         result= BLI_strdup(path);
1846
1847         if(i > 0 && result[i-1] == '.') i--;
1848         result[i]= 0;
1849
1850         return result;
1851 }
1852
1853 char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop)
1854 {
1855         char *ptrpath=NULL, *path;
1856         const char *propname;
1857
1858         if(!ptr->id.data || !ptr->data || !prop)
1859                 return NULL;
1860         
1861         if(!RNA_struct_is_ID(ptr->type)) {
1862                 if(ptr->type->path) {
1863                         /* if type has a path to some ID, use it */
1864                         ptrpath= ptr->type->path(ptr);
1865                 }
1866                 else if(ptr->type->nested) {
1867                         PointerRNA parentptr;
1868                         PropertyRNA *userprop;
1869                         
1870                         /* find the property in the struct we're nested in that references this struct, and 
1871                          * use its identifier as the first part of the path used...
1872                          */
1873                         RNA_pointer_create(ptr->id.data, ptr->type->nested, ptr->data, &parentptr);
1874                         userprop= RNA_struct_find_nested(&parentptr, ptr->type); 
1875                         
1876                         if(userprop)
1877                                 ptrpath= BLI_strdup(RNA_property_identifier(userprop));
1878                         else
1879                                 return NULL; // can't do anything about this case yet...
1880                 }
1881                 else
1882                         return NULL;
1883         }
1884
1885         propname= RNA_property_identifier(prop);
1886
1887         if(ptrpath) {
1888                 path= BLI_sprintfN("%s.%s", ptrpath, propname);
1889                 MEM_freeN(ptrpath);
1890         }
1891         else
1892                 path= BLI_strdup(propname);
1893         
1894         return path;
1895 }
1896
1897 /* Quick name based property access */
1898
1899 int RNA_boolean_get(PointerRNA *ptr, const char *name)
1900 {
1901         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1902
1903         if(prop) {
1904                 return RNA_property_boolean_get(ptr, prop);
1905         }
1906         else {
1907                 printf("RNA_boolean_get: %s.%s not found.\n", ptr->type->identifier, name);
1908                 return 0;
1909         }
1910 }
1911
1912 void RNA_boolean_set(PointerRNA *ptr, const char *name, int value)
1913 {
1914         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1915
1916         if(prop)
1917                 RNA_property_boolean_set(ptr, prop, value);
1918         else
1919                 printf("RNA_boolean_set: %s.%s not found.\n", ptr->type->identifier, name);
1920 }
1921
1922 void RNA_boolean_get_array(PointerRNA *ptr, const char *name, int *values)
1923 {
1924         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1925
1926         if(prop)
1927                 RNA_property_boolean_get_array(ptr, prop, values);
1928         else
1929                 printf("RNA_boolean_get_array: %s.%s not found.\n", ptr->type->identifier, name);
1930 }
1931
1932 void RNA_boolean_set_array(PointerRNA *ptr, const char *name, const int *values)
1933 {
1934         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1935
1936         if(prop)
1937                 RNA_property_boolean_set_array(ptr, prop, values);
1938         else
1939                 printf("RNA_boolean_set_array: %s.%s not found.\n", ptr->type->identifier, name);
1940 }
1941
1942 int RNA_int_get(PointerRNA *ptr, const char *name)
1943 {
1944         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1945
1946         if(prop) {
1947                 return RNA_property_int_get(ptr, prop);
1948         }
1949         else {
1950                 printf("RNA_int_get: %s.%s not found.\n", ptr->type->identifier, name);
1951                 return 0;
1952         }
1953 }
1954
1955 void RNA_int_set(PointerRNA *ptr, const char *name, int value)
1956 {
1957         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1958
1959         if(prop)
1960                 RNA_property_int_set(ptr, prop, value);
1961         else
1962                 printf("RNA_int_set: %s.%s not found.\n", ptr->type->identifier, name);
1963 }
1964
1965 void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values)
1966 {
1967         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1968
1969         if(prop)
1970                 RNA_property_int_get_array(ptr, prop, values);
1971         else
1972                 printf("RNA_int_get_array: %s.%s not found.\n", ptr->type->identifier, name);
1973 }
1974
1975 void RNA_int_set_array(PointerRNA *ptr, const char *name, const int *values)
1976 {
1977         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1978
1979         if(prop)
1980                 RNA_property_int_set_array(ptr, prop, values);
1981         else
1982                 printf("RNA_int_set_array: %s.%s not found.\n", ptr->type->identifier, name);
1983 }
1984
1985 float RNA_float_get(PointerRNA *ptr, const char *name)
1986 {
1987         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1988
1989         if(prop) {
1990                 return RNA_property_float_get(ptr, prop);
1991         }
1992         else {
1993                 printf("RNA_float_get: %s.%s not found.\n", ptr->type->identifier, name);
1994                 return 0;
1995         }
1996 }
1997
1998 void RNA_float_set(PointerRNA *ptr, const char *name, float value)
1999 {
2000         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2001
2002         if(prop)
2003                 RNA_property_float_set(ptr, prop, value);
2004         else
2005                 printf("RNA_float_set: %s.%s not found.\n", ptr->type->identifier, name);
2006 }
2007
2008 void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
2009 {
2010         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2011
2012         if(prop)
2013                 RNA_property_float_get_array(ptr, prop, values);
2014         else
2015                 printf("RNA_float_get_array: %s.%s not found.\n", ptr->type->identifier, name);
2016 }
2017
2018 void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
2019 {
2020         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2021
2022         if(prop)
2023                 RNA_property_float_set_array(ptr, prop, values);
2024         else
2025                 printf("RNA_float_set_array: %s.%s not found.\n", ptr->type->identifier, name);
2026 }
2027
2028 int RNA_enum_get(PointerRNA *ptr, const char *name)
2029 {
2030         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2031
2032         if(prop) {
2033                 return RNA_property_enum_get(ptr, prop);
2034         }
2035         else {
2036                 printf("RNA_enum_get: %s.%s not found.\n", ptr->type->identifier, name);
2037                 return 0;
2038         }
2039 }
2040
2041 void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
2042 {
2043         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2044
2045         if(prop)
2046                 RNA_property_enum_set(ptr, prop, value);
2047         else
2048                 printf("RNA_enum_set: %s.%s not found.\n", ptr->type->identifier, name);
2049 }
2050
2051 int RNA_enum_is_equal(PointerRNA *ptr, const char *name, const char *enumname)
2052 {
2053         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2054         const EnumPropertyItem *item;
2055         int a, totitem;
2056
2057         if(prop) {
2058                 RNA_property_enum_items(ptr, prop, &item, &totitem);
2059
2060                 for(a=0; a<totitem; a++)
2061                         if(strcmp(item[a].identifier, enumname) == 0)
2062                                 return (item[a].value == RNA_property_enum_get(ptr, prop));
2063
2064                 printf("RNA_enum_is_equal: %s.%s item %s not found.\n", ptr->type->identifier, name, enumname);
2065                 return 0;
2066         }
2067         else {
2068                 printf("RNA_enum_is_equal: %s.%s not found.\n", ptr->type->identifier, name);
2069                 return 0;
2070         }
2071 }
2072
2073 int RNA_enum_value_from_id(const EnumPropertyItem *item, const char *identifier, int *value)
2074 {
2075         for( ; item->identifier; item++) {
2076                 if(strcmp(item->identifier, identifier)==0) {
2077                         *value= item->value;
2078                         return 1;
2079                 }
2080         }
2081         
2082         return 0;
2083 }
2084
2085 int     RNA_enum_id_from_value(const EnumPropertyItem *item, int value, const char **identifier)
2086 {
2087         for( ; item->identifier; item++) {
2088                 if(item->value==value) {
2089                         *identifier= item->identifier;
2090                         return 1;
2091                 }
2092         }
2093
2094         return 0;
2095 }
2096
2097
2098
2099 void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
2100 {
2101         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2102
2103         if(prop)
2104                 RNA_property_string_get(ptr, prop, value);
2105         else
2106                 printf("RNA_string_get: %s.%s not found.\n", ptr->type->identifier, name);
2107 }
2108
2109 char *RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen)
2110 {
2111         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2112
2113         if(prop) {
2114                 return RNA_property_string_get_alloc(ptr, prop, fixedbuf, fixedlen);
2115         }
2116         else {
2117                 printf("RNA_string_get_alloc: %s.%s not found.\n", ptr->type->identifier, name);
2118                 return 0;
2119         }
2120 }
2121
2122 int RNA_string_length(PointerRNA *ptr, const char *name)
2123 {
2124         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2125
2126         if(prop) {
2127                 return RNA_property_string_length(ptr, prop);
2128         }
2129         else {
2130                 printf("RNA_string_length: %s.%s not found.\n", ptr->type->identifier, name);
2131                 return 0;
2132         }
2133 }
2134
2135 void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
2136 {
2137         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2138
2139         if(prop)
2140                 RNA_property_string_set(ptr, prop, value);
2141         else
2142                 printf("RNA_string_set: %s.%s not found.\n", ptr->type->identifier, name);
2143 }
2144
2145 PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
2146 {
2147         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2148
2149         if(prop) {
2150                 return RNA_property_pointer_get(ptr, prop);
2151         }
2152         else {
2153                 PointerRNA result;
2154
2155                 printf("RNA_pointer_get: %s.%s not found.\n", ptr->type->identifier, name);
2156
2157                 memset(&result, 0, sizeof(result));
2158                 return result;
2159         }
2160 }
2161
2162 void RNA_pointer_add(PointerRNA *ptr, const char *name)
2163 {
2164         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2165
2166         if(prop)
2167                 RNA_property_pointer_add(ptr, prop);
2168         else
2169                 printf("RNA_pointer_set: %s.%s not found.\n", ptr->type->identifier, name);
2170 }
2171
2172 void RNA_collection_begin(PointerRNA *ptr, const char *name, CollectionPropertyIterator *iter)
2173 {
2174         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2175
2176         if(prop)
2177                 RNA_property_collection_begin(ptr, prop, iter);
2178         else
2179                 printf("RNA_collection_begin: %s.%s not found.\n", ptr->type->identifier, name);
2180 }
2181
2182 void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value)
2183 {
2184         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2185
2186         if(prop)
2187                 RNA_property_collection_add(ptr, prop, r_value);
2188         else
2189                 printf("RNA_collection_add: %s.%s not found.\n", ptr->type->identifier, name);
2190 }
2191
2192 void RNA_collection_clear(PointerRNA *ptr, const char *name)
2193 {
2194         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2195
2196         if(prop)
2197                 RNA_property_collection_clear(ptr, prop);
2198         else
2199                 printf("RNA_collection_clear: %s.%s not found.\n", ptr->type->identifier, name);
2200 }
2201
2202 int RNA_collection_length(PointerRNA *ptr, const char *name)
2203 {
2204         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2205
2206         if(prop) {
2207                 return RNA_property_collection_length(ptr, prop);
2208         }
2209         else {
2210                 printf("RNA_collection_length: %s.%s not found.\n", ptr->type->identifier, name);
2211                 return 0;
2212         }
2213 }
2214
2215 int RNA_property_is_set(PointerRNA *ptr, const char *name)
2216 {
2217         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
2218
2219         if(prop) {
2220                 return (rna_idproperty_find(ptr, name) != NULL);
2221         }
2222         else {
2223                 printf("RNA_property_is_set: %s.%s not found.\n", ptr->type->identifier, name);
2224                 return 0;
2225         }
2226 }
2227
2228 /* string representation of a property, python
2229  * compatible but can be used for display too*/
2230 char *RNA_pointer_as_string(PointerRNA *ptr)
2231 {
2232         DynStr *dynstr= BLI_dynstr_new();
2233         char *cstring;
2234         
2235         PropertyRNA *prop, *iterprop;
2236         CollectionPropertyIterator iter;
2237         const char *propname;
2238         int first_time = 1;
2239         
2240         BLI_dynstr_append(dynstr, "{");
2241         
2242         iterprop= RNA_struct_iterator_property(ptr->type);
2243
2244         for(RNA_property_collection_begin(ptr, iterprop, &iter); iter.valid; RNA_property_collection_next(&iter)) {
2245                 prop= iter.ptr.data;
2246                 propname = RNA_property_identifier(prop);
2247                 
2248                 if(strcmp(propname, "rna_type")==0)
2249                         continue;
2250                 
2251                 if(first_time==0)
2252                         BLI_dynstr_append(dynstr, ", ");
2253                 first_time= 0;
2254                 
2255                 cstring = RNA_property_as_string(ptr, prop);
2256                 BLI_dynstr_appendf(dynstr, "\"%s\":%s", propname, cstring);
2257                 MEM_freeN(cstring);
2258         }
2259
2260         RNA_property_collection_end(&iter);
2261         BLI_dynstr_append(dynstr, "}"); 
2262         
2263         
2264         cstring = BLI_dynstr_get_cstring(dynstr);
2265         BLI_dynstr_free(dynstr);
2266         return cstring;
2267 }
2268
2269 char *RNA_property_as_string(PointerRNA *ptr, PropertyRNA *prop)
2270 {
2271         int type = RNA_property_type(prop);
2272         int len = RNA_property_array_length(prop);
2273         int i;
2274
2275         DynStr *dynstr= BLI_dynstr_new();
2276         char *cstring;
2277         
2278
2279         /* see if we can coorce into a python type - PropertyType */
2280         switch (type) {
2281         case PROP_BOOLEAN:
2282                 if(len==0) {
2283                         BLI_dynstr_append(dynstr, RNA_property_boolean_get(ptr, prop) ? "True" : "False");
2284                 }
2285                 else {
2286                         BLI_dynstr_append(dynstr, "(");
2287                         for(i=0; i<len; i++) {
2288                                 BLI_dynstr_appendf(dynstr, i?", %s":"%s", RNA_property_boolean_get_index(ptr, prop, i) ? "True" : "False");
2289                         }
2290                         BLI_dynstr_append(dynstr, ")");
2291                 }
2292                 break;
2293         case PROP_INT:
2294                 if(len==0) {
2295                         BLI_dynstr_appendf(dynstr, "%d", RNA_property_int_get(ptr, prop));
2296                 }
2297                 else {
2298                         BLI_dynstr_append(dynstr, "(");
2299                         for(i=0; i<len; i++) {
2300                                 BLI_dynstr_appendf(dynstr, i?", %d":"%d", RNA_property_int_get_index(ptr, prop, i));
2301                         }
2302                         BLI_dynstr_append(dynstr, ")");
2303                 }
2304                 break;
2305         case PROP_FLOAT:
2306                 if(len==0) {
2307                         BLI_dynstr_appendf(dynstr, "%g", RNA_property_float_get(ptr, prop));
2308                 }
2309                 else {
2310                         BLI_dynstr_append(dynstr, "(");
2311                         for(i=0; i<len; i++) {
2312                                 BLI_dynstr_appendf(dynstr, i?", %g":"%g", RNA_property_float_get_index(ptr, prop, i));
2313                         }
2314                         BLI_dynstr_append(dynstr, ")");
2315                 }
2316                 break;
2317         case PROP_STRING:
2318         {
2319                 /* string arrays dont exist */
2320                 char *buf;
2321                 buf = RNA_property_string_get_alloc(ptr, prop, NULL, -1);
2322                 BLI_dynstr_appendf(dynstr, "\"%s\"", buf);
2323                 MEM_freeN(buf);
2324                 break;
2325         }
2326         case PROP_ENUM:
2327         {
2328                 /* string arrays dont exist */
2329                 const char *identifier;
2330                 int val = RNA_property_enum_get(ptr, prop);
2331
2332                 if(RNA_property_enum_identifier(ptr, prop, val, &identifier)) {
2333                         BLI_dynstr_appendf(dynstr, "'%s'", identifier);
2334                 }
2335                 else {
2336                         BLI_dynstr_appendf(dynstr, "'<UNKNOWN ENUM>'", identifier);
2337                 }
2338                 break;
2339         }
2340         case PROP_POINTER:
2341         {
2342                 BLI_dynstr_append(dynstr, "'<POINTER>'"); /* TODO */
2343                 break;
2344         }
2345         case PROP_COLLECTION:
2346         {
2347                 int first_time = 1;
2348                 CollectionPropertyIterator collect_iter;
2349                 BLI_dynstr_append(dynstr, "[");
2350                 
2351                 for(RNA_property_collection_begin(ptr, prop, &collect_iter); collect_iter.valid; RNA_property_collection_next(&collect_iter)) {
2352                         PointerRNA itemptr= collect_iter.ptr;
2353                         
2354                         if(first_time==0)
2355                                 BLI_dynstr_append(dynstr, ", ");
2356                         first_time= 0;
2357                         
2358                         /* now get every prop of the collection */
2359                         cstring= RNA_pointer_as_string(&itemptr);
2360                         BLI_dynstr_append(dynstr, cstring);
2361                         MEM_freeN(cstring);
2362                 }
2363                 
2364                 RNA_property_collection_end(&collect_iter);
2365                 BLI_dynstr_append(dynstr, "]");
2366                 break;
2367         }
2368         default:
2369                 BLI_dynstr_append(dynstr, "'<UNKNOWN TYPE>'"); /* TODO */
2370                 break;
2371         }
2372
2373         cstring = BLI_dynstr_get_cstring(dynstr);
2374         BLI_dynstr_free(dynstr);
2375         return cstring;
2376 }
2377
2378 /* Function */
2379
2380 const char *RNA_function_identifier(FunctionRNA *func)
2381 {
2382         return func->identifier;
2383 }
2384
2385 PropertyRNA *RNA_function_return(FunctionRNA *func)
2386 {
2387         return func->ret;
2388 }
2389
2390 const char *RNA_function_ui_description(FunctionRNA *func)
2391 {
2392         return func->description;
2393 }
2394
2395 int RNA_function_flag(FunctionRNA *func)
2396 {
2397         return func->flag;
2398 }
2399
2400 PropertyRNA *RNA_function_get_parameter(PointerRNA *ptr, FunctionRNA *func, int index)
2401 {
2402         PropertyRNA *parm;
2403         int i;
2404
2405         parm= func->cont.properties.first;
2406         for(i= 0; parm; parm= parm->next, i++)
2407                 if(i==index)
2408                         return parm;
2409
2410         return NULL;
2411 }
2412
2413 PropertyRNA *RNA_function_find_parameter(PointerRNA *ptr, FunctionRNA *func, const char *identifier)
2414 {
2415         PropertyRNA *parm;
2416
2417         parm= func->cont.properties.first;
2418         for(; parm; parm= parm->next)
2419                 if(strcmp(parm->identifier, identifier)==0)
2420                         return parm;
2421
2422         return NULL;
2423 }
2424
2425 const struct ListBase *RNA_function_defined_parameters(FunctionRNA *func)
2426 {
2427         return &func->cont.properties;
2428 }
2429
2430 /* Utility */
2431
2432 ParameterList *RNA_parameter_list_create(PointerRNA *ptr, FunctionRNA *func)
2433 {
2434         ParameterList *parms;
2435         PropertyRNA *parm;
2436         int tot;
2437
2438         parms= MEM_callocN(sizeof(ParameterList), "ParameterList");
2439
2440         parm= func->cont.properties.first;
2441         for(tot= 0; parm; parm= parm->next)
2442                 tot+= rna_parameter_size(parm);
2443
2444         parms->data= MEM_callocN(tot, "RNA_parameter_list_create");
2445         parms->func= func;
2446
2447         return parms;
2448 }
2449
2450 void RNA_parameter_list_free(ParameterList *parms)
2451 {
2452         MEM_freeN(parms->data);
2453         parms->data= NULL;
2454
2455         parms->func= NULL;
2456
2457         MEM_freeN(parms);
2458 }
2459
2460 void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter)
2461 {
2462         PropertyType ptype;
2463
2464         RNA_pointer_create(NULL, &RNA_Function, parms->func, &iter->funcptr);
2465
2466         iter->parms= parms;
2467         iter->parm= parms->func->cont.properties.first;
2468         iter->valid= iter->parm != NULL;
2469         iter->offset= 0;
2470
2471         if(iter->valid) {
2472                 iter->size= rna_parameter_size(iter->parm);
2473                 iter->data= (((char*)iter->parms->data)+iter->offset);
2474                 ptype= RNA_property_type(iter->parm);
2475         }
2476 }
2477
2478 void RNA_parameter_list_next(ParameterIterator *iter)
2479 {
2480         PropertyType ptype;
2481
2482         iter->offset+= iter->size;
2483         iter->parm= iter->parm->next;
2484         iter->valid= iter->parm != NULL;
2485
2486         if(iter->valid) {
2487                 iter->size= rna_parameter_size(iter->parm);
2488                 iter->data= (((char*)iter->parms->data)+iter->offset);
2489                 ptype= RNA_property_type(iter->parm);
2490         }
2491 }
2492
2493 void RNA_parameter_list_end(ParameterIterator *iter)
2494 {
2495         /* nothing to do */
2496 }
2497
2498 void RNA_parameter_get(ParameterList *parms, PropertyRNA *parm, void **value)
2499 {
2500         ParameterIterator iter;
2501
2502         RNA_parameter_list_begin(parms, &iter);
2503
2504         for(; iter.valid; RNA_parameter_list_next(&iter))
2505                 if(iter.parm==parm) 
2506                         break;
2507
2508         if(iter.valid)
2509                 *value= iter.data;
2510         else
2511                 *value= NULL;
2512
2513         RNA_parameter_list_end(&iter);
2514 }
2515
2516 void RNA_parameter_get_lookup(ParameterList *parms, const char *identifier, void **value)
2517 {
2518         PropertyRNA *parm;
2519
2520         parm= parms->func->cont.properties.first;
2521         for(; parm; parm= parm->next)
2522                 if(strcmp(RNA_property_identifier(parm), identifier)==0)
2523                         break;
2524
2525         if(parm)
2526                 RNA_parameter_get(parms, parm, value);
2527 }
2528
2529 void RNA_parameter_set(ParameterList *parms, PropertyRNA *parm, void *value)
2530 {
2531         ParameterIterator iter;
2532
2533         RNA_parameter_list_begin(parms, &iter);
2534
2535         for(; iter.valid; RNA_parameter_list_next(&iter))
2536                 if(iter.parm==parm) 
2537                         break;
2538
2539         if(iter.valid)
2540                 memcpy(iter.data, value, iter.size);
2541
2542         RNA_parameter_list_end(&iter);
2543 }
2544
2545 void RNA_parameter_set_lookup(ParameterList *parms, const char *identifier, void *value)
2546 {
2547         PropertyRNA *parm;
2548
2549         parm= parms->func->cont.properties.first;
2550         for(; parm; parm= parm->next)
2551                 if(strcmp(RNA_property_identifier(parm), identifier)==0)
2552                         break;
2553
2554         if(parm)
2555                 RNA_parameter_set(parms, parm, value);
2556 }
2557
2558 int RNA_function_call(bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
2559 {
2560         if(func->call) {
2561                 func->call(C, reports, ptr, parms);
2562
2563                 return 0;
2564         }
2565
2566         return -1;
2567 }
2568
2569 int RNA_function_call_lookup(bContext *C, ReportList *reports, PointerRNA *ptr, const char *identifier, ParameterList *parms)
2570 {
2571         FunctionRNA *func;
2572
2573         func= RNA_struct_find_function(ptr, identifier);
2574
2575         if(func)
2576                 return RNA_function_call(C, reports, ptr, func, parms);
2577
2578         return -1;
2579 }
2580
2581 int RNA_function_call_direct(bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, const char *format, ...)
2582 {
2583         va_list args;
2584         int ret;
2585
2586         va_start(args, format);
2587
2588         ret= RNA_function_call_direct_va(C, reports, ptr, func, format, args);
2589
2590         va_end(args);
2591
2592         return ret;
2593 }
2594
2595 int RNA_function_call_direct_lookup(bContext *C, ReportList *reports, PointerRNA *ptr, const char *identifier, const char *format, ...)
2596 {
2597         FunctionRNA *func;
2598
2599         func= RNA_struct_find_function(ptr, identifier);
2600
2601         if(func) {
2602                 va_list args;
2603                 int ret;
2604
2605                 va_start(args, format);
2606
2607                 ret= RNA_function_call_direct_va(C, reports, ptr, func, format, args);
2608
2609                 va_end(args);
2610
2611                 return ret;
2612         }
2613
2614         return -1;
2615 }
2616
2617 static int rna_function_format_array_length(const char *format, int ofs, int flen)
2618 {
2619         char lenbuf[16];
2620         int idx= 0;
2621
2622         if (format[ofs++]=='[')
2623                 for (; ofs<flen && format[ofs]!=']' && idx<sizeof(*lenbuf)-1; idx++, ofs++)
2624                         lenbuf[idx]= format[ofs];
2625
2626         if (ofs<flen && format[ofs++]==']') {
2627                 /* XXX put better error reporting for ofs>=flen or idx over lenbuf capacity */
2628                 lenbuf[idx]= '\0';
2629                 return atoi(lenbuf);
2630         }
2631
2632         return 0;
2633 }
2634
2635 static int rna_function_parameter_parse(PointerRNA *ptr, PropertyRNA *prop, PropertyType type, char ftype, int len, void *dest, void *src, StructRNA *srna, const char *tid, const char *fid, const char *pid)
2636 {
2637         /* ptr is always a function pointer, prop always a parameter */
2638
2639         switch (type) {
2640         case PROP_BOOLEAN:
2641                 {
2642                         if (ftype!='b') {
2643                                 fprintf(stderr, "%s.%s: wrong type for parameter %s, a boolean was expected\n", tid, fid, pid);
2644                                 return -1;
2645                         }
2646
2647                         if (len==0)
2648                                 *((int*)dest)= *((int*)src);
2649                         else
2650                                 memcpy(dest, src, len*sizeof(int));
2651
2652                         break;
2653                 }
2654         case PROP_INT:
2655                 {
2656                         if (ftype!='i') {
2657                                 fprintf(stderr, "%s.%s: wrong type for parameter %s, an integer was expected\n", tid, fid, pid);
2658                                 return -1;
2659                         }
2660
2661                         if (len==0)
2662                                 *((int*)dest)= *((int*)src);
2663                         else
2664                                 memcpy(dest, src, len*sizeof(int));
2665
2666                         break;
2667                 }
2668         case PROP_FLOAT:
2669                 {
2670                         if (ftype!='f') {
2671                                 fprintf(stderr, "%s.%s: wrong type for parameter %s, a float was expected\n", tid, fid, pid);
2672                                 return -1;
2673                         }
2674
2675                         if (len==0)
2676                                 *((float*)dest)= *((float*)src);
2677                         else
2678                                 memcpy(dest, src, len*sizeof(float));
2679
2680                         break;
2681                 }
2682         case PROP_STRING:
2683                 {
2684                         if (ftype!='s') {
2685                                 fprintf(stderr, "%s.%s: wrong type for parameter %s, a string was expected\n", tid, fid, pid);
2686                                 return -1;
2687                         }
2688
2689                         *((char**)dest)= *((char**)src);
2690
2691                         break;
2692                 }
2693         case PROP_ENUM:
2694                 {
2695                         if (ftype!='e') {
2696                                 fprintf(stderr, "%s.%s: wrong type for parameter %s, an enum was expected\n", tid, fid, pid);
2697                                 return -1;
2698                         }
2699
2700                         *((int*)dest)= *((int*)src);
2701
2702                         break;
2703                 }
2704         case PROP_POINTER:
2705                 {
2706                         StructRNA *ptype;
2707
2708                         if (ftype!='O') {
2709                                 fprintf(stderr, "%s.%s: wrong type for parameter %s, an object was expected\n", tid, fid, pid);
2710                                 return -1;
2711                         }
2712
2713                         ptype= RNA_property_pointer_type(ptr, prop);
2714
2715                         if(prop->flag & PROP_RNAPTR) {
2716                                 *((PointerRNA*)dest)= *((PointerRNA*)src);
2717                         }
2718                         else if (ptype!=srna) {
2719                                 if (!RNA_struct_is_a(srna, ptype)) {
2720                                         fprintf(stderr, "%s.%s: wrong type for parameter %s, an object of type %s was expected, passed an object of type %s\n", tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(ptype));
2721                                         return -1;
2722                                 }
2723
2724                                 *((void**)dest)= *((void**)src);
2725                         }
2726
2727                         break;
2728                 }
2729         case PROP_COLLECTION:
2730                 {
2731                         /* XXX collections are not supported yet */
2732                         fprintf(stderr, "%s.%s: for parameter %s, collections are not supported yet\n", tid, fid, pid);
2733                         return -1;
2734                 }
2735         default: 
2736                 {
2737                         if (len==0)
2738                                 fprintf(stderr, "%s.%s: unknown type for parameter %s\n", tid, fid, pid);
2739                         else
2740                                 fprintf(stderr, "%s.%s: unknown array type for parameter %s\n", tid, fid, pid);
2741
2742                         return -1;
2743                 }
2744         }
2745
2746         return 0;
2747 }
2748
2749 int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, const char *format, va_list args)
2750 {
2751         PointerRNA funcptr;
2752         ParameterList *parms;
2753         ParameterIterator iter;
2754         PropertyRNA *pret, *parm;
2755         PropertyType type;
2756         int i, ofs, flen, flag, len, alen, err= 0;
2757         const char *tid, *fid, *pid=NULL;
2758         char ftype;
2759         void **retdata=NULL;
2760
2761         RNA_pointer_create(NULL, &RNA_Function, func, &funcptr);
2762
2763         tid= RNA_struct_identifier(ptr->type);
2764         fid= RNA_function_identifier(func);
2765         pret= RNA_function_return(func);
2766         flen= strlen(format);
2767
2768         parms= RNA_parameter_list_create(ptr, func);
2769         RNA_parameter_list_begin(parms, &iter);
2770
2771         for(i= 0, ofs= 0; iter.valid; RNA_parameter_list_next(&iter), i++) {
2772                 parm= iter.parm;
2773
2774                 if(parm==pret) {
2775                         retdata= iter.data;
2776                         continue;
2777                 }
2778
2779                 pid= RNA_property_identifier(parm);
2780                 flag= RNA_property_flag(parm);
2781
2782                 if (ofs>=flen || format[ofs]=='N') {
2783                         if (flag & PROP_REQUIRED) {
2784                                 err= -1;
2785                                 fprintf(stderr, "%s.%s: missing required parameter %s\n", tid, fid, pid);
2786                                 break;
2787                         }
2788                         ofs++;
2789                         continue;
2790                 }
2791
2792                 type= RNA_property_type(parm);
2793                 ftype= format[ofs++];
2794                 len= RNA_property_array_length(parm);
2795                 alen= rna_function_format_array_length(format, ofs, flen);
2796
2797                 if (len!=alen) {
2798                         err= -1;
2799                         fprintf(stderr, "%s.%s: for parameter %s, was expecting an array of %i elements, passed %i elements instead\n", tid, fid, pid, len, alen);
2800                         break;
2801                 }
2802
2803                 switch (type) {
2804                 case PROP_BOOLEAN:
2805                 case PROP_INT:
2806                 case PROP_ENUM:
2807                         {
2808                                 int arg= va_arg(args, int);
2809                                 err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, NULL, tid, fid, pid);
2810                                 break;
2811                         }
2812                 case PROP_FLOAT:
2813                         {
2814                                 double arg= va_arg(args, double);
2815                                 err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, NULL, tid, fid, pid);
2816                                 break;
2817                         }
2818                 case PROP_STRING:
2819                         {
2820                                 char *arg= va_arg(args, char*);
2821                                 err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, NULL, tid, fid, pid);
2822                                 break;
2823                         }
2824                 case PROP_POINTER:
2825                         {
2826                                 StructRNA *srna= va_arg(args, StructRNA*);
2827                                 void *arg= va_arg(args, void*);
2828                                 err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, srna, tid, fid, pid);
2829                                 break;
2830                         }
2831                 default:
2832                         {
2833                                 /* handle errors */
2834                                 err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, NULL, NULL, tid, fid, pid);
2835                                 break;
2836                         }
2837                 }
2838
2839                 if (err!=0)
2840                         break;
2841         }
2842
2843         if (err==0)
2844                 err= RNA_function_call(C, reports, ptr, func, parms);
2845
2846         /* XXX throw error when more parameters than those needed are passed or leave silent? */
2847         if (err==0 && pret && ofs<flen && format[ofs++]=='R') {
2848                 parm= pret;
2849
2850                 type= RNA_property_type(parm);
2851                 ftype= format[ofs++];
2852                 len= RNA_property_array_length(parm);
2853                 alen= rna_function_format_array_length(format, ofs, flen);
2854
2855                 if (len!=alen) {
2856                         err= -1;
2857                         fprintf(stderr, "%s.%s: for return parameter %s, was expecting an array of %i elements, passed %i elements instead\n", tid, fid, pid, len, alen);
2858                 }
2859                 else {
2860                         switch (type) {
2861                         case PROP_BOOLEAN:
2862                         case PROP_INT:
2863                         case PROP_ENUM:
2864                                 {
2865                                         int *arg= va_arg(args, int*);
2866                                         err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, NULL, tid, fid, pid);
2867                                         break;
2868                                 }
2869                         case PROP_FLOAT:
2870                                 {
2871                                         float *arg= va_arg(args, float*);
2872                                         err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, NULL, tid, fid, pid);
2873                                         break;
2874                                 }
2875                         case PROP_STRING:
2876                                 {
2877                                         char **arg= va_arg(args, char**);
2878                                         err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, NULL, tid, fid, pid);
2879                                         break;
2880                                 }
2881                         case PROP_POINTER:
2882                                 {
2883                                         StructRNA *srna= va_arg(args, StructRNA*);
2884                                         void **arg= va_arg(args, void**);
2885                                         err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, srna, tid, fid, pid);
2886                                         break;
2887                                 }
2888                         default:
2889                                 {
2890                                         /* handle errors */
2891                                         err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, NULL, NULL, NULL, tid, fid, pid);
2892                                         break;
2893                                 }
2894                         }
2895                 }
2896         }
2897
2898         RNA_parameter_list_end(&iter);
2899         RNA_parameter_list_free(parms);
2900
2901         return err;
2902 }
2903
2904 int RNA_function_call_direct_va_lookup(bContext *C, ReportList *reports, PointerRNA *ptr, const char *identifier, const char *format, va_list args)
2905 {
2906         FunctionRNA *func;
2907
2908         func= RNA_struct_find_function(ptr, identifier);
2909
2910         if(func)
2911                 return RNA_function_call_direct_va(C, reports, ptr, func, format, args);
2912
2913         return 0;
2914 }
2915