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