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