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