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 "BLI_blenlib.h"
31 #include "BLI_dynstr.h"
32
33 #include "BKE_idprop.h"
34 #include "BKE_utildefines.h"
35
36 #include "DNA_ID.h"
37 #include "DNA_windowmanager_types.h"
38
39 #include "RNA_access.h"
40 #include "RNA_define.h"
41 #include "RNA_types.h"
42
43 #include "rna_internal.h"
44
45 /* Exit */
46
47 void RNA_exit()
48 {
49         RNA_free(&BLENDER_RNA);
50 }
51
52 /* Pointer */
53
54 void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr)
55 {
56         r_ptr->id.type= NULL;
57         r_ptr->id.data= NULL;
58         r_ptr->type= &RNA_Main;
59         r_ptr->data= main;
60 }
61
62 void RNA_id_pointer_create(StructRNA *idtype, ID *id, PointerRNA *r_ptr)
63 {
64         r_ptr->id.type= idtype;
65         r_ptr->id.data= id;
66         r_ptr->type= idtype;
67         r_ptr->data= id;
68 }
69
70 void RNA_pointer_create(StructRNA *idtype, ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
71 {
72         r_ptr->id.type= idtype;
73         r_ptr->id.data= id;
74         r_ptr->type= type;
75         r_ptr->data= data;
76 }
77
78 static void rna_pointer_inherit_id(PointerRNA *parent, PointerRNA *ptr)
79 {
80         if(ptr->type && ptr->type->flag & STRUCT_ID) {
81                 ptr->id.data= ptr->data;
82                 ptr->id.type= ptr->type;
83         }
84         else {
85                 ptr->id.data= parent->id.data;
86                 ptr->id.type= parent->id.type;
87         }
88 }
89
90 /* ID Properties */
91
92 IDProperty *rna_idproperties_get(StructRNA *type, void *data, int create)
93 {
94         if(type->flag & STRUCT_ID)
95                 return IDP_GetProperties(data, create);
96         else if(type == &RNA_IDPropertyGroup)
97                 return data;
98         else if(type->from == &RNA_Operator) {
99                 wmOperator *op= (wmOperator*)data;
100
101                 if(create && !op->properties) {
102                         IDPropertyTemplate val;
103                         val.i = 0; /* silence MSVC warning about uninitialized var when debugging */
104                         op->properties= IDP_New(IDP_GROUP, val, "property");
105                 }
106
107                 return op->properties;
108         }
109         else
110                 return NULL;
111 }
112
113 static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name)
114 {
115         IDProperty *group= rna_idproperties_get(ptr->type, ptr->data, 0);
116         IDProperty *idprop;
117
118         if(group) {
119                 for(idprop=group->data.group.first; idprop; idprop=idprop->next)
120                         if(strcmp(idprop->name, name) == 0)
121                                 return idprop;
122         }
123         
124         return NULL;
125 }
126
127 static int rna_idproperty_verify_valid(PropertyRNA *prop, IDProperty *idprop)
128 {
129         /* this verifies if the idproperty actually matches the property
130          * description and otherwise removes it. this is to ensure that
131          * rna property access is type safe, e.g. if you defined the rna
132          * to have a certain array length you can count on that staying so */
133         
134         switch(idprop->type) {
135                 case IDP_ARRAY:
136                         if(prop->arraylength != idprop->len)
137                                 return 0;
138
139                         if(idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT)
140                                 return 0;
141                         if(idprop->subtype == IDP_INT && !ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
142                                 return 0;
143
144                         break;
145                 case IDP_INT:
146                         if(!ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
147                                 return 0;
148                         break;
149                 case IDP_FLOAT:
150                 case IDP_DOUBLE:
151                         if(prop->type != PROP_FLOAT)
152                                 return 0;
153                         break;
154                 case IDP_STRING:
155                         if(prop->type != PROP_STRING)
156                                 return 0;
157                         break;
158                 case IDP_GROUP:
159                         if(prop->type != PROP_POINTER)
160                                 return 0;
161                         break;
162                 default:
163                         return 0;
164         }
165
166         return 1;
167 }
168
169 IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr)
170 {
171         /* This is quite a hack, but avoids some complexity in the API. we
172          * pass IDProperty structs as PropertyRNA pointers to the outside.
173          * We store some bytes in PropertyRNA structs that allows us to
174          * distinguish it from IDProperty structs. If it is an ID property,
175          * we look up an IDP PropertyRNA based on the type, and set the data
176          * pointer to the IDProperty. */
177
178         if((*prop)->magic == RNA_MAGIC) {
179                 if((*prop)->flag & PROP_IDPROPERTY) {
180                         IDProperty *idprop= rna_idproperty_find(ptr, (*prop)->identifier);
181
182                         if(idprop && !rna_idproperty_verify_valid(*prop, idprop)) {
183                                 IDProperty *group= rna_idproperties_get(ptr->type, ptr->data, 0);
184
185                                 IDP_RemFromGroup(group, idprop);
186                                 IDP_FreeProperty(idprop);
187                                 MEM_freeN(idprop);
188                                 return NULL;
189                         }
190
191                         return idprop;
192                 }
193                 else
194                         return NULL;
195         }
196
197         {
198                 static PropertyRNA *typemap[IDP_NUMTYPES] =
199                         {(PropertyRNA*)&rna_IDProperty_string,
200                          (PropertyRNA*)&rna_IDProperty_int,
201                          (PropertyRNA*)&rna_IDProperty_float,
202                          NULL, NULL, NULL,
203                          (PropertyRNA*)&rna_IDProperty_group, NULL,
204                          (PropertyRNA*)&rna_IDProperty_double};
205
206                 static PropertyRNA *arraytypemap[IDP_NUMTYPES] =
207                         {NULL, (PropertyRNA*)&rna_IDProperty_intarray,
208                          (PropertyRNA*)&rna_IDProperty_floatarray,
209                          NULL, NULL, NULL, NULL, NULL,
210                          (PropertyRNA*)&rna_IDProperty_doublearray};
211
212                 IDProperty *idprop= (IDProperty*)(*prop);
213
214                 if(idprop->type == IDP_ARRAY)
215                         *prop= arraytypemap[(int)(idprop->subtype)];
216                 else 
217                         *prop= typemap[(int)(idprop->type)];
218
219                 return idprop;
220         }
221 }
222
223 /* Structs */
224
225 const char *RNA_struct_identifier(PointerRNA *ptr)
226 {
227         return ptr->type->identifier;
228 }
229
230 const char *RNA_struct_ui_name(PointerRNA *ptr)
231 {
232         return ptr->type->name;
233 }
234
235 PropertyRNA *RNA_struct_name_property(PointerRNA *ptr)
236 {
237         return ptr->type->nameproperty;
238 }
239
240 PropertyRNA *RNA_struct_iterator_property(PointerRNA *ptr)
241 {
242         return ptr->type->iteratorproperty;
243 }
244
245 PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
246 {
247         CollectionPropertyIterator iter;
248         PropertyRNA *iterprop, *prop;
249         int i = 0;
250
251         iterprop= RNA_struct_iterator_property(ptr);
252         RNA_property_collection_begin(ptr, iterprop, &iter);
253         prop= NULL;
254
255         for(; iter.valid; RNA_property_collection_next(&iter), i++) {
256                 if(strcmp(identifier, RNA_property_identifier(&iter.ptr, iter.ptr.data)) == 0) {
257                         prop= iter.ptr.data;
258                         break;
259                 }
260         }
261
262         RNA_property_collection_end(&iter);
263
264         return prop;
265 }
266
267 /* Property Information */
268
269 const char *RNA_property_identifier(PointerRNA *ptr, PropertyRNA *prop)
270 {
271         IDProperty *idprop;
272
273         if((idprop=rna_idproperty_check(&prop, ptr)))
274                 return idprop->name;
275         else
276                 return prop->identifier;
277 }
278
279 PropertyType RNA_property_type(PointerRNA *ptr, PropertyRNA *prop)
280 {
281         rna_idproperty_check(&prop, ptr);
282
283         return prop->type;
284 }
285
286 PropertySubType RNA_property_subtype(PointerRNA *ptr, PropertyRNA *prop)
287 {
288         rna_idproperty_check(&prop, ptr);
289
290         return prop->subtype;
291 }
292
293 int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
294 {
295         IDProperty *idprop;
296
297         if((idprop=rna_idproperty_check(&prop, ptr)) && idprop->type==IDP_ARRAY)
298                 return idprop->len;
299         else
300                 return prop->arraylength;
301 }
302
303 void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
304 {
305         IntPropertyRNA *iprop;
306         
307         rna_idproperty_check(&prop, ptr);
308         iprop= (IntPropertyRNA*)prop;
309
310         if(iprop->range) {
311                 iprop->range(ptr, hardmin, hardmax);
312         }
313         else {
314                 *hardmin= iprop->hardmin;
315                 *hardmax= iprop->hardmax;
316         }
317 }
318
319 void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
320 {
321         IntPropertyRNA *iprop;
322         int hardmin, hardmax;
323         
324         rna_idproperty_check(&prop, ptr);
325         iprop= (IntPropertyRNA*)prop;
326
327         if(iprop->range) {
328                 iprop->range(ptr, &hardmin, &hardmax);
329                 *softmin= MAX2(iprop->softmin, hardmin);
330                 *softmax= MIN2(iprop->softmax, hardmax);
331         }
332         else {
333                 *softmin= iprop->softmin;
334                 *softmax= iprop->softmax;
335         }
336
337         *step= iprop->step;
338 }
339
340 void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
341 {
342         FloatPropertyRNA *fprop;
343
344         rna_idproperty_check(&prop, ptr);
345         fprop= (FloatPropertyRNA*)prop;
346
347         if(fprop->range) {
348                 fprop->range(ptr, hardmin, hardmax);
349         }
350         else {
351                 *hardmin= fprop->hardmin;
352                 *hardmax= fprop->hardmax;
353         }
354 }
355
356 void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision)
357 {
358         FloatPropertyRNA *fprop;
359         float hardmin, hardmax;
360
361         rna_idproperty_check(&prop, ptr);
362         fprop= (FloatPropertyRNA*)prop;
363
364         if(fprop->range) {
365                 fprop->range(ptr, &hardmin, &hardmax);
366                 *softmin= MAX2(fprop->softmin, hardmin);
367                 *softmax= MIN2(fprop->softmax, hardmax);
368         }
369         else {
370                 *softmin= fprop->softmin;
371                 *softmax= fprop->softmax;
372         }
373
374         *step= fprop->step;
375         *precision= fprop->precision;
376 }
377
378 int RNA_property_string_maxlength(PointerRNA *ptr, PropertyRNA *prop)
379 {
380         StringPropertyRNA *sprop;
381         
382         rna_idproperty_check(&prop, ptr);
383         sprop= (StringPropertyRNA*)prop;
384
385         return sprop->maxlength;
386 }
387
388 void RNA_property_enum_items(PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **item, int *totitem)
389 {
390         EnumPropertyRNA *eprop;
391
392         rna_idproperty_check(&prop, ptr);
393         eprop= (EnumPropertyRNA*)prop;
394
395         *item= eprop->item;
396         *totitem= eprop->totitem;
397 }
398
399 const char *RNA_property_ui_name(PointerRNA *ptr, PropertyRNA *prop)
400 {
401         PropertyRNA *oldprop= prop;
402         IDProperty *idprop;
403
404         if((idprop=rna_idproperty_check(&prop, ptr)) && oldprop!=prop)
405                 return idprop->name;
406         else
407                 return prop->name;
408 }
409
410 const char *RNA_property_ui_description(PointerRNA *ptr, PropertyRNA *prop)
411 {
412         PropertyRNA *oldprop= prop;
413
414         if(rna_idproperty_check(&prop, ptr) && oldprop!=prop)
415                 return "";
416         else
417                 return prop->description;
418 }
419
420 int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
421 {
422         int flag;
423
424         rna_idproperty_check(&prop, ptr);
425
426         if(prop->editable)
427                 flag= prop->editable(ptr);
428         else
429                 flag= prop->flag;
430
431         return !(flag & PROP_NOT_EDITABLE);
432 }
433
434 int RNA_property_evaluated(PointerRNA *ptr, PropertyRNA *prop)
435 {
436         int flag;
437
438         rna_idproperty_check(&prop, ptr);
439
440         if(prop->editable)
441                 flag= prop->editable(ptr);
442         else
443                 flag= prop->flag;
444
445         return (flag & PROP_EVALUATED);
446 }
447
448 void RNA_property_notify(PropertyRNA *prop, struct bContext *C, PointerRNA *ptr)
449 {
450         rna_idproperty_check(&prop, ptr);
451
452         if(prop->notify)
453                 prop->notify(C, ptr);
454 }
455
456 /* Property Data */
457
458 int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
459 {
460         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
461         IDProperty *idprop;
462
463         if((idprop=rna_idproperty_check(&prop, ptr)))
464                 return IDP_Int(idprop);
465         else if(bprop->get)
466                 return bprop->get(ptr);
467         else
468                 return bprop->defaultvalue;
469 }
470
471 void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
472 {
473         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
474         IDProperty *idprop;
475
476         if((idprop=rna_idproperty_check(&prop, ptr)))
477                 IDP_Int(idprop)= value;
478         else if(bprop->set)
479                 bprop->set(ptr, value);
480         else if(!(prop->flag & PROP_NOT_EDITABLE)) {
481                 IDPropertyTemplate val;
482                 IDProperty *group;
483
484                 val.i= value;
485
486                 group= rna_idproperties_get(ptr->type, ptr->data, 1);
487                 if(group)
488                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
489         }
490 }
491
492 int RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int index)
493 {
494         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
495         IDProperty *idprop;
496
497         if((idprop=rna_idproperty_check(&prop, ptr)))
498                 return ((int*)IDP_Array(idprop))[index];
499         else if(bprop->getarray)
500                 return bprop->getarray(ptr, index);
501         else
502                 return bprop->defaultarray[index];
503 }
504
505 void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
506 {
507         BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
508         IDProperty *idprop;
509
510         if((idprop=rna_idproperty_check(&prop, ptr)))
511                 ((int*)IDP_Array(idprop))[index]= value;
512         else if(bprop->setarray)
513                 bprop->setarray(ptr, index, value);
514         else if(!(prop->flag & PROP_NOT_EDITABLE)) {
515                 IDPropertyTemplate val;
516                 IDProperty *group;
517
518                 val.array.len= prop->arraylength;
519                 val.array.type= IDP_INT;
520
521                 group= rna_idproperties_get(ptr->type, ptr->data, 1);
522                 if(group) {
523                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
524                         IDP_AddToGroup(group, idprop);
525                         memcpy(idprop->data.pointer, bprop->defaultarray, sizeof(int)*prop->arraylength);
526                         ((int*)idprop->data.pointer)[index]= value;
527                 }
528         }
529 }
530
531 int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
532 {
533         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
534         IDProperty *idprop;
535
536         if((idprop=rna_idproperty_check(&prop, ptr)))
537                 return IDP_Int(idprop);
538         else if(iprop->get)
539                 return iprop->get(ptr);
540         else
541                 return iprop->defaultvalue;
542 }
543
544 void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
545 {
546         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
547         IDProperty *idprop;
548
549         if((idprop=rna_idproperty_check(&prop, ptr)))
550                 IDP_Int(idprop)= value;
551         else if(iprop->set)
552                 iprop->set(ptr, value);
553         else if(!(prop->flag & PROP_NOT_EDITABLE)) {
554                 IDPropertyTemplate val;
555                 IDProperty *group;
556
557                 val.i= value;
558
559                 group= rna_idproperties_get(ptr->type, ptr->data, 1);
560                 if(group)
561                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
562         }
563 }
564
565 int RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int index)
566 {
567         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
568         IDProperty *idprop;
569
570         if((idprop=rna_idproperty_check(&prop, ptr)))
571                 return ((int*)IDP_Array(idprop))[index];
572         else if(iprop->getarray)
573                 return iprop->getarray(ptr, index);
574         else
575                 return iprop->defaultarray[index];
576 }
577
578 void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
579 {
580         IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
581         IDProperty *idprop;
582
583         if((idprop=rna_idproperty_check(&prop, ptr)))
584                 ((int*)IDP_Array(idprop))[index]= value;
585         else if(iprop->setarray)
586                 iprop->setarray(ptr, index, value);
587         else if(!(prop->flag & PROP_NOT_EDITABLE)) {
588                 IDPropertyTemplate val;
589                 IDProperty *group;
590
591                 val.array.len= prop->arraylength;
592                 val.array.type= IDP_INT;
593
594                 group= rna_idproperties_get(ptr->type, ptr->data, 1);
595                 if(group) {
596                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
597                         IDP_AddToGroup(group, idprop);
598                         memcpy(idprop->data.pointer, iprop->defaultarray, sizeof(int)*prop->arraylength);
599                         ((int*)idprop->data.pointer)[index]= value;
600                 }
601         }
602 }
603
604 float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
605 {
606         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
607         IDProperty *idprop;
608
609         if((idprop=rna_idproperty_check(&prop, ptr))) {
610                 if(idprop->type == IDP_FLOAT)
611                         return IDP_Float(idprop);
612                 else
613                         return (float)IDP_Double(idprop);
614         }
615         else if(fprop->get)
616                 return fprop->get(ptr);
617         else
618                 return fprop->defaultvalue;
619 }
620
621 void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
622 {
623         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
624         IDProperty *idprop;
625
626         if((idprop=rna_idproperty_check(&prop, ptr))) {
627                 if(idprop->type == IDP_FLOAT)
628                         IDP_Float(idprop)= value;
629                 else
630                         IDP_Double(idprop)= value;
631         }
632         else if(fprop->set) {
633                 fprop->set(ptr, value);
634         }
635         else if(!(prop->flag & PROP_NOT_EDITABLE)) {
636                 IDPropertyTemplate val;
637                 IDProperty *group;
638
639                 val.f= value;
640
641                 group= rna_idproperties_get(ptr->type, ptr->data, 1);
642                 if(group)
643                         IDP_AddToGroup(group, IDP_New(IDP_FLOAT, val, (char*)prop->identifier));
644         }
645 }
646
647 float RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, int index)
648 {
649         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
650         IDProperty *idprop;
651
652         if((idprop=rna_idproperty_check(&prop, ptr))) {
653                 if(idprop->type == IDP_FLOAT)
654                         return ((float*)IDP_Array(idprop))[index];
655                 else
656                         return (float)(((double*)IDP_Array(idprop))[index]);
657         }
658         else if(fprop->getarray)
659                 return fprop->getarray(ptr, index);
660         else
661                 return fprop->defaultarray[index];
662 }
663
664 void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
665 {
666         FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
667         IDProperty *idprop;
668
669         if((idprop=rna_idproperty_check(&prop, ptr))) {
670                 if(idprop->type == IDP_FLOAT)
671                         ((float*)IDP_Array(idprop))[index]= value;
672                 else
673                         ((double*)IDP_Array(idprop))[index]= value;
674         }
675         else if(fprop->setarray) {
676                 fprop->setarray(ptr, index, value);
677         }
678         else if(!(prop->flag & PROP_NOT_EDITABLE)) {
679                 IDPropertyTemplate val;
680                 IDProperty *group;
681
682                 val.array.len= prop->arraylength;
683                 val.array.type= IDP_FLOAT;
684
685                 group= rna_idproperties_get(ptr->type, ptr->data, 1);
686                 if(group) {
687                         idprop= IDP_New(IDP_ARRAY, val, (char*)prop->identifier);
688                         IDP_AddToGroup(group, idprop);
689                         memcpy(idprop->data.pointer, fprop->defaultarray, sizeof(float)*prop->arraylength);
690                         ((float*)idprop->data.pointer)[index]= value;
691                 }
692         }
693 }
694
695 void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
696 {
697         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
698         IDProperty *idprop;
699
700         if((idprop=rna_idproperty_check(&prop, ptr)))
701                 strcpy(value, IDP_String(idprop));
702         else if(sprop->get)
703                 sprop->get(ptr, value);
704         else
705                 strcpy(value, sprop->defaultvalue);
706 }
707
708 char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen)
709 {
710         char *buf;
711         int length;
712
713         length= RNA_property_string_length(ptr, prop);
714
715         if(length+1 < fixedlen)
716                 buf= fixedbuf;
717         else
718                 buf= MEM_callocN(sizeof(char)*(length+1), "RNA_string_get_alloc");
719
720         RNA_property_string_get(ptr, prop, buf);
721
722         return buf;
723 }
724
725 int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
726 {
727         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
728         IDProperty *idprop;
729
730         if((idprop=rna_idproperty_check(&prop, ptr)))
731                 return strlen(IDP_String(idprop));
732         else if(sprop->length)
733                 return sprop->length(ptr);
734         else
735                 return strlen(sprop->defaultvalue);
736 }
737
738 void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
739 {
740         StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
741         IDProperty *idprop;
742
743         if((idprop=rna_idproperty_check(&prop, ptr)))
744                 IDP_AssignString(idprop, (char*)value);
745         else if(sprop->set)
746                 sprop->set(ptr, value);
747 }
748
749 int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
750 {
751         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
752         IDProperty *idprop;
753
754         if((idprop=rna_idproperty_check(&prop, ptr)))
755                 return IDP_Int(idprop);
756         else if(eprop->get)
757                 return eprop->get(ptr);
758         else
759                 return eprop->defaultvalue;
760 }
761
762 void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
763 {
764         EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
765         IDProperty *idprop;
766
767         if((idprop=rna_idproperty_check(&prop, ptr)))
768                 IDP_Int(idprop)= value;
769         else if(eprop->set) {
770                 eprop->set(ptr, value);
771         }
772         else if(!(prop->flag & PROP_NOT_EDITABLE)) {
773                 IDPropertyTemplate val;
774                 IDProperty *group;
775
776                 val.i= value;
777
778                 group= rna_idproperties_get(ptr->type, ptr->data, 1);
779                 if(group)
780                         IDP_AddToGroup(group, IDP_New(IDP_INT, val, (char*)prop->identifier));
781         }
782 }
783
784 static StructRNA *rna_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
785 {
786         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
787         StructRNA *type;
788
789         if(pprop->type)
790                 type= pprop->type(ptr);
791         else
792                 type= pprop->structtype;
793         
794         if(type->refine)
795                 type= type->refine(r_ptr);
796         
797         r_ptr->type= type;
798         return type;
799 }
800
801 void RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
802 {
803         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
804         IDProperty *idprop;
805
806         if((idprop=rna_idproperty_check(&prop, ptr)))
807                 r_ptr->data= idprop; /* for groups, data is idprop itself */
808         else if(pprop->get)
809                 r_ptr->data= pprop->get(ptr);
810         else
811                 r_ptr->data= NULL;
812
813         if(r_ptr->data && rna_property_pointer_type(ptr, prop, r_ptr))
814                 rna_pointer_inherit_id(ptr, r_ptr);
815         else
816                 memset(r_ptr, 0, sizeof(*r_ptr));
817 }
818
819 void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *ptr_value)
820 {
821         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
822
823         if(pprop->set)
824                 pprop->set(ptr, ptr_value->data);
825 }
826
827 static StructRNA *rna_property_collection_type(CollectionPropertyIterator *iter)
828 {
829         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
830         StructRNA *type;
831
832         if(cprop->type)
833                 type= cprop->type(iter);
834         else
835                 type= cprop->structtype;
836         
837         if(type->refine)
838                 type= type->refine(&iter->ptr);
839
840         iter->ptr.type= type;
841         return type;
842 }
843
844 static void rna_property_collection_get(CollectionPropertyIterator *iter)
845 {
846         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
847
848         iter->ptr.data= cprop->get(iter);
849
850         if(iter->ptr.data && rna_property_collection_type(iter))
851                 rna_pointer_inherit_id(&iter->parent, &iter->ptr);
852         else
853                 memset(&iter->ptr, 0, sizeof(iter->ptr));
854 }
855
856 void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter)
857 {
858         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
859
860         if(cprop->begin) {
861                 iter->parent= *ptr;
862                 iter->prop= prop;
863                 cprop->begin(iter, ptr);
864
865                 if(iter->valid)
866                         rna_property_collection_get(iter);
867                 else
868                         memset(&iter->ptr, 0, sizeof(iter->ptr));
869         }
870         else
871                 memset(&iter, 0, sizeof(*iter));
872 }
873
874 void RNA_property_collection_next(CollectionPropertyIterator *iter)
875 {
876         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
877
878         cprop->next(iter);
879
880         if(iter->valid)
881                 rna_property_collection_get(iter);
882         else
883                 memset(&iter->ptr, 0, sizeof(iter->ptr));
884 }
885
886 void RNA_property_collection_end(CollectionPropertyIterator *iter)
887 {
888         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
889
890         if(cprop->end)
891                 cprop->end(iter);
892 }
893
894 int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
895 {
896         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
897
898         if(cprop->length) {
899                 return cprop->length(ptr);
900         }
901         else {
902                 CollectionPropertyIterator iter;
903                 int length= 0;
904
905                 RNA_property_collection_begin(ptr, prop, &iter);
906                 for(; iter.valid; RNA_property_collection_next(&iter))
907                         length++;
908                 RNA_property_collection_end(&iter);
909
910                 return length;
911         }
912 }
913
914 int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
915 {
916         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
917
918         if(cprop->lookupint) {
919                 /* we have a callback defined, use it */
920                 r_ptr->data= cprop->lookupint(ptr, key, &r_ptr->type);
921
922                 if(r_ptr->data) {
923                         if(!r_ptr->type)
924                                 r_ptr->type= cprop->structtype;
925                         rna_pointer_inherit_id(ptr, r_ptr);
926
927                         return 1;
928                 }
929                 else {
930                         memset(r_ptr, 0, sizeof(*r_ptr));
931                         return 0;
932                 }
933         }
934         else {
935                 /* no callback defined, just iterate and find the nth item */
936                 CollectionPropertyIterator iter;
937                 int i;
938
939                 RNA_property_collection_begin(ptr, prop, &iter);
940                 for(i=0; iter.valid; RNA_property_collection_next(&iter), i++) {
941                         if(i == key) {
942                                 *r_ptr= iter.ptr;
943                                 break;
944                         }
945                 }
946                 RNA_property_collection_end(&iter);
947
948                 if(!iter.valid)
949                         memset(r_ptr, 0, sizeof(*r_ptr));
950
951                 return iter.valid;
952         }
953 }
954
955 int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr)
956 {
957         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
958
959         if(cprop->lookupstring) {
960                 /* we have a callback defined, use it */
961                 r_ptr->data= cprop->lookupstring(ptr, key, &r_ptr->type);
962
963                 if(r_ptr->data) {
964                         if(!r_ptr->type)
965                                 r_ptr->type= cprop->structtype;
966                         rna_pointer_inherit_id(ptr, r_ptr);
967
968                         return 1;
969                 }
970                 else {
971                         memset(r_ptr, 0, sizeof(*r_ptr));
972                         return 0;
973                 }
974         }
975         else {
976                 /* no callback defined, compare with name properties if they exist */
977                 CollectionPropertyIterator iter;
978                 PropertyRNA *nameprop;
979                 char name[256], *nameptr;
980                 int length, alloc, found= 0;
981
982                 RNA_property_collection_begin(ptr, prop, &iter);
983                 for(; iter.valid; RNA_property_collection_next(&iter)) {
984                         if(iter.ptr.data && iter.ptr.type->nameproperty) {
985                                 nameprop= iter.ptr.type->nameproperty;
986
987                                 length= RNA_property_string_length(&iter.ptr, nameprop);
988
989                                 if(sizeof(name)-1 < length) {
990                                         nameptr= name;
991                                         alloc= 0;
992                                 }
993                                 else {
994                                         nameptr= MEM_mallocN(sizeof(char)*length+1, "RNA_lookup_string");
995                                         alloc= 1;
996                                 }
997
998                                 RNA_property_string_get(&iter.ptr, nameprop, nameptr);
999
1000                                 if(strcmp(nameptr, key) == 0) {
1001                                         *r_ptr= iter.ptr;
1002                                         found= 1;
1003                                 }
1004
1005                                 if(alloc)
1006                                         MEM_freeN(nameptr);
1007
1008                                 if(found)
1009                                         break;
1010                         }
1011                 }
1012                 RNA_property_collection_end(&iter);
1013
1014                 if(!iter.valid)
1015                         memset(r_ptr, 0, sizeof(*r_ptr));
1016
1017                 return iter.valid;
1018         }
1019 }
1020
1021 /* Standard iterator functions */
1022
1023 void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip)
1024 {
1025         ListBaseIterator *internal;
1026
1027         internal= MEM_callocN(sizeof(ListBaseIterator), "ListBaseIterator");
1028         internal->link= lb->first;
1029         internal->skip= skip;
1030
1031         iter->internal= internal;
1032         iter->valid= (internal->link != NULL);
1033
1034         if(skip && iter->valid && skip(iter, internal->link))
1035                 rna_iterator_listbase_next(iter);
1036 }
1037
1038 void rna_iterator_listbase_next(CollectionPropertyIterator *iter)
1039 {
1040         ListBaseIterator *internal= iter->internal;
1041
1042         if(internal->skip) {
1043                 do {
1044                         internal->link= internal->link->next;
1045                         iter->valid= (internal->link != NULL);
1046                 } while(iter->valid && internal->skip(iter, internal->link));
1047         }
1048         else {
1049                 internal->link= internal->link->next;
1050                 iter->valid= (internal->link != NULL);
1051         }
1052 }
1053
1054 void *rna_iterator_listbase_get(CollectionPropertyIterator *iter)
1055 {
1056         ListBaseIterator *internal= iter->internal;
1057
1058         return internal->link;
1059 }
1060
1061 void rna_iterator_listbase_end(CollectionPropertyIterator *iter)
1062 {
1063         MEM_freeN(iter->internal);
1064 }
1065
1066 void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int itemsize, int length, IteratorSkipFunc skip)
1067 {
1068         ArrayIterator *internal;
1069
1070         if(ptr == NULL)
1071                 length= 0;
1072
1073         internal= MEM_callocN(sizeof(ArrayIterator), "ArrayIterator");
1074         internal->ptr= ptr;
1075         internal->endptr= ((char*)ptr)+length*itemsize;
1076         internal->itemsize= itemsize;
1077         internal->skip= skip;
1078
1079         iter->internal= internal;
1080         iter->valid= (internal->ptr != internal->endptr);
1081
1082         if(skip && iter->valid && skip(iter, internal->ptr))
1083                 rna_iterator_array_next(iter);
1084 }
1085
1086 void rna_iterator_array_next(CollectionPropertyIterator *iter)
1087 {
1088         ArrayIterator *internal= iter->internal;
1089
1090         if(internal->skip) {
1091                 do {
1092                         internal->ptr += internal->itemsize;
1093                         iter->valid= (internal->ptr != internal->endptr);
1094                 } while(iter->valid && internal->skip(iter, internal->ptr));
1095         }
1096         else {
1097                 internal->ptr += internal->itemsize;
1098                 iter->valid= (internal->ptr != internal->endptr);
1099         }
1100 }
1101
1102 void *rna_iterator_array_get(CollectionPropertyIterator *iter)
1103 {
1104         ArrayIterator *internal= iter->internal;
1105
1106         return internal->ptr;
1107 }
1108
1109 void rna_iterator_array_end(CollectionPropertyIterator *iter)
1110 {
1111         MEM_freeN(iter->internal);
1112 }
1113
1114 /* RNA Path - Experiment */
1115
1116 static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int bracket)
1117 {
1118         const char *p;
1119         char *buf;
1120         int i, j, len, escape;
1121
1122         len= 0;
1123
1124         if(bracket) {
1125                 /* get data between [], check escaping ] with \] */
1126                 if(**path == '[') (*path)++;
1127                 else return NULL;
1128
1129                 p= *path;
1130
1131                 escape= 0;
1132                 while(*p && (*p != ']' || escape)) {
1133                         escape= (*p == '\\');
1134                         len++;
1135                         p++;
1136                 }
1137
1138                 if(*p != ']') return NULL;
1139         }
1140         else {
1141                 /* get data until . or [ */
1142                 p= *path;
1143
1144                 while(*p && *p != '.' && *p != '[') {
1145                         len++;
1146                         p++;
1147                 }
1148         }
1149         
1150         /* empty, return */
1151         if(len == 0)
1152                 return NULL;
1153         
1154         /* try to use fixed buffer if possible */
1155         if(len+1 < fixedlen)
1156                 buf= fixedbuf;
1157         else
1158                 buf= MEM_callocN(sizeof(char)*(len+1), "rna_path_token");
1159
1160         /* copy string, taking into account escaped ] */
1161         for(p=*path, i=0, j=0; i<len; i++, p++) {
1162                 if(*p == '\\' && *(p+1) == ']');
1163                 else buf[j++]= *p;
1164         }
1165
1166         buf[j]= 0;
1167
1168         /* set path to start of next token */
1169         if(*p == ']') p++;
1170         if(*p == '.') p++;
1171         *path= p;
1172
1173         return buf;
1174 }
1175
1176 int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
1177 {
1178         CollectionPropertyIterator iter;
1179         PropertyRNA *prop, *iterprop;
1180         PointerRNA curptr, nextptr;
1181         char fixedbuf[256], *token;
1182         int len, intkey;
1183
1184         prop= NULL;
1185         curptr= *ptr;
1186
1187         while(*path) {
1188                 /* look up property name in current struct */
1189                 token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 0);
1190
1191                 if(!token)
1192                         return 0;
1193
1194                 iterprop= RNA_struct_iterator_property(&curptr);
1195                 RNA_property_collection_begin(&curptr, iterprop, &iter);
1196                 prop= NULL;
1197
1198                 for(; iter.valid; RNA_property_collection_next(&iter)) {
1199                         if(strcmp(token, RNA_property_identifier(&iter.ptr, iter.ptr.data)) == 0) {
1200                                 prop= iter.ptr.data;
1201                                 break;
1202                         }
1203                 }
1204
1205                 RNA_property_collection_end(&iter);
1206
1207                 if(token != fixedbuf)
1208                         MEM_freeN(token);
1209
1210                 if(!prop)
1211                         return 0;
1212
1213                 /* now look up the value of this property if it is a pointer or
1214                  * collection, otherwise return the property rna so that the
1215                  * caller can read the value of the property itself */
1216                 if(RNA_property_type(&curptr, prop) == PROP_POINTER) {
1217                         RNA_property_pointer_get(&curptr, prop, &nextptr);
1218
1219                         if(nextptr.data)
1220                                 curptr= nextptr;
1221                         else
1222                                 return 0;
1223                 }
1224                 else if(RNA_property_type(&curptr, prop) == PROP_COLLECTION && *path) {
1225                         /* resolve the lookup with [] brackets */
1226                         token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1);
1227
1228                         if(!token)
1229                                 return 0;
1230
1231                         len= strlen(token);
1232
1233                         /* check for "" to see if it is a string */
1234                         if(len >= 2 && *token == '"' && token[len-2] == '"') {
1235                                 /* strip away "" */
1236                                 token[len-2]= 0;
1237                                 RNA_property_collection_lookup_string(&curptr, prop, token+1, &nextptr);
1238                         }
1239                         else {
1240                                 /* otherwise do int lookup */
1241                                 intkey= atoi(token);
1242                                 RNA_property_collection_lookup_int(&curptr, prop, intkey, &nextptr);
1243                         }
1244
1245                         if(token != fixedbuf)
1246                                 MEM_freeN(token);
1247
1248                         if(nextptr.data)
1249                                 curptr= nextptr;
1250                         else
1251                                 return 0;
1252                 }
1253         }
1254
1255         *r_ptr= curptr;
1256         *r_prop= prop;
1257
1258         return 1;
1259 }
1260
1261 char *RNA_path_append(const char *path, PointerRNA *ptr, PropertyRNA *prop, int intkey, const char *strkey)
1262 {
1263         DynStr *dynstr;
1264         const char *s;
1265         char appendstr[128], *result;
1266         
1267         dynstr= BLI_dynstr_new();
1268
1269         /* add .identifier */
1270         if(path) {
1271                 BLI_dynstr_append(dynstr, (char*)path);
1272                 if(*path)
1273                         BLI_dynstr_append(dynstr, ".");
1274         }
1275
1276         BLI_dynstr_append(dynstr, (char*)RNA_property_identifier(ptr, prop));
1277
1278         if(RNA_property_type(ptr, prop) == PROP_COLLECTION) {
1279                 /* add ["strkey"] or [intkey] */
1280                 BLI_dynstr_append(dynstr, "[");
1281
1282                 if(strkey) {
1283                         BLI_dynstr_append(dynstr, "\"");
1284                         for(s=strkey; *s; s++) {
1285                                 if(*s == '[') {
1286                                         appendstr[0]= '\\';
1287                                         appendstr[1]= *s;
1288                                         appendstr[2]= 0;
1289                                 }
1290                                 else {
1291                                         appendstr[0]= *s;
1292                                         appendstr[1]= 0;
1293                                 }
1294                                 BLI_dynstr_append(dynstr, appendstr);
1295                         }
1296                         BLI_dynstr_append(dynstr, "\"");
1297                 }
1298                 else {
1299                         sprintf(appendstr, "%d", intkey);
1300                         BLI_dynstr_append(dynstr, appendstr);
1301                 }
1302
1303                 BLI_dynstr_append(dynstr, "]");
1304         }
1305
1306         result= BLI_dynstr_get_cstring(dynstr);
1307         BLI_dynstr_free(dynstr);
1308
1309         return result;
1310 }
1311
1312 char *RNA_path_back(const char *path)
1313 {
1314         char fixedbuf[256];
1315         const char *previous, *current;
1316         char *result, *token;
1317         int i;
1318
1319         if(!path)
1320                 return NULL;
1321
1322         previous= NULL;
1323         current= path;
1324
1325         /* parse token by token until the end, then we back up to the previous
1326          * position and strip of the next token to get the path one step back */
1327         while(*current) {
1328                 token= rna_path_token(&current, fixedbuf, sizeof(fixedbuf), 0);
1329
1330                 if(!token)
1331                         return NULL;
1332                 if(token != fixedbuf)
1333                         MEM_freeN(token);
1334
1335                 /* in case of collection we also need to strip off [] */
1336                 token= rna_path_token(&current, fixedbuf, sizeof(fixedbuf), 1);
1337                 if(token && token != fixedbuf)
1338                         MEM_freeN(token);
1339                 
1340                 if(!*current)
1341                         break;
1342
1343                 previous= current;
1344         }
1345
1346         if(!previous)
1347                 return NULL;
1348
1349         /* copy and strip off last token */
1350         i= previous - path;
1351         result= BLI_strdup(path);
1352
1353         if(i > 0 && result[i-1] == '.') i--;
1354         result[i]= 0;
1355
1356         return result;
1357 }
1358
1359 /* Quick name based property access */
1360
1361 int RNA_boolean_get(PointerRNA *ptr, const char *name)
1362 {
1363         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1364
1365         if(prop) {
1366                 return RNA_property_boolean_get(ptr, prop);
1367         }
1368         else {
1369                 printf("RNA_boolean_get: %s.%s not found.\n", ptr->type->identifier, name);
1370                 return 0;
1371         }
1372 }
1373
1374 void RNA_boolean_set(PointerRNA *ptr, const char *name, int value)
1375 {
1376         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1377
1378         if(prop)
1379                 RNA_property_boolean_set(ptr, prop, value);
1380         else
1381                 printf("RNA_boolean_set: %s.%s not found.\n", ptr->type->identifier, name);
1382 }
1383
1384 void RNA_boolean_get_array(PointerRNA *ptr, const char *name, int *values)
1385 {
1386         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1387         int i, length;
1388
1389         if(prop) {
1390                 length= RNA_property_array_length(ptr, prop);
1391                 for(i=0; i<length; i++)
1392                         values[i]= RNA_property_boolean_get_array(ptr, prop, i);
1393         }
1394         else
1395                 printf("RNA_boolean_get_array: %s.%s not found.\n", ptr->type->identifier, name);
1396 }
1397
1398 void RNA_boolean_set_array(PointerRNA *ptr, const char *name, const int *values)
1399 {
1400         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1401         int i, length;
1402
1403         if(prop) {
1404                 length= RNA_property_array_length(ptr, prop);
1405                 for(i=0; i<length; i++)
1406                         RNA_property_boolean_set_array(ptr, prop, i, values[i]);
1407         }
1408         else
1409                 printf("RNA_boolean_set_array: %s.%s not found.\n", ptr->type->identifier, name);
1410 }
1411
1412 int RNA_int_get(PointerRNA *ptr, const char *name)
1413 {
1414         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1415
1416         if(prop) {
1417                 return RNA_property_int_get(ptr, prop);
1418         }
1419         else {
1420                 printf("RNA_int_get: %s.%s not found.\n", ptr->type->identifier, name);
1421                 return 0;
1422         }
1423 }
1424
1425 void RNA_int_set(PointerRNA *ptr, const char *name, int value)
1426 {
1427         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1428
1429         if(prop)
1430                 RNA_property_int_set(ptr, prop, value);
1431         else
1432                 printf("RNA_int_set: %s.%s not found.\n", ptr->type->identifier, name);
1433 }
1434
1435 void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values)
1436 {
1437         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1438         int i, length;
1439
1440         if(prop) {
1441                 length= RNA_property_array_length(ptr, prop);
1442                 for(i=0; i<length; i++)
1443                         values[i]= RNA_property_int_get_array(ptr, prop, i);
1444         }
1445         else
1446                 printf("RNA_int_get_array: %s.%s not found.\n", ptr->type->identifier, name);
1447 }
1448
1449 void RNA_int_set_array(PointerRNA *ptr, const char *name, const int *values)
1450 {
1451         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1452         int i, length;
1453
1454         if(prop) {
1455                 length= RNA_property_array_length(ptr, prop);
1456                 for(i=0; i<length; i++)
1457                         RNA_property_int_set_array(ptr, prop, i, values[i]);
1458         }
1459         else
1460                 printf("RNA_int_set_array: %s.%s not found.\n", ptr->type->identifier, name);
1461 }
1462
1463 float RNA_float_get(PointerRNA *ptr, const char *name)
1464 {
1465         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1466
1467         if(prop) {
1468                 return RNA_property_float_get(ptr, prop);
1469         }
1470         else {
1471                 printf("RNA_float_get: %s.%s not found.\n", ptr->type->identifier, name);
1472                 return 0;
1473         }
1474 }
1475
1476 void RNA_float_set(PointerRNA *ptr, const char *name, float value)
1477 {
1478         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1479
1480         if(prop)
1481                 RNA_property_float_set(ptr, prop, value);
1482         else
1483                 printf("RNA_float_set: %s.%s not found.\n", ptr->type->identifier, name);
1484 }
1485
1486 void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
1487 {
1488         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1489         int i, length;
1490
1491         if(prop) {
1492                 length= RNA_property_array_length(ptr, prop);
1493                 for(i=0; i<length; i++)
1494                         values[i]= RNA_property_float_get_array(ptr, prop, i);
1495         }
1496         else
1497                 printf("RNA_float_get_array: %s.%s not found.\n", ptr->type->identifier, name);
1498 }
1499
1500 void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
1501 {
1502         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1503         int i, length;
1504
1505         if(prop) {
1506                 length= RNA_property_array_length(ptr, prop);
1507                 for(i=0; i<length; i++)
1508                         RNA_property_float_set_array(ptr, prop, i, values[i]);
1509         }
1510         else
1511                 printf("RNA_float_set_array: %s.%s not found.\n", ptr->type->identifier, name);
1512 }
1513
1514 int RNA_enum_get(PointerRNA *ptr, const char *name)
1515 {
1516         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1517
1518         if(prop) {
1519                 return RNA_property_enum_get(ptr, prop);
1520         }
1521         else {
1522                 printf("RNA_enum_get: %s.%s not found.\n", ptr->type->identifier, name);
1523                 return 0;
1524         }
1525 }
1526
1527 void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
1528 {
1529         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1530
1531         if(prop)
1532                 RNA_property_enum_set(ptr, prop, value);
1533         else
1534                 printf("RNA_enum_set: %s.%s not found.\n", ptr->type->identifier, name);
1535 }
1536
1537 void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
1538 {
1539         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1540
1541         if(prop)
1542                 RNA_property_string_get(ptr, prop, value);
1543         else
1544                 printf("RNA_string_get: %s.%s not found.\n", ptr->type->identifier, name);
1545 }
1546
1547 char *RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen)
1548 {
1549         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1550
1551         if(prop) {
1552                 return RNA_property_string_get_alloc(ptr, prop, fixedbuf, fixedlen);
1553         }
1554         else {
1555                 printf("RNA_string_get_alloc: %s.%s not found.\n", ptr->type->identifier, name);
1556                 return 0;
1557         }
1558 }
1559
1560 int RNA_string_length(PointerRNA *ptr, const char *name)
1561 {
1562         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1563
1564         if(prop) {
1565                 return RNA_property_string_length(ptr, prop);
1566         }
1567         else {
1568                 printf("RNA_string_length: %s.%s not found.\n", ptr->type->identifier, name);
1569                 return 0;
1570         }
1571 }
1572
1573 void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
1574 {
1575         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1576
1577         if(prop)
1578                 RNA_property_string_set(ptr, prop, value);
1579         else
1580                 printf("RNA_string_set: %s.%s not found.\n", ptr->type->identifier, name);
1581 }
1582
1583 int RNA_property_is_set(PointerRNA *ptr, const char *name)
1584 {
1585         PropertyRNA *prop= RNA_struct_find_property(ptr, name);
1586
1587         if(prop) {
1588                 return (rna_idproperty_find(ptr, name) != NULL);
1589         }
1590         else {
1591                 printf("RNA_property_is_set: %s.%s not found.\n", ptr->type->identifier, name);
1592                 return 0;
1593         }
1594 }
1595