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