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