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