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