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