Blender V2.61 - r43446

rna_access.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * Contributor(s): Blender Foundation (2008).
00019  *
00020  * ***** END GPL LICENSE BLOCK *****
00021  */
00022 
00028 #include <stdlib.h>
00029 #include <stddef.h>
00030 #include <string.h>
00031 #include <ctype.h>
00032 
00033 #include "MEM_guardedalloc.h"
00034 
00035 #include "DNA_ID.h"
00036 #include "DNA_scene_types.h"
00037 #include "DNA_windowmanager_types.h"
00038 
00039 #include "BLI_blenlib.h"
00040 #include "BLI_utildefines.h"
00041 #include "BLI_dynstr.h"
00042 #include "BLI_ghash.h"
00043 
00044 #include "BLF_api.h"
00045 #include "BLF_translation.h"
00046 
00047 #include "BKE_animsys.h"
00048 #include "BKE_context.h"
00049 #include "BKE_idprop.h"
00050 #include "BKE_main.h"
00051 #include "BKE_report.h"
00052 
00053 
00054 #include "WM_api.h"
00055 
00056 #include "RNA_access.h"
00057 #include "RNA_define.h"
00058 
00059 /* flush updates */
00060 #include "DNA_object_types.h"
00061 #include "BKE_depsgraph.h"
00062 #include "WM_types.h"
00063 
00064 #include "rna_internal.h"
00065 
00066 const PointerRNA PointerRNA_NULL= {{NULL}};
00067 
00068 /* Init/Exit */
00069 
00070 void RNA_init(void)
00071 {
00072     StructRNA *srna;
00073     PropertyRNA *prop;
00074 
00075     for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
00076         if(!srna->cont.prophash) {
00077             srna->cont.prophash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "RNA_init gh");
00078 
00079             for(prop=srna->cont.properties.first; prop; prop=prop->next)
00080                 if(!(prop->flag & PROP_BUILTIN))
00081                     BLI_ghash_insert(srna->cont.prophash, (void*)prop->identifier, prop);
00082         }
00083     }
00084 }
00085 
00086 void RNA_exit(void)
00087 {
00088     StructRNA *srna;
00089     
00090     RNA_property_update_cache_free();
00091     
00092     for(srna=BLENDER_RNA.structs.first; srna; srna=srna->cont.next) {
00093         if(srna->cont.prophash) {
00094             BLI_ghash_free(srna->cont.prophash, NULL, NULL);
00095             srna->cont.prophash= NULL;
00096         }
00097     }
00098 
00099     RNA_free(&BLENDER_RNA);
00100 }
00101 
00102 /* Pointer */
00103 
00104 void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr)
00105 {
00106     r_ptr->id.data= NULL;
00107     r_ptr->type= &RNA_BlendData;
00108     r_ptr->data= main;
00109 }
00110 
00111 void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
00112 {
00113     StructRNA *type, *idtype= NULL;
00114 
00115     if(id) {
00116         PointerRNA tmp= {{NULL}};
00117         tmp.data= id;
00118         idtype= rna_ID_refine(&tmp);
00119         
00120         while(idtype->refine) {
00121             type= idtype->refine(&tmp);
00122 
00123             if(type == idtype)
00124                 break;
00125             else
00126                 idtype= type;
00127         }
00128     }
00129     
00130     r_ptr->id.data= id;
00131     r_ptr->type= idtype;
00132     r_ptr->data= id;
00133 }
00134 
00135 void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
00136 {
00137 #if 0 /* UNUSED */
00138     StructRNA *idtype= NULL;
00139 
00140     if(id) {
00141         PointerRNA tmp= {{0}};
00142         tmp.data= id;
00143         idtype= rna_ID_refine(&tmp);
00144     }
00145 #endif
00146 
00147     r_ptr->id.data= id;
00148     r_ptr->type= type;
00149     r_ptr->data= data;
00150 
00151     if(data) {
00152         while(r_ptr->type && r_ptr->type->refine) {
00153             StructRNA *rtype= r_ptr->type->refine(r_ptr);
00154 
00155             if(rtype == r_ptr->type)
00156                 break;
00157             else
00158                 r_ptr->type= rtype;
00159         }
00160     }
00161 }
00162 
00163 static void rna_pointer_inherit_id(StructRNA *type, PointerRNA *parent, PointerRNA *ptr)
00164 {
00165     if(type && type->flag & STRUCT_ID) {
00166         ptr->id.data= ptr->data;
00167     }
00168     else {
00169         ptr->id.data= parent->id.data;
00170     }
00171 }
00172 
00173 void RNA_blender_rna_pointer_create(PointerRNA *r_ptr)
00174 {
00175     r_ptr->id.data= NULL;
00176     r_ptr->type= &RNA_BlenderRNA;
00177     r_ptr->data= &BLENDER_RNA;
00178 }
00179 
00180 PointerRNA rna_pointer_inherit_refine(PointerRNA *ptr, StructRNA *type, void *data)
00181 {
00182     if(data) {
00183         PointerRNA result;
00184         result.data= data;
00185         result.type= type;
00186         rna_pointer_inherit_id(type, ptr, &result);
00187 
00188         while(result.type->refine) {
00189             type= result.type->refine(&result);
00190 
00191             if(type == result.type)
00192                 break;
00193             else
00194                 result.type= type;
00195         }
00196         return result;
00197     }
00198     else {
00199         return PointerRNA_NULL;
00200     }
00201 }
00202 
00203 
00204 void RNA_pointer_recast(PointerRNA *ptr, PointerRNA *r_ptr)
00205 {
00206 #if 0 // works but this case if covered by more general code below.
00207     if(RNA_struct_is_ID(ptr->type)) {
00208         /* simple case */
00209         RNA_id_pointer_create(ptr->id.data, r_ptr);
00210     }
00211     else
00212 #endif
00213     {
00214         StructRNA *base;
00215         PointerRNA t_ptr;
00216         *r_ptr= *ptr; /* initialize as the same incase cant recast */
00217 
00218         for(base=ptr->type->base; base; base=base->base) {
00219             t_ptr= rna_pointer_inherit_refine(ptr, base, ptr->data);
00220             if(t_ptr.type && t_ptr.type != ptr->type) {
00221                 *r_ptr= t_ptr;
00222             }
00223         }
00224     }
00225 }
00226 
00227 /* ID Properties */
00228 
00229 static void rna_idproperty_touch(IDProperty *idprop)
00230 {
00231     /* so the property is seen as 'set' by rna */
00232     idprop->flag &= ~IDP_FLAG_GHOST;
00233 }
00234 
00235 /* return a UI local ID prop definition for this prop */
00236 IDProperty *rna_idproperty_ui(PropertyRNA *prop)
00237 {
00238     IDProperty *idprop;
00239 
00240     for(idprop= ((IDProperty *)prop)->prev; idprop; idprop= idprop->prev) {
00241         if (strcmp(RNA_IDP_UI, idprop->name)==0)
00242             break;
00243     }
00244 
00245     if(idprop==NULL) {
00246         for(idprop= ((IDProperty *)prop)->next; idprop; idprop= idprop->next) {
00247             if (strcmp(RNA_IDP_UI, idprop->name)==0)
00248                 break;
00249         }
00250     }
00251 
00252     if (idprop) {
00253         return IDP_GetPropertyTypeFromGroup(idprop, ((IDProperty *)prop)->name, IDP_GROUP);
00254     }
00255 
00256     return NULL;
00257 }
00258 
00259 IDProperty *RNA_struct_idprops(PointerRNA *ptr, int create)
00260 {
00261     StructRNA *type= ptr->type;
00262 
00263     if(type && type->idproperties)
00264         return type->idproperties(ptr, create);
00265     
00266     return NULL;
00267 }
00268 
00269 int RNA_struct_idprops_check(StructRNA *srna)
00270 {
00271     return (srna && srna->idproperties) ? 1 : 0;
00272 }
00273 
00274 static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name)
00275 {
00276     IDProperty *group= RNA_struct_idprops(ptr, 0);
00277 
00278     if(group)
00279         return IDP_GetPropertyFromGroup(group, name);
00280 
00281     return NULL;
00282 }
00283 
00284 static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
00285 {
00286     if(prop->magic == RNA_MAGIC) {
00287         int arraylen[RNA_MAX_ARRAY_DIMENSION];
00288         return (prop->getlength && ptr->data)? prop->getlength(ptr, arraylen): prop->totarraylength;
00289     }
00290     else {
00291         IDProperty *idprop= (IDProperty*)prop;
00292 
00293         if(idprop->type == IDP_ARRAY)
00294             return idprop->len;
00295         else
00296             return 0;
00297     }
00298 }
00299 
00300 static int rna_ensure_property_array_check(PropertyRNA *prop)
00301 {
00302     if(prop->magic == RNA_MAGIC) {
00303         return (prop->getlength || prop->totarraylength) ? 1:0;
00304     }
00305     else {
00306         IDProperty *idprop= (IDProperty*)prop;
00307 
00308         return idprop->type == IDP_ARRAY ? 1:0;
00309     }
00310 }
00311 
00312 static void rna_ensure_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int length[])
00313 {
00314     if(prop->magic == RNA_MAGIC) {
00315         if(prop->getlength)
00316             prop->getlength(ptr, length);
00317         else
00318             memcpy(length, prop->arraylength, prop->arraydimension*sizeof(int));
00319     }
00320     else {
00321         IDProperty *idprop= (IDProperty*)prop;
00322 
00323         if(idprop->type == IDP_ARRAY)
00324             length[0]= idprop->len;
00325         else
00326             length[0]= 0;
00327     }
00328 }
00329 
00330 static int rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDProperty *idprop)
00331 {
00332     /* this verifies if the idproperty actually matches the property
00333      * description and otherwise removes it. this is to ensure that
00334      * rna property access is type safe, e.g. if you defined the rna
00335      * to have a certain array length you can count on that staying so */
00336     
00337     switch(idprop->type) {
00338         case IDP_IDPARRAY:
00339             if(prop->type != PROP_COLLECTION)
00340                 return 0;
00341             break;
00342         case IDP_ARRAY:
00343             if(rna_ensure_property_array_length(ptr, prop) != idprop->len)
00344                 return 0;
00345 
00346             if(idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT)
00347                 return 0;
00348             if(idprop->subtype == IDP_INT && !ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
00349                 return 0;
00350 
00351             break;
00352         case IDP_INT:
00353             if(!ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
00354                 return 0;
00355             break;
00356         case IDP_FLOAT:
00357         case IDP_DOUBLE:
00358             if(prop->type != PROP_FLOAT)
00359                 return 0;
00360             break;
00361         case IDP_STRING:
00362             if(prop->type != PROP_STRING)
00363                 return 0;
00364             break;
00365         case IDP_GROUP:
00366             if(prop->type != PROP_POINTER)
00367                 return 0;
00368             break;
00369         default:
00370             return 0;
00371     }
00372 
00373     return 1;
00374 }
00375 
00376 static PropertyRNA *typemap[IDP_NUMTYPES] =
00377     {(PropertyRNA*)&rna_PropertyGroupItem_string,
00378      (PropertyRNA*)&rna_PropertyGroupItem_int,
00379      (PropertyRNA*)&rna_PropertyGroupItem_float,
00380      NULL, NULL, NULL,
00381      (PropertyRNA*)&rna_PropertyGroupItem_group, NULL,
00382      (PropertyRNA*)&rna_PropertyGroupItem_double,
00383      (PropertyRNA*)&rna_PropertyGroupItem_idp_array};
00384 
00385 static PropertyRNA *arraytypemap[IDP_NUMTYPES] =
00386     {NULL, (PropertyRNA*)&rna_PropertyGroupItem_int_array,
00387      (PropertyRNA*)&rna_PropertyGroupItem_float_array,
00388      NULL, NULL, NULL,
00389      (PropertyRNA*)&rna_PropertyGroupItem_collection, NULL,
00390      (PropertyRNA*)&rna_PropertyGroupItem_double_array};
00391 
00392 IDProperty *rna_idproperty_check(PropertyRNA **prop, PointerRNA *ptr)
00393 {
00394     /* This is quite a hack, but avoids some complexity in the API. we
00395      * pass IDProperty structs as PropertyRNA pointers to the outside.
00396      * We store some bytes in PropertyRNA structs that allows us to
00397      * distinguish it from IDProperty structs. If it is an ID property,
00398      * we look up an IDP PropertyRNA based on the type, and set the data
00399      * pointer to the IDProperty. */
00400 
00401     if((*prop)->magic == RNA_MAGIC) {
00402         if((*prop)->flag & PROP_IDPROPERTY) {
00403             IDProperty *idprop= rna_idproperty_find(ptr, (*prop)->identifier);
00404 
00405             if(idprop && !rna_idproperty_verify_valid(ptr, *prop, idprop)) {
00406                 IDProperty *group= RNA_struct_idprops(ptr, 0);
00407 
00408                 IDP_RemFromGroup(group, idprop);
00409                 IDP_FreeProperty(idprop);
00410                 MEM_freeN(idprop);
00411                 return NULL;
00412             }
00413 
00414             return idprop;
00415         }
00416         else
00417             return NULL;
00418     }
00419 
00420     {
00421         IDProperty *idprop= (IDProperty*)(*prop);
00422 
00423         if(idprop->type == IDP_ARRAY)
00424             *prop= arraytypemap[(int)(idprop->subtype)];
00425         else 
00426             *prop= typemap[(int)(idprop->type)];
00427 
00428         return idprop;
00429     }
00430 }
00431 
00432 static PropertyRNA *rna_ensure_property(PropertyRNA *prop)
00433 {
00434     /* the quick version if we don't need the idproperty */
00435 
00436     if(prop->magic == RNA_MAGIC)
00437         return prop;
00438 
00439     {
00440         IDProperty *idprop= (IDProperty*)prop;
00441 
00442         if(idprop->type == IDP_ARRAY)
00443             return arraytypemap[(int)(idprop->subtype)];
00444         else 
00445             return typemap[(int)(idprop->type)];
00446     }
00447 }
00448 
00449 static const char *rna_ensure_property_identifier(PropertyRNA *prop)
00450 {
00451     if(prop->magic == RNA_MAGIC)
00452         return prop->identifier;
00453     else
00454         return ((IDProperty*)prop)->name;
00455 }
00456 
00457 static const char *rna_ensure_property_description(PropertyRNA *prop)
00458 {
00459     const char *description= NULL;
00460 
00461     if(prop->magic == RNA_MAGIC)
00462         description= prop->description;
00463     else {
00464         /* attempt to get the local ID values */
00465         IDProperty *idp_ui= rna_idproperty_ui(prop);
00466 
00467         if(idp_ui) {
00468             IDProperty *item= IDP_GetPropertyTypeFromGroup(idp_ui, "description", IDP_STRING);
00469             if(item)
00470                 description= IDP_String(item);
00471         }
00472 
00473         if(description == NULL)
00474             description= ((IDProperty*)prop)->name; /* XXX - not correct */
00475     }
00476 
00477 #ifdef WITH_INTERNATIONAL
00478     if(description && (U.transopts&USER_DOTRANSLATE) && (U.transopts&USER_TR_TOOLTIPS))
00479         description= BLF_gettext(description);
00480 #endif
00481 
00482     return description;
00483 }
00484 
00485 static const char *rna_ensure_property_name(PropertyRNA *prop)
00486 {
00487     const char *name;
00488 
00489     if(prop->magic == RNA_MAGIC)
00490         name= prop->name;
00491     else
00492         name= ((IDProperty*)prop)->name;
00493 
00494 #ifdef WITH_INTERNATIONAL
00495     if((U.transopts&USER_DOTRANSLATE) && (U.transopts&USER_TR_IFACE)) {
00496         if(prop->translation_context)
00497             name = BLF_pgettext(prop->translation_context, name);
00498         else
00499             name = BLF_gettext(name);
00500     }
00501 #endif
00502 
00503     return name;
00504 }
00505 
00506 /* Structs */
00507 
00508 StructRNA *RNA_struct_find(const char *identifier)
00509 {
00510     StructRNA *type;
00511     if (identifier) {
00512         for (type = BLENDER_RNA.structs.first; type; type = type->cont.next)
00513             if (strcmp(type->identifier, identifier)==0)
00514                 return type;
00515     }
00516     return NULL;
00517 }
00518 
00519 const char *RNA_struct_identifier(StructRNA *type)
00520 {
00521     return type->identifier;
00522 }
00523 
00524 const char *RNA_struct_ui_name(StructRNA *type)
00525 {
00526     return type->name;
00527 }
00528 
00529 int RNA_struct_ui_icon(StructRNA *type)
00530 {
00531     if(type)
00532         return type->icon;
00533     else
00534         return ICON_DOT;
00535 }
00536 
00537 const char *RNA_struct_ui_description(StructRNA *type)
00538 {
00539     return type->description;
00540 }
00541 
00542 PropertyRNA *RNA_struct_name_property(StructRNA *type)
00543 {
00544     return type->nameproperty;
00545 }
00546 
00547 PropertyRNA *RNA_struct_iterator_property(StructRNA *type)
00548 {
00549     return type->iteratorproperty;
00550 }
00551 
00552 StructRNA *RNA_struct_base(StructRNA *type)
00553 {
00554     return type->base;
00555 }
00556 
00557 int RNA_struct_is_ID(StructRNA *type)
00558 {
00559     return (type->flag & STRUCT_ID) != 0;
00560 }
00561 
00562 int RNA_struct_undo_check(StructRNA *type)
00563 {
00564     return (type->flag & STRUCT_UNDO) != 0;
00565 }
00566 
00567 int RNA_struct_idprops_register_check(StructRNA *type)
00568 {
00569     return (type->flag & STRUCT_NO_IDPROPERTIES) == 0;
00570 }
00571 
00572 /* remove an id-property */
00573 int RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier)
00574 {
00575     IDProperty *group= RNA_struct_idprops(ptr, 0);
00576 
00577     if(group) {
00578         IDProperty *idp= IDP_GetPropertyFromGroup(group, identifier);
00579         if(idp) {
00580             IDP_RemFromGroup(group, idp);
00581             IDP_FreeProperty(idp);
00582             MEM_freeN(idp);
00583 
00584             return 1;
00585         }
00586     }
00587     return 0;
00588 }
00589 
00590 int RNA_struct_is_a(StructRNA *type, StructRNA *srna)
00591 {
00592     StructRNA *base;
00593 
00594     if(!type)
00595         return 0;
00596 
00597     /* ptr->type is always maximally refined */
00598     for(base=type; base; base=base->base)
00599         if(base == srna)
00600             return 1;
00601     
00602     return 0;
00603 }
00604 
00605 PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
00606 {
00607     if(identifier[0]=='[' && identifier[1]=='"') { // "  (dummy comment to avoid confusing some function lists in text editors)
00608         /* id prop lookup, not so common */
00609         PropertyRNA *r_prop= NULL;
00610         PointerRNA r_ptr; /* only support single level props */
00611         if(RNA_path_resolve(ptr, identifier, &r_ptr, &r_prop) && r_ptr.type==ptr->type && r_ptr.data==ptr->data)
00612             return r_prop;
00613     }
00614     else {
00615         /* most common case */
00616         PropertyRNA *iterprop= RNA_struct_iterator_property(ptr->type);
00617         PointerRNA propptr;
00618 
00619         if(RNA_property_collection_lookup_string(ptr, iterprop, identifier, &propptr))
00620             return propptr.data;
00621     }
00622     
00623     return NULL;
00624 }
00625 
00626 /* Find the property which uses the given nested struct */
00627 PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
00628 {
00629     PropertyRNA *prop= NULL;
00630 
00631     RNA_STRUCT_BEGIN(ptr, iprop) {
00632         /* This assumes that there can only be one user of this nested struct */
00633         if (RNA_property_pointer_type(ptr, iprop) == srna) {
00634             prop= iprop;
00635             break;
00636         }
00637     }
00638     RNA_PROP_END;
00639 
00640     return prop;
00641 }
00642 
00643 int RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test)
00644 {
00645     /* note, prop_test could be freed memory, only use for comparison */
00646 
00647     /* validate the RNA is ok */
00648     PropertyRNA *iterprop;
00649     int found= FALSE;
00650 
00651     iterprop= RNA_struct_iterator_property(ptr->type);
00652 
00653     RNA_PROP_BEGIN(ptr, itemptr, iterprop) {
00654         /* PropertyRNA *prop= itemptr.data; */
00655         if(prop_test == (PropertyRNA *)itemptr.data) {
00656             found= TRUE;
00657             break;
00658         }
00659     }
00660     RNA_PROP_END;
00661 
00662     return found;
00663 }
00664 
00665 /* low level direct access to type->properties, note this ignores parent classes so should be used with care */
00666 const struct ListBase *RNA_struct_type_properties(StructRNA *srna)
00667 {
00668     return &srna->cont.properties;
00669 }
00670 
00671 PropertyRNA *RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
00672 {
00673     return BLI_findstring_ptr(&srna->cont.properties, identifier, offsetof(PropertyRNA, identifier));
00674 }
00675 
00676 FunctionRNA *RNA_struct_find_function(PointerRNA *ptr, const char *identifier)
00677 {
00678 #if 1
00679     FunctionRNA *func;
00680     StructRNA *type;
00681     for(type= ptr->type; type; type= type->base) {
00682         func= (FunctionRNA *)BLI_findstring_ptr(&type->functions, identifier, offsetof(FunctionRNA, identifier));
00683         if(func) {
00684             return func;
00685         }
00686     }
00687     return NULL;
00688 
00689     /* funcitonal but slow */
00690 #else
00691     PointerRNA tptr;
00692     PropertyRNA *iterprop;
00693     FunctionRNA *func;
00694 
00695     RNA_pointer_create(NULL, &RNA_Struct, ptr->type, &tptr);
00696     iterprop= RNA_struct_find_property(&tptr, "functions");
00697 
00698     func= NULL;
00699 
00700     RNA_PROP_BEGIN(&tptr, funcptr, iterprop) {
00701         if(strcmp(identifier, RNA_function_identifier(funcptr.data)) == 0) {
00702             func= funcptr.data;
00703             break;
00704         }
00705     }
00706     RNA_PROP_END;
00707 
00708     return func;
00709 #endif
00710 }
00711 
00712 const struct ListBase *RNA_struct_type_functions(StructRNA *srna)
00713 {
00714     return &srna->functions;
00715 }
00716 
00717 StructRegisterFunc RNA_struct_register(StructRNA *type)
00718 {
00719     return type->reg;
00720 }
00721 
00722 StructUnregisterFunc RNA_struct_unregister(StructRNA *type)
00723 {
00724     do {
00725         if(type->unreg)
00726             return type->unreg;
00727     } while((type=type->base));
00728 
00729     return NULL;
00730 }
00731 
00732 void **RNA_struct_instance(PointerRNA *ptr)
00733 {
00734     StructRNA *type= ptr->type;
00735 
00736     do {
00737         if(type->instance)
00738             return type->instance(ptr);
00739     } while((type=type->base));
00740 
00741     return NULL;
00742 }
00743 
00744 void *RNA_struct_py_type_get(StructRNA *srna)
00745 {
00746     return srna->py_type;
00747 }
00748 
00749 void RNA_struct_py_type_set(StructRNA *srna, void *py_type)
00750 {
00751     srna->py_type= py_type;
00752 }
00753 
00754 void *RNA_struct_blender_type_get(StructRNA *srna)
00755 {
00756     return srna->blender_type;
00757 }
00758 
00759 void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
00760 {
00761     srna->blender_type= blender_type;
00762 }
00763 
00764 char *RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len)
00765 {
00766     PropertyRNA *nameprop;
00767 
00768     if(ptr->data && (nameprop = RNA_struct_name_property(ptr->type)))
00769         return RNA_property_string_get_alloc(ptr, nameprop, fixedbuf, fixedlen, r_len);
00770 
00771     return NULL;
00772 }
00773 
00774 /* Property Information */
00775 
00776 const char *RNA_property_identifier(PropertyRNA *prop)
00777 {
00778     return rna_ensure_property_identifier(prop);
00779 }
00780 
00781 const char *RNA_property_description(PropertyRNA *prop)
00782 {
00783     return rna_ensure_property_description(prop);
00784 }
00785 
00786 PropertyType RNA_property_type(PropertyRNA *prop)
00787 {
00788     return rna_ensure_property(prop)->type;
00789 }
00790 
00791 PropertySubType RNA_property_subtype(PropertyRNA *prop)
00792 {
00793     return rna_ensure_property(prop)->subtype;
00794 }
00795 
00796 PropertyUnit RNA_property_unit(PropertyRNA *prop)
00797 {
00798     return RNA_SUBTYPE_UNIT(rna_ensure_property(prop)->subtype);
00799 }
00800 
00801 int RNA_property_flag(PropertyRNA *prop)
00802 {
00803     return rna_ensure_property(prop)->flag;
00804 }
00805 
00806 void *RNA_property_py_data_get(PropertyRNA *prop)
00807 {
00808     return prop->py_data;
00809 }
00810 
00811 int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
00812 {
00813     return rna_ensure_property_array_length(ptr, prop);
00814 }
00815 
00816 int RNA_property_array_check(PropertyRNA *prop)
00817 {
00818     return rna_ensure_property_array_check(prop);
00819 }
00820 
00821 /* used by BPY to make an array from the python object */
00822 int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[])
00823 {
00824     PropertyRNA *rprop= rna_ensure_property(prop);
00825 
00826     if(length)
00827             rna_ensure_property_multi_array_length(ptr, prop, length);
00828 
00829     return rprop->arraydimension;
00830 }
00831 
00832 /* Return the size of Nth dimension. */
00833 int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dim)
00834 {
00835     int len[RNA_MAX_ARRAY_DIMENSION];
00836 
00837     rna_ensure_property_multi_array_length(ptr, prop, len);
00838 
00839     return len[dim];
00840 }
00841 
00842 char RNA_property_array_item_char(PropertyRNA *prop, int index)
00843 {
00844     const char *vectoritem= "XYZW";
00845     const char *quatitem= "WXYZ";
00846     const char *coloritem= "RGBA";
00847     PropertySubType subtype= rna_ensure_property(prop)->subtype;
00848 
00849     /* get string to use for array index */
00850     if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
00851         return quatitem[index];
00852     }
00853     else if((index < 4) && ELEM8(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ, PROP_XYZ_LENGTH,
00854                                           PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION, PROP_COORDS))
00855     {
00856         return vectoritem[index];
00857     }
00858     else if ((index < 4) && ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
00859         return coloritem[index];
00860     }
00861 
00862     return '\0';
00863 }
00864 
00865 int RNA_property_array_item_index(PropertyRNA *prop, char name)
00866 {
00867     PropertySubType subtype= rna_ensure_property(prop)->subtype;
00868 
00869     /* get index based on string name/alias */
00870     /* maybe a function to find char index in string would be better than all the switches */
00871     if (ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
00872         switch (name) {
00873             case 'w':
00874                 return 0;
00875             case 'x':
00876                 return 1;
00877             case 'y':
00878                 return 2;
00879             case 'z':
00880                 return 3;
00881         }
00882     }
00883     else if(ELEM6(subtype, PROP_TRANSLATION, PROP_DIRECTION, PROP_XYZ,
00884                            PROP_EULER, PROP_VELOCITY, PROP_ACCELERATION))
00885     {
00886         switch (name) {
00887             case 'x':
00888                 return 0;
00889             case 'y':
00890                 return 1;
00891             case 'z':
00892                 return 2;
00893             case 'w':
00894                 return 3;
00895         }
00896     }
00897     else if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA)) {
00898         switch (name) {
00899             case 'r':
00900                 return 0;
00901             case 'g':
00902                 return 1;
00903             case 'b':
00904                 return 2;
00905             case 'a':
00906                 return 3;
00907         }
00908     }
00909 
00910     return -1;
00911 }
00912 
00913 
00914 void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
00915 {
00916     IntPropertyRNA *iprop= (IntPropertyRNA*)rna_ensure_property(prop);
00917 
00918     if(prop->magic != RNA_MAGIC) {
00919         /* attempt to get the local ID values */
00920         IDProperty *idp_ui= rna_idproperty_ui(prop);
00921 
00922         if(idp_ui) {
00923             IDProperty *item;
00924 
00925             item= IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_INT);
00926             *hardmin= item ? IDP_Int(item) : INT_MIN;
00927 
00928             item= IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_INT);
00929             *hardmax= item ? IDP_Int(item) : INT_MAX;
00930 
00931             return;
00932         }
00933     }
00934 
00935     if(iprop->range) {
00936         iprop->range(ptr, hardmin, hardmax);
00937     }
00938     else {
00939         *hardmin= iprop->hardmin;
00940         *hardmax= iprop->hardmax;
00941     }
00942 }
00943 
00944 void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
00945 {
00946     IntPropertyRNA *iprop= (IntPropertyRNA*)rna_ensure_property(prop);
00947     int hardmin, hardmax;
00948     
00949     if(prop->magic != RNA_MAGIC) {
00950         /* attempt to get the local ID values */
00951         IDProperty *idp_ui= rna_idproperty_ui(prop);
00952 
00953         if(idp_ui) {
00954             IDProperty *item;
00955 
00956             item= IDP_GetPropertyTypeFromGroup(idp_ui, "soft_min", IDP_INT);
00957             *softmin= item ? IDP_Int(item) : INT_MIN;
00958 
00959             item= IDP_GetPropertyTypeFromGroup(idp_ui, "soft_max", IDP_INT);
00960             *softmax= item ? IDP_Int(item) : INT_MAX;
00961 
00962             item= IDP_GetPropertyTypeFromGroup(idp_ui, "step", IDP_INT);
00963             *step= item ? IDP_Int(item) : 1;
00964 
00965             return;
00966         }
00967     }
00968 
00969     if(iprop->range) {
00970         iprop->range(ptr, &hardmin, &hardmax);
00971         *softmin= MAX2(iprop->softmin, hardmin);
00972         *softmax= MIN2(iprop->softmax, hardmax);
00973     }
00974     else {
00975         *softmin= iprop->softmin;
00976         *softmax= iprop->softmax;
00977     }
00978 
00979     *step= iprop->step;
00980 }
00981 
00982 void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
00983 {
00984     FloatPropertyRNA *fprop= (FloatPropertyRNA*)rna_ensure_property(prop);
00985 
00986     if(prop->magic != RNA_MAGIC) {
00987         /* attempt to get the local ID values */
00988         IDProperty *idp_ui= rna_idproperty_ui(prop);
00989 
00990         if(idp_ui) {
00991             IDProperty *item;
00992 
00993             item= IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_DOUBLE);
00994             *hardmin= item ? (float)IDP_Double(item) : FLT_MIN;
00995 
00996             item= IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_DOUBLE);
00997             *hardmax= item ? (float)IDP_Double(item) : FLT_MAX;
00998 
00999             return;
01000         }
01001     }
01002 
01003     if(fprop->range) {
01004         fprop->range(ptr, hardmin, hardmax);
01005     }
01006     else {
01007         *hardmin= fprop->hardmin;
01008         *hardmax= fprop->hardmax;
01009     }
01010 }
01011 
01012 void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision)
01013 {
01014     FloatPropertyRNA *fprop= (FloatPropertyRNA*)rna_ensure_property(prop);
01015     float hardmin, hardmax;
01016 
01017     if(prop->magic != RNA_MAGIC) {
01018         /* attempt to get the local ID values */
01019         IDProperty *idp_ui= rna_idproperty_ui(prop);
01020 
01021         if(idp_ui) {
01022             IDProperty *item;
01023 
01024             item= IDP_GetPropertyTypeFromGroup(idp_ui, "soft_min", IDP_DOUBLE);
01025             *softmin= item ? (float)IDP_Double(item) : FLT_MIN;
01026 
01027             item= IDP_GetPropertyTypeFromGroup(idp_ui, "soft_max", IDP_DOUBLE);
01028             *softmax= item ? (float)IDP_Double(item) : FLT_MAX;
01029 
01030             item= IDP_GetPropertyTypeFromGroup(idp_ui, "step", IDP_DOUBLE);
01031             *step= item ? (float)IDP_Double(item) : 1.0f;
01032 
01033             item= IDP_GetPropertyTypeFromGroup(idp_ui, "precision", IDP_DOUBLE);
01034             *precision= item ? (float)IDP_Double(item) : 3.0f;
01035 
01036             return;
01037         }
01038     }
01039 
01040     if(fprop->range) {
01041         fprop->range(ptr, &hardmin, &hardmax);
01042         *softmin= MAX2(fprop->softmin, hardmin);
01043         *softmax= MIN2(fprop->softmax, hardmax);
01044     }
01045     else {
01046         *softmin= fprop->softmin;
01047         *softmax= fprop->softmax;
01048     }
01049 
01050     *step= fprop->step;
01051     *precision= (float)fprop->precision;
01052 }
01053 
01054 int RNA_property_float_clamp(PointerRNA *ptr, PropertyRNA *prop, float *value)
01055 {
01056     float min, max;
01057 
01058     RNA_property_float_range(ptr, prop, &min, &max);
01059 
01060     if(*value < min) {
01061         *value= min;
01062         return -1;
01063     }
01064     else if(*value > max) {
01065         *value= max;
01066         return 1;
01067     }
01068     else {
01069         return 0;
01070     }
01071 }
01072 
01073 int RNA_property_int_clamp(PointerRNA *ptr, PropertyRNA *prop, int *value)
01074 {
01075     int min, max;
01076 
01077     RNA_property_int_range(ptr, prop, &min, &max);
01078 
01079     if(*value < min) {
01080         *value= min;
01081         return -1;
01082     }
01083     else if(*value > max) {
01084         *value= max;
01085         return 1;
01086     }
01087     else {
01088         return 0;
01089     }
01090 }
01091 
01092 /* this is the max length including \0 terminator.
01093  * '0' used when their is no maximum */
01094 int RNA_property_string_maxlength(PropertyRNA *prop)
01095 {
01096     StringPropertyRNA *sprop= (StringPropertyRNA*)rna_ensure_property(prop);
01097     return sprop->maxlength;
01098 }
01099 
01100 StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
01101 {
01102     prop= rna_ensure_property(prop);
01103 
01104     if(prop->type == PROP_POINTER) {
01105         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
01106 
01107         if(pprop->typef)
01108             return pprop->typef(ptr);
01109         else if(pprop->type)
01110             return pprop->type;
01111     }
01112     else if(prop->type == PROP_COLLECTION) {
01113         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
01114 
01115         if(cprop->item_type)
01116             return cprop->item_type;
01117     }
01118     /* ignore other types, RNA_struct_find_nested calls with unchecked props */
01119 
01120     return &RNA_UnknownType;
01121 }
01122 
01123 int RNA_property_pointer_poll(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *value)
01124 {
01125     prop= rna_ensure_property(prop);
01126 
01127     if(prop->type == PROP_POINTER) {
01128         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
01129         if(pprop->poll)
01130             return pprop->poll(ptr, *value);
01131 
01132         return 1;
01133     }
01134 
01135     printf("%s %s: is not a pointer property.\n", __func__, prop->identifier);
01136     return 0;
01137 }
01138 
01139 /* Reuse for dynamic types  */
01140 EnumPropertyItem DummyRNA_NULL_items[] = {
01141     {0, NULL, 0, NULL, NULL}
01142 };
01143 
01144 /* Reuse for dynamic types with default value */
01145 EnumPropertyItem DummyRNA_DEFAULT_items[] = {
01146     {0, "DEFAULT", 0, "Default", ""},
01147     {0, NULL, 0, NULL, NULL}
01148 };
01149 
01150 void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item, int *totitem, int *free)
01151 {
01152     EnumPropertyRNA *eprop= (EnumPropertyRNA*)rna_ensure_property(prop);
01153 
01154     *free= 0;
01155 
01156     if(eprop->itemf && (C != NULL || (prop->flag & PROP_ENUM_NO_CONTEXT))) {
01157         int tot= 0;
01158 
01159         if (prop->flag & PROP_ENUM_NO_CONTEXT)
01160             *item= eprop->itemf(NULL, ptr, prop, free);
01161         else
01162             *item= eprop->itemf(C, ptr, prop, free);
01163 
01164         if(totitem) {
01165             if(*item) {
01166                 for( ; (*item)[tot].identifier; tot++);
01167             }
01168 
01169             *totitem= tot;
01170         }
01171 
01172     }
01173     else {
01174         *item= eprop->item;
01175         if(totitem)
01176             *totitem= eprop->totitem;
01177     }
01178 }
01179 
01180 void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item, int *totitem, int *free)
01181 {
01182     RNA_property_enum_items(C, ptr, prop, item, totitem, free);
01183 
01184 #ifdef WITH_INTERNATIONAL
01185     if((U.transopts&USER_DOTRANSLATE) && (U.transopts&USER_TR_IFACE)) {
01186         int i;
01187         EnumPropertyItem *nitem;
01188 
01189         if(*free) {
01190             nitem= *item;
01191         } else {
01192             int totitem= 0;
01193 
01194             /* count */
01195             for(i=0; (*item)[i].identifier; i++)
01196                 totitem++;
01197 
01198             nitem= MEM_callocN(sizeof(EnumPropertyItem)*(totitem+1), "enum_items_gettexted");
01199 
01200             for(i=0; (*item)[i].identifier; i++)
01201                 nitem[i]= (*item)[i];
01202 
01203             *free= 1;
01204         }
01205 
01206         for(i=0; nitem[i].identifier; i++) {
01207             if( nitem[i].name ) {
01208                 if(prop->translation_context)
01209                     nitem[i].name = BLF_pgettext(prop->translation_context, nitem[i].name);
01210                 else
01211                     nitem[i].name = BLF_gettext(nitem[i].name);
01212             }
01213             if( nitem[i].description )
01214                 nitem[i].description = BLF_gettext(nitem[i].description);
01215         }
01216 
01217         *item= nitem;
01218     }
01219 #endif
01220 }
01221 
01222 
01223 int RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value)
01224 {   
01225     EnumPropertyItem *item, *item_array;
01226     int free, found;
01227 
01228     RNA_property_enum_items(C, ptr, prop, &item_array, NULL, &free);
01229 
01230     if(item_array) {
01231         for(item= item_array; item->identifier; item++) {
01232             if(item->identifier[0] && strcmp(item->identifier, identifier)==0) {
01233                 *value = item->value;
01234                 break;
01235             }
01236         }
01237 
01238         found= (item->identifier != NULL); /* could be alloc'd, assign before free */
01239 
01240         if(free) {
01241             MEM_freeN(item_array);
01242         }
01243     }
01244     else {
01245         found= 0;
01246     }
01247     return found;
01248 }
01249 
01250 int RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier)
01251 {
01252     for (; item->identifier; item++) {
01253         if(item->identifier[0] && item->value==value) {
01254             *identifier = item->identifier;
01255             return 1;
01256         }
01257     }
01258     return 0;
01259 }
01260 
01261 int RNA_enum_bitflag_identifiers(EnumPropertyItem *item, const int value, const char **identifier)
01262 {
01263     int index= 0;
01264     for (; item->identifier; item++) {
01265         if(item->identifier[0] && item->value & value) {
01266             identifier[index++] = item->identifier;
01267         }
01268     }
01269     identifier[index]= NULL;
01270     return index;
01271 }
01272 
01273 int RNA_enum_name(EnumPropertyItem *item, const int value, const char **name)
01274 {
01275     for (; item->identifier; item++) {
01276         if(item->identifier[0] && item->value==value) {
01277             *name = item->name;
01278             return 1;
01279         }
01280     }
01281     return 0;
01282 }
01283 
01284 int RNA_enum_description(EnumPropertyItem *item, const int value, const char **description)
01285 {
01286     for (; item->identifier; item++) {
01287         if(item->identifier[0] && item->value==value) {
01288             *description = item->description;
01289             return 1;
01290         }
01291     }
01292     return 0;
01293 }
01294 
01295 int RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
01296 {   
01297     EnumPropertyItem *item= NULL;
01298     int result, free;
01299     
01300     RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
01301     if(item) {
01302         result= RNA_enum_identifier(item, value, identifier);
01303         if(free)
01304             MEM_freeN(item);
01305 
01306         return result;
01307     }
01308     return 0;
01309 }
01310 
01311 int RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
01312 {   
01313     EnumPropertyItem *item= NULL;
01314     int result, free;
01315     
01316     RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
01317     if(item) {
01318         result= RNA_enum_name(item, value, name);
01319         if(free)
01320             MEM_freeN(item);
01321         
01322         return result;
01323     }
01324     return 0;
01325 }
01326 
01327 int RNA_property_enum_bitflag_identifiers(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
01328 {
01329     EnumPropertyItem *item= NULL;
01330     int result, free;
01331 
01332     RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
01333     if(item) {
01334         result= RNA_enum_bitflag_identifiers(item, value, identifier);
01335         if(free)
01336             MEM_freeN(item);
01337 
01338         return result;
01339     }
01340     return 0;
01341 }
01342 
01343 const char *RNA_property_ui_name(PropertyRNA *prop)
01344 {
01345     return rna_ensure_property_name(prop);
01346 }
01347 
01348 const char *RNA_property_ui_description(PropertyRNA *prop)
01349 {
01350     return rna_ensure_property_description(prop);
01351 }
01352 
01353 int RNA_property_ui_icon(PropertyRNA *prop)
01354 {
01355     return rna_ensure_property(prop)->icon;
01356 }
01357 
01358 int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
01359 {
01360     ID *id= ptr->id.data;
01361     int flag;
01362 
01363     prop= rna_ensure_property(prop);
01364     flag= prop->editable ? prop->editable(ptr) : prop->flag;
01365     return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
01366 }
01367 
01368 int RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop)
01369 {
01370     int flag;
01371 
01372     prop= rna_ensure_property(prop);
01373     flag= prop->editable ? prop->editable(ptr) : prop->flag;
01374     return (flag & PROP_EDITABLE);
01375 }
01376 
01377 /* same as RNA_property_editable(), except this checks individual items in an array */
01378 int RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index)
01379 {
01380     ID *id;
01381     int flag;
01382 
01383     prop= rna_ensure_property(prop);
01384 
01385     flag= prop->flag;
01386     
01387     if(prop->editable)
01388         flag &= prop->editable(ptr);
01389 
01390     if (prop->itemeditable)
01391         flag &= prop->itemeditable(ptr, index);
01392 
01393     id= ptr->id.data;
01394 
01395     return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
01396 }
01397 
01398 int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
01399 {
01400     /* check that base ID-block can support animation data */
01401     if (!id_type_can_have_animdata(ptr->id.data))
01402         return 0;
01403     
01404     prop= rna_ensure_property(prop);
01405 
01406     if(!(prop->flag & PROP_ANIMATABLE))
01407         return 0;
01408 
01409     return (prop->flag & PROP_EDITABLE);
01410 }
01411 
01412 int RNA_property_animated(PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop))
01413 {
01414     /* would need to ask animation system */
01415 
01416     return 0;
01417 }
01418 
01419 
01420 /* this function is to check if its possible to create a valid path from the ID
01421  * its slow so dont call in a loop */
01422 int RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
01423 {
01424     char *path= RNA_path_from_ID_to_property(ptr, prop);
01425     int ret= 0;
01426 
01427     if(path) {
01428         PointerRNA id_ptr;
01429         PointerRNA r_ptr;
01430         PropertyRNA *r_prop;
01431 
01432         RNA_id_pointer_create(ptr->id.data, &id_ptr);
01433         RNA_path_resolve(&id_ptr, path, &r_ptr, &r_prop);
01434         ret= (prop == r_prop);
01435         MEM_freeN(path);
01436     }
01437 
01438     return ret;
01439 }
01440 
01441 
01442 static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
01443 {
01444     int is_rna = (prop->magic == RNA_MAGIC);
01445     prop= rna_ensure_property(prop);
01446 
01447     if(is_rna) {
01448         if(prop->update) {
01449             /* ideally no context would be needed for update, but there's some
01450                parts of the code that need it still, so we have this exception */
01451             if(prop->flag & PROP_CONTEXT_UPDATE) {
01452                 if(C) {
01453                     if(prop->flag & PROP_CONTEXT_PROPERTY_UPDATE) {
01454                         ((ContextPropUpdateFunc)prop->update)(C, ptr, prop);
01455                     }
01456                     else {
01457                         ((ContextUpdateFunc)prop->update)(C, ptr);
01458                     }
01459                 }
01460             }
01461             else
01462                 prop->update(bmain, scene, ptr);
01463         }
01464         if(prop->noteflag)
01465             WM_main_add_notifier(prop->noteflag, ptr->id.data);
01466     }
01467     
01468     if(!is_rna || (prop->flag & PROP_IDPROPERTY)) {
01469         /* WARNING! This is so property drivers update the display!
01470          * not especially nice  */
01471         DAG_id_tag_update(ptr->id.data, OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME);
01472         WM_main_add_notifier(NC_WINDOW, NULL);
01473     }
01474 }
01475 
01476 /* must keep in sync with 'rna_property_update'
01477  * note, its possible this returns a false positive in the case of PROP_CONTEXT_UPDATE
01478  * but this isnt likely to be a performance problem. */
01479 int RNA_property_update_check(PropertyRNA *prop)
01480 {
01481     return (prop->magic != RNA_MAGIC || prop->update || prop->noteflag);
01482 }
01483 
01484 void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
01485 {
01486     rna_property_update(C, CTX_data_main(C), CTX_data_scene(C), ptr, prop);
01487 }
01488 
01489 void RNA_property_update_main(Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
01490 {
01491     rna_property_update(NULL, bmain, scene, ptr, prop);
01492 }
01493 
01494 
01495 /* RNA Updates Cache ------------------------ */
01496 /* Overview of RNA Update cache system:
01497  *
01498  * RNA Update calls need to be cached in order to maintain reasonable performance
01499  * of the animation system (i.e. maintaining a somewhat interactive framerate)
01500  * while still allowing updates to be called (necessary in particular for modifier
01501  * property updates to actually work).
01502  *
01503  * The cache is structured with a dual-layer structure
01504  * - L1 = PointerRNA used as key; id.data is used (it should always be defined,
01505  *       and most updates end up using just that anyways)
01506  * - L2 = Update functions to be called on those PointerRNA's
01507  */
01508 
01509 /* cache element */
01510 typedef struct tRnaUpdateCacheElem {
01511     struct tRnaUpdateCacheElem *next, *prev;
01512     
01513     PointerRNA ptr;     /* L1 key - id as primary, data secondary/ignored? */
01514     ListBase L2Funcs;   /* L2 functions (LinkData<RnaUpdateFuncRef>) */
01515 } tRnaUpdateCacheElem;
01516 
01517 /* cache global (tRnaUpdateCacheElem's) - only accessible using these API calls */
01518 static ListBase rna_updates_cache = {NULL, NULL};
01519 
01520 /* ........................... */
01521 
01522 void RNA_property_update_cache_add(PointerRNA *ptr, PropertyRNA *prop)
01523 {
01524     tRnaUpdateCacheElem *uce = NULL;
01525     UpdateFunc fn = NULL;
01526     LinkData *ld;
01527     short is_rna = (prop->magic == RNA_MAGIC);
01528     
01529     /* sanity check */
01530     if (ELEM(NULL, ptr, prop))
01531         return;
01532         
01533     prop= rna_ensure_property(prop);
01534     
01535     /* we can only handle update calls with no context args for now (makes animsys updates easier) */
01536     if ((is_rna == 0) || (prop->update == NULL) || (prop->flag & PROP_CONTEXT_UPDATE))
01537         return;
01538     fn = prop->update;
01539         
01540     /* find cache element for which key matches... */
01541     for (uce = rna_updates_cache.first; uce; uce = uce->next) {
01542         /* just match by id only for now, since most update calls that we'll encounter only really care about this */
01543         /* TODO: later, the cache might need to have some nesting on L1 to cope better
01544          * with these problems + some tagging to indicate we need this */
01545         if (uce->ptr.id.data == ptr->id.data)
01546             break;
01547     }
01548     if (uce == NULL) {
01549         /* create new instance */
01550         uce = MEM_callocN(sizeof(tRnaUpdateCacheElem), "tRnaUpdateCacheElem");
01551         BLI_addtail(&rna_updates_cache, uce);
01552         
01553         /* copy pointer */
01554         RNA_pointer_create(ptr->id.data, ptr->type, ptr->data, &uce->ptr);
01555     }
01556     
01557     /* check on the update func */
01558     for (ld = uce->L2Funcs.first; ld; ld = ld->next) {
01559         /* stop on match - function already cached */
01560         if (fn == ld->data)
01561             return;
01562     }
01563     /* else... if still here, we need to add it */
01564     BLI_addtail(&uce->L2Funcs, BLI_genericNodeN(fn));
01565 }
01566 
01567 void RNA_property_update_cache_flush(Main *bmain, Scene *scene)
01568 {
01569     tRnaUpdateCacheElem *uce;
01570     
01571     // TODO: should we check that bmain and scene are valid? The above stuff doesn't!
01572     
01573     /* execute the cached updates */
01574     for (uce = rna_updates_cache.first; uce; uce = uce->next) {
01575         LinkData *ld;
01576         
01577         for (ld = uce->L2Funcs.first; ld; ld = ld->next) {
01578             UpdateFunc fn = (UpdateFunc)ld->data;
01579             fn(bmain, scene, &uce->ptr);
01580         }
01581     }
01582 }
01583 
01584 void RNA_property_update_cache_free(void)
01585 {
01586     tRnaUpdateCacheElem *uce, *ucn;
01587     
01588     for (uce = rna_updates_cache.first; uce; uce = ucn) {
01589         ucn = uce->next;
01590         
01591         /* free L2 cache */
01592         BLI_freelistN(&uce->L2Funcs);
01593         
01594         /* remove self */
01595         BLI_freelinkN(&rna_updates_cache, uce);
01596     }
01597 }
01598 
01599 /* ---------------------------------------------------------------------- */
01600 
01601 /* Property Data */
01602 
01603 int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
01604 {
01605     BoolPropertyRNA *bprop= (BoolPropertyRNA*)prop;
01606     IDProperty *idprop;
01607 
01608     BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
01609     BLI_assert(RNA_property_array_check(prop) == 0);
01610 
01611     if((idprop=rna_idproperty_check(&prop, ptr)))
01612         return IDP_Int(idprop);
01613     else if(bprop->get)
01614         return bprop->get(ptr);
01615     else
01616         return bprop->defaultvalue;
01617 }
01618 
01619 void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
01620 {
01621     BoolPropertyRNA *bprop= (BoolPropertyRNA*)prop;
01622     IDProperty *idprop;
01623 
01624     BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
01625     BLI_assert(RNA_property_array_check(prop) == 0);
01626 
01627     /* just incase other values are passed */
01628     if(value) value= 1;
01629 
01630     if((idprop=rna_idproperty_check(&prop, ptr))) {
01631         IDP_Int(idprop)= value;
01632         rna_idproperty_touch(idprop);
01633     }
01634     else if(bprop->set)
01635         bprop->set(ptr, value);
01636     else if(prop->flag & PROP_EDITABLE) {
01637         IDPropertyTemplate val = {0};
01638         IDProperty *group;
01639 
01640         val.i= value;
01641 
01642         group= RNA_struct_idprops(ptr, 1);
01643         if(group)
01644             IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
01645     }
01646 }
01647 
01648 void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
01649 {
01650     BoolPropertyRNA *bprop= (BoolPropertyRNA*)prop;
01651     IDProperty *idprop;
01652 
01653     BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
01654     BLI_assert(RNA_property_array_check(prop) != 0);
01655 
01656     if((idprop=rna_idproperty_check(&prop, ptr))) {
01657         if(prop->arraydimension == 0)
01658             values[0]= RNA_property_boolean_get(ptr, prop);
01659         else
01660             memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
01661     }
01662     else if(prop->arraydimension == 0)
01663         values[0]= RNA_property_boolean_get(ptr, prop);
01664     else if(bprop->getarray)
01665         bprop->getarray(ptr, values);
01666     else if(bprop->defaultarray)
01667         memcpy(values, bprop->defaultarray, sizeof(int)*prop->totarraylength);
01668     else
01669         memset(values, 0, sizeof(int)*prop->totarraylength);
01670 }
01671 
01672 int RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
01673 {
01674     int tmp[RNA_MAX_ARRAY_LENGTH];
01675     int len= rna_ensure_property_array_length(ptr, prop);
01676 
01677     BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
01678     BLI_assert(RNA_property_array_check(prop) != 0);
01679 
01680     if(len <= RNA_MAX_ARRAY_LENGTH) {
01681         RNA_property_boolean_get_array(ptr, prop, tmp);
01682         return tmp[index];
01683     }
01684     else {
01685         int *tmparray, value;
01686 
01687         tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_index");
01688         RNA_property_boolean_get_array(ptr, prop, tmparray);
01689         value= tmparray[index];
01690         MEM_freeN(tmparray);
01691 
01692         return value;
01693     }
01694 }
01695 
01696 void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
01697 {
01698     BoolPropertyRNA *bprop= (BoolPropertyRNA*)prop;
01699     IDProperty *idprop;
01700 
01701     BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
01702     BLI_assert(RNA_property_array_check(prop) != 0);
01703 
01704     if((idprop=rna_idproperty_check(&prop, ptr))) {
01705         if(prop->arraydimension == 0)
01706             IDP_Int(idprop)= values[0];
01707         else
01708             memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
01709 
01710         rna_idproperty_touch(idprop);
01711     }
01712     else if(prop->arraydimension == 0)
01713         RNA_property_boolean_set(ptr, prop, values[0]);
01714     else if(bprop->setarray)
01715         bprop->setarray(ptr, values);
01716     else if(prop->flag & PROP_EDITABLE) {
01717         IDPropertyTemplate val = {0};
01718         IDProperty *group;
01719 
01720         val.array.len= prop->totarraylength;
01721         val.array.type= IDP_INT;
01722 
01723         group= RNA_struct_idprops(ptr, 1);
01724         if(group) {
01725             idprop= IDP_New(IDP_ARRAY, &val, prop->identifier);
01726             IDP_AddToGroup(group, idprop);
01727             memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
01728         }
01729     }
01730 }
01731 
01732 void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
01733 {
01734     int tmp[RNA_MAX_ARRAY_LENGTH];
01735     int len= rna_ensure_property_array_length(ptr, prop);
01736 
01737     BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
01738     BLI_assert(RNA_property_array_check(prop) != 0);
01739 
01740     if(len <= RNA_MAX_ARRAY_LENGTH) {
01741         RNA_property_boolean_get_array(ptr, prop, tmp);
01742         tmp[index]= value;
01743         RNA_property_boolean_set_array(ptr, prop, tmp);
01744     }
01745     else {
01746         int *tmparray;
01747 
01748         tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_index");
01749         RNA_property_boolean_get_array(ptr, prop, tmparray);
01750         tmparray[index]= value;
01751         RNA_property_boolean_set_array(ptr, prop, tmparray);
01752         MEM_freeN(tmparray);
01753     }
01754 }
01755 
01756 int RNA_property_boolean_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
01757 {
01758     BoolPropertyRNA *bprop= (BoolPropertyRNA*)prop;
01759 
01760     BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
01761     BLI_assert(RNA_property_array_check(prop) == 0);
01762 
01763     return bprop->defaultvalue;
01764 }
01765 
01766 void RNA_property_boolean_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int *values)
01767 {
01768     BoolPropertyRNA *bprop= (BoolPropertyRNA*)prop;
01769     
01770     BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
01771     BLI_assert(RNA_property_array_check(prop) != 0);
01772 
01773     if(prop->arraydimension == 0)
01774         values[0]= bprop->defaultvalue;
01775     else if(bprop->defaultarray)
01776         memcpy(values, bprop->defaultarray, sizeof(int)*prop->totarraylength);
01777     else
01778         memset(values, 0, sizeof(int)*prop->totarraylength);
01779 }
01780 
01781 int RNA_property_boolean_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
01782 {
01783     int tmp[RNA_MAX_ARRAY_LENGTH];
01784     int len= rna_ensure_property_array_length(ptr, prop);
01785 
01786     BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
01787     BLI_assert(RNA_property_array_check(prop) != 0);
01788 
01789     if(len <= RNA_MAX_ARRAY_LENGTH) {
01790         RNA_property_boolean_get_default_array(ptr, prop, tmp);
01791         return tmp[index];
01792     }
01793     else {
01794         int *tmparray, value;
01795 
01796         tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_boolean_get_default_index");
01797         RNA_property_boolean_get_default_array(ptr, prop, tmparray);
01798         value= tmparray[index];
01799         MEM_freeN(tmparray);
01800 
01801         return value;
01802     }
01803 }
01804 
01805 int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
01806 {
01807     IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
01808     IDProperty *idprop;
01809 
01810     BLI_assert(RNA_property_type(prop) == PROP_INT);
01811     BLI_assert(RNA_property_array_check(prop) == 0);
01812 
01813     if((idprop=rna_idproperty_check(&prop, ptr)))
01814         return IDP_Int(idprop);
01815     else if(iprop->get)
01816         return iprop->get(ptr);
01817     else
01818         return iprop->defaultvalue;
01819 }
01820 
01821 void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
01822 {
01823     IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
01824     IDProperty *idprop;
01825 
01826     BLI_assert(RNA_property_type(prop) == PROP_INT);
01827     BLI_assert(RNA_property_array_check(prop) == 0);
01828     /* useful to check on bad values but set function should clamp */
01829     /* BLI_assert(RNA_property_int_clamp(ptr, prop, &value) == 0); */
01830 
01831     if((idprop=rna_idproperty_check(&prop, ptr))) {
01832         IDP_Int(idprop)= value;
01833         rna_idproperty_touch(idprop);
01834     }
01835     else if(iprop->set)
01836         iprop->set(ptr, value);
01837     else if(prop->flag & PROP_EDITABLE) {
01838         IDPropertyTemplate val = {0};
01839         IDProperty *group;
01840 
01841         val.i= value;
01842 
01843         group= RNA_struct_idprops(ptr, 1);
01844         if(group)
01845             IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
01846     }
01847 }
01848 
01849 void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
01850 {
01851     IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
01852     IDProperty *idprop;
01853 
01854     BLI_assert(RNA_property_type(prop) == PROP_INT);
01855     BLI_assert(RNA_property_array_check(prop) != 0);
01856 
01857     if((idprop=rna_idproperty_check(&prop, ptr))) {
01858         if(prop->arraydimension == 0)
01859             values[0]= RNA_property_int_get(ptr, prop);
01860         else
01861             memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
01862     }
01863     else if(prop->arraydimension == 0)
01864         values[0]= RNA_property_int_get(ptr, prop);
01865     else if(iprop->getarray)
01866         iprop->getarray(ptr, values);
01867     else if(iprop->defaultarray)
01868         memcpy(values, iprop->defaultarray, sizeof(int)*prop->totarraylength);
01869     else
01870         memset(values, 0, sizeof(int)*prop->totarraylength);
01871 }
01872 
01873 void RNA_property_int_get_array_range(PointerRNA *ptr, PropertyRNA *prop, int values[2])
01874 {
01875     const int array_len= RNA_property_array_length(ptr, prop);
01876 
01877     if(array_len <= 0) {
01878         values[0]= 0;
01879         values[1]= 0;
01880     }
01881     else if (array_len == 1) {
01882         RNA_property_int_get_array(ptr, prop, values);
01883         values[1]= values[0];
01884     }
01885     else {
01886         int arr_stack[32];
01887         int *arr;
01888         int i;
01889 
01890         if(array_len > 32) {
01891             arr= MEM_mallocN(sizeof(int) * array_len, "RNA_property_int_get_array_range");
01892         }
01893         else {
01894             arr= arr_stack;
01895         }
01896 
01897         RNA_property_int_get_array(ptr, prop, arr);
01898         values[0]= values[1]= arr[0];
01899         for(i= 1; i < array_len; i++) {
01900             values[0]= MIN2(values[0], arr[i]);
01901             values[1]= MAX2(values[1], arr[i]);
01902         }
01903 
01904         if(arr != arr_stack) {
01905             MEM_freeN(arr);
01906         }
01907     }
01908 }
01909 
01910 int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
01911 {
01912     int tmp[RNA_MAX_ARRAY_LENGTH];
01913     int len= rna_ensure_property_array_length(ptr, prop);
01914 
01915     BLI_assert(RNA_property_type(prop) == PROP_INT);
01916     BLI_assert(RNA_property_array_check(prop) != 0);
01917 
01918     if(len <= RNA_MAX_ARRAY_LENGTH) {
01919         RNA_property_int_get_array(ptr, prop, tmp);
01920         return tmp[index];
01921     }
01922     else {
01923         int *tmparray, value;
01924 
01925         tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_index");
01926         RNA_property_int_get_array(ptr, prop, tmparray);
01927         value= tmparray[index];
01928         MEM_freeN(tmparray);
01929 
01930         return value;
01931     }
01932 }
01933 
01934 void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *values)
01935 {
01936     IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
01937     IDProperty *idprop;
01938 
01939     BLI_assert(RNA_property_type(prop) == PROP_INT);
01940     BLI_assert(RNA_property_array_check(prop) != 0);
01941 
01942     if((idprop=rna_idproperty_check(&prop, ptr))) {
01943         if(prop->arraydimension == 0)
01944             IDP_Int(idprop)= values[0];
01945         else
01946             memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
01947 
01948         rna_idproperty_touch(idprop);
01949     }
01950     else if(prop->arraydimension == 0)
01951         RNA_property_int_set(ptr, prop, values[0]);
01952     else if(iprop->setarray)
01953         iprop->setarray(ptr, values);
01954     else if(prop->flag & PROP_EDITABLE) {
01955         IDPropertyTemplate val = {0};
01956         IDProperty *group;
01957 
01958         val.array.len= prop->totarraylength;
01959         val.array.type= IDP_INT;
01960 
01961         group= RNA_struct_idprops(ptr, 1);
01962         if(group) {
01963             idprop= IDP_New(IDP_ARRAY, &val, prop->identifier);
01964             IDP_AddToGroup(group, idprop);
01965             memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
01966         }
01967     }
01968 }
01969 
01970 void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
01971 {
01972     int tmp[RNA_MAX_ARRAY_LENGTH];
01973     int len= rna_ensure_property_array_length(ptr, prop);
01974 
01975     BLI_assert(RNA_property_type(prop) == PROP_INT);
01976     BLI_assert(RNA_property_array_check(prop) != 0);
01977 
01978     if(len <= RNA_MAX_ARRAY_LENGTH) {
01979         RNA_property_int_get_array(ptr, prop, tmp);
01980         tmp[index]= value;
01981         RNA_property_int_set_array(ptr, prop, tmp);
01982     }
01983     else {
01984         int *tmparray;
01985 
01986         tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_index");
01987         RNA_property_int_get_array(ptr, prop, tmparray);
01988         tmparray[index]= value;
01989         RNA_property_int_set_array(ptr, prop, tmparray);
01990         MEM_freeN(tmparray);
01991     }
01992 }
01993 
01994 int RNA_property_int_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
01995 {
01996     IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
01997     return iprop->defaultvalue;
01998 }
01999 
02000 void RNA_property_int_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, int *values)
02001 {
02002     IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
02003     
02004     BLI_assert(RNA_property_type(prop) == PROP_INT);
02005     BLI_assert(RNA_property_array_check(prop) != 0);
02006 
02007     if(prop->arraydimension == 0)
02008         values[0]= iprop->defaultvalue;
02009     else if(iprop->defaultarray)
02010         memcpy(values, iprop->defaultarray, sizeof(int)*prop->totarraylength);
02011     else
02012         memset(values, 0, sizeof(int)*prop->totarraylength);
02013 }
02014 
02015 int RNA_property_int_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
02016 {
02017     int tmp[RNA_MAX_ARRAY_LENGTH];
02018     int len= rna_ensure_property_array_length(ptr, prop);
02019 
02020     if(len <= RNA_MAX_ARRAY_LENGTH) {
02021         RNA_property_int_get_default_array(ptr, prop, tmp);
02022         return tmp[index];
02023     }
02024     else {
02025         int *tmparray, value;
02026 
02027         tmparray= MEM_callocN(sizeof(int)*len, "RNA_property_int_get_default_index");
02028         RNA_property_int_get_default_array(ptr, prop, tmparray);
02029         value= tmparray[index];
02030         MEM_freeN(tmparray);
02031 
02032         return value;
02033     }
02034 }
02035 
02036 float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
02037 {
02038     FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
02039     IDProperty *idprop;
02040 
02041     BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
02042     BLI_assert(RNA_property_array_check(prop) == 0);
02043 
02044     if((idprop=rna_idproperty_check(&prop, ptr))) {
02045         if(idprop->type == IDP_FLOAT)
02046             return IDP_Float(idprop);
02047         else
02048             return (float)IDP_Double(idprop);
02049     }
02050     else if(fprop->get)
02051         return fprop->get(ptr);
02052     else
02053         return fprop->defaultvalue;
02054 }
02055 
02056 void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
02057 {
02058     FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
02059     IDProperty *idprop;
02060 
02061     BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
02062     BLI_assert(RNA_property_array_check(prop) == 0);
02063     /* useful to check on bad values but set function should clamp */
02064     /* BLI_assert(RNA_property_float_clamp(ptr, prop, &value) == 0); */
02065 
02066     if((idprop=rna_idproperty_check(&prop, ptr))) {
02067         if(idprop->type == IDP_FLOAT)
02068             IDP_Float(idprop)= value;
02069         else
02070             IDP_Double(idprop)= value;
02071 
02072         rna_idproperty_touch(idprop);
02073     }
02074     else if(fprop->set) {
02075         fprop->set(ptr, value);
02076     }
02077     else if(prop->flag & PROP_EDITABLE) {
02078         IDPropertyTemplate val = {0};
02079         IDProperty *group;
02080 
02081         val.f= value;
02082 
02083         group= RNA_struct_idprops(ptr, 1);
02084         if(group)
02085             IDP_AddToGroup(group, IDP_New(IDP_FLOAT, &val, prop->identifier));
02086     }
02087 }
02088 
02089 void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
02090 {
02091     FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
02092     IDProperty *idprop;
02093     int i;
02094 
02095     BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
02096     BLI_assert(RNA_property_array_check(prop) != 0);
02097 
02098     if((idprop=rna_idproperty_check(&prop, ptr))) {
02099         if(prop->arraydimension == 0)
02100             values[0]= RNA_property_float_get(ptr, prop);
02101         else if(idprop->subtype == IDP_FLOAT) {
02102             memcpy(values, IDP_Array(idprop), sizeof(float)*idprop->len);
02103         }
02104         else {
02105             for(i=0; i<idprop->len; i++)
02106                 values[i]=  (float)(((double*)IDP_Array(idprop))[i]);
02107         }
02108     }
02109     else if(prop->arraydimension == 0)
02110         values[0]= RNA_property_float_get(ptr, prop);
02111     else if(fprop->getarray)
02112         fprop->getarray(ptr, values);
02113     else if(fprop->defaultarray)
02114         memcpy(values, fprop->defaultarray, sizeof(float)*prop->totarraylength);
02115     else
02116         memset(values, 0, sizeof(float)*prop->totarraylength);
02117 }
02118 
02119 void RNA_property_float_get_array_range(PointerRNA *ptr, PropertyRNA *prop, float values[2])
02120 {
02121     const int array_len= RNA_property_array_length(ptr, prop);
02122 
02123     if(array_len <= 0) {
02124         values[0]= 0.0f;
02125         values[1]= 0.0f;
02126     }
02127     else if (array_len == 1) {
02128         RNA_property_float_get_array(ptr, prop, values);
02129         values[1]= values[0];
02130     }
02131     else {
02132         float arr_stack[32];
02133         float *arr;
02134         int i;
02135 
02136         if(array_len > 32) {
02137             arr= MEM_mallocN(sizeof(float) * array_len, "RNA_property_float_get_array_range");
02138         }
02139         else {
02140             arr= arr_stack;
02141         }
02142 
02143         RNA_property_float_get_array(ptr, prop, arr);
02144         values[0]= values[1]= arr[0];
02145         for(i= 1; i < array_len; i++) {
02146             values[0]= MIN2(values[0], arr[i]);
02147             values[1]= MAX2(values[1], arr[i]);
02148         }
02149 
02150         if(arr != arr_stack) {
02151             MEM_freeN(arr);
02152         }
02153     }
02154 }
02155 
02156 float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
02157 {
02158     float tmp[RNA_MAX_ARRAY_LENGTH];
02159     int len= rna_ensure_property_array_length(ptr, prop);
02160 
02161     BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
02162     BLI_assert(RNA_property_array_check(prop) != 0);
02163 
02164     if(len <= RNA_MAX_ARRAY_LENGTH) {
02165         RNA_property_float_get_array(ptr, prop, tmp);
02166         return tmp[index];
02167     }
02168     else {
02169         float *tmparray, value;
02170 
02171         tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_index");
02172         RNA_property_float_get_array(ptr, prop, tmparray);
02173         value= tmparray[index];
02174         MEM_freeN(tmparray);
02175 
02176         return value;
02177     }
02178 
02179 }
02180 
02181 void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
02182 {
02183     FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
02184     IDProperty *idprop;
02185     int i;
02186 
02187     BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
02188     BLI_assert(RNA_property_array_check(prop) != 0);
02189 
02190     if((idprop=rna_idproperty_check(&prop, ptr))) {
02191         if(prop->arraydimension == 0) {
02192             if(idprop->type == IDP_FLOAT)
02193                 IDP_Float(idprop)= values[0];
02194             else
02195                 IDP_Double(idprop)= values[0];
02196         }
02197         else if(idprop->subtype == IDP_FLOAT) {
02198             memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len);
02199         }
02200         else {
02201             for(i=0; i<idprop->len; i++)
02202                 ((double*)IDP_Array(idprop))[i]= values[i];
02203         }
02204 
02205         rna_idproperty_touch(idprop);
02206     }
02207     else if(prop->arraydimension == 0)
02208         RNA_property_float_set(ptr, prop, values[0]);
02209     else if(fprop->setarray) {
02210         fprop->setarray(ptr, values);
02211     }
02212     else if(prop->flag & PROP_EDITABLE) {
02213         IDPropertyTemplate val = {0};
02214         IDProperty *group;
02215 
02216         val.array.len= prop->totarraylength;
02217         val.array.type= IDP_FLOAT;
02218 
02219         group= RNA_struct_idprops(ptr, 1);
02220         if(group) {
02221             idprop= IDP_New(IDP_ARRAY, &val, prop->identifier);
02222             IDP_AddToGroup(group, idprop);
02223             memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len);
02224         }
02225     }
02226 }
02227 
02228 void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
02229 {
02230     float tmp[RNA_MAX_ARRAY_LENGTH];
02231     int len= rna_ensure_property_array_length(ptr, prop);
02232 
02233     BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
02234     BLI_assert(RNA_property_array_check(prop) != 0);
02235 
02236     if(len <= RNA_MAX_ARRAY_LENGTH) {
02237         RNA_property_float_get_array(ptr, prop, tmp);
02238         tmp[index]= value;
02239         RNA_property_float_set_array(ptr, prop, tmp);
02240     }
02241     else {
02242         float *tmparray;
02243 
02244         tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_index");
02245         RNA_property_float_get_array(ptr, prop, tmparray);
02246         tmparray[index]= value;
02247         RNA_property_float_set_array(ptr, prop, tmparray);
02248         MEM_freeN(tmparray);
02249     }
02250 }
02251 
02252 float RNA_property_float_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
02253 {
02254     FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
02255 
02256     BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
02257     BLI_assert(RNA_property_array_check(prop) == 0);
02258 
02259     return fprop->defaultvalue;
02260 }
02261 
02262 void RNA_property_float_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *prop, float *values)
02263 {
02264     FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
02265     
02266     BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
02267     BLI_assert(RNA_property_array_check(prop) != 0);
02268 
02269     if(prop->arraydimension == 0)
02270         values[0]= fprop->defaultvalue;
02271     else if(fprop->defaultarray)
02272         memcpy(values, fprop->defaultarray, sizeof(float)*prop->totarraylength);
02273     else
02274         memset(values, 0, sizeof(float)*prop->totarraylength);
02275 }
02276 
02277 float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int index)
02278 {
02279     float tmp[RNA_MAX_ARRAY_LENGTH];
02280     int len= rna_ensure_property_array_length(ptr, prop);
02281 
02282     BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
02283     BLI_assert(RNA_property_array_check(prop) != 0);
02284 
02285     if(len <= RNA_MAX_ARRAY_LENGTH) {
02286         RNA_property_float_get_default_array(ptr, prop, tmp);
02287         return tmp[index];
02288     }
02289     else {
02290         float *tmparray, value;
02291 
02292         tmparray= MEM_callocN(sizeof(float)*len, "RNA_property_float_get_default_index");
02293         RNA_property_float_get_default_array(ptr, prop, tmparray);
02294         value= tmparray[index];
02295         MEM_freeN(tmparray);
02296 
02297         return value;
02298     }
02299 }
02300 
02301 void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
02302 {
02303     StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
02304     IDProperty *idprop;
02305 
02306     BLI_assert(RNA_property_type(prop) == PROP_STRING);
02307 
02308     if((idprop=rna_idproperty_check(&prop, ptr))) {
02309         /* editing bytes is not 100% supported
02310          * since they can contain NIL chars */
02311         if (idprop->subtype == IDP_STRING_SUB_BYTE) {
02312             memcpy(value, IDP_String(idprop), idprop->len);
02313             value[idprop->len]= '\0';
02314         }
02315         else {
02316             memcpy(value, IDP_String(idprop), idprop->len);
02317         }
02318     }
02319     else if(sprop->get) {
02320         sprop->get(ptr, value);
02321     }
02322     else {
02323         strcpy(value, sprop->defaultvalue);
02324     }
02325 }
02326 
02327 char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop,
02328                                     char *fixedbuf, int fixedlen, int *r_len)
02329 {
02330     char *buf;
02331     int length;
02332 
02333     BLI_assert(RNA_property_type(prop) == PROP_STRING);
02334 
02335     length= RNA_property_string_length(ptr, prop);
02336 
02337     if(length+1 < fixedlen)
02338         buf= fixedbuf;
02339     else
02340         buf= MEM_mallocN(sizeof(char)*(length+1), "RNA_string_get_alloc");
02341 
02342 #ifndef NDEBUG
02343     /* safety check to ensure the string is actually set */
02344     buf[length]= 255;
02345 #endif
02346 
02347     RNA_property_string_get(ptr, prop, buf);
02348 
02349 #ifndef NDEBUG
02350     BLI_assert(buf[length] == '\0');
02351 #endif
02352 
02353     if (r_len) {
02354         *r_len= length;
02355     }
02356 
02357     return buf;
02358 }
02359 
02360 /* this is the length without \0 terminator */
02361 int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
02362 {
02363     StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
02364     IDProperty *idprop;
02365 
02366     BLI_assert(RNA_property_type(prop) == PROP_STRING);
02367 
02368     if((idprop=rna_idproperty_check(&prop, ptr))) {
02369         if (idprop->subtype == IDP_STRING_SUB_BYTE) {
02370             return idprop->len;
02371         }
02372         else {
02373 #ifndef NDEBUG
02374             /* these _must_ stay in sync */
02375             BLI_assert(strlen(IDP_String(idprop)) == idprop->len - 1);
02376 #endif
02377             return idprop->len - 1;
02378         }
02379     }
02380     else if(sprop->length)
02381         return sprop->length(ptr);
02382     else
02383         return strlen(sprop->defaultvalue);
02384 }
02385 
02386 void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
02387 {
02388     StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
02389     IDProperty *idprop;
02390 
02391     BLI_assert(RNA_property_type(prop) == PROP_STRING);
02392 
02393     if((idprop=rna_idproperty_check(&prop, ptr))) {
02394         /* both IDP_STRING_SUB_BYTE / IDP_STRING_SUB_UTF8 */
02395         IDP_AssignString(idprop, value, RNA_property_string_maxlength(prop) - 1);
02396         rna_idproperty_touch(idprop);
02397     }
02398     else if(sprop->set)
02399         sprop->set(ptr, value); /* set function needs to clamp its self */
02400     else if(prop->flag & PROP_EDITABLE) {
02401         IDProperty *group;
02402 
02403         group= RNA_struct_idprops(ptr, 1);
02404         if(group)
02405             IDP_AddToGroup(group, IDP_NewString(value, prop->identifier, RNA_property_string_maxlength(prop) - 1));
02406     }
02407 }
02408 
02409 void RNA_property_string_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop, char *value)
02410 {
02411     StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
02412 
02413     BLI_assert(RNA_property_type(prop) == PROP_STRING);
02414 
02415     strcpy(value, sprop->defaultvalue);
02416 }
02417 
02418 char *RNA_property_string_get_default_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen)
02419 {
02420     char *buf;
02421     int length;
02422 
02423     BLI_assert(RNA_property_type(prop) == PROP_STRING);
02424 
02425     length= RNA_property_string_default_length(ptr, prop);
02426 
02427     if(length+1 < fixedlen)
02428         buf= fixedbuf;
02429     else
02430         buf= MEM_callocN(sizeof(char)*(length+1), "RNA_string_get_alloc");
02431 
02432     RNA_property_string_get_default(ptr, prop, buf);
02433 
02434     return buf;
02435 }
02436 
02437 /* this is the length without \0 terminator */
02438 int RNA_property_string_default_length(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
02439 {
02440     StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
02441 
02442     BLI_assert(RNA_property_type(prop) == PROP_STRING);
02443 
02444     return strlen(sprop->defaultvalue);
02445 }
02446 
02447 int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
02448 {
02449     EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
02450     IDProperty *idprop;
02451 
02452     BLI_assert(RNA_property_type(prop) == PROP_ENUM);
02453 
02454     if((idprop=rna_idproperty_check(&prop, ptr)))
02455         return IDP_Int(idprop);
02456     else if(eprop->get)
02457         return eprop->get(ptr);
02458     else
02459         return eprop->defaultvalue;
02460 }
02461 
02462 void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
02463 {
02464     EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
02465     IDProperty *idprop;
02466 
02467     BLI_assert(RNA_property_type(prop) == PROP_ENUM);
02468 
02469     if((idprop=rna_idproperty_check(&prop, ptr))) {
02470         IDP_Int(idprop)= value;
02471         rna_idproperty_touch(idprop);
02472     }
02473     else if(eprop->set) {
02474         eprop->set(ptr, value);
02475     }
02476     else if(prop->flag & PROP_EDITABLE) {
02477         IDPropertyTemplate val = {0};
02478         IDProperty *group;
02479 
02480         val.i= value;
02481 
02482         group= RNA_struct_idprops(ptr, 1);
02483         if(group)
02484             IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier));
02485     }
02486 }
02487 
02488 int RNA_property_enum_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
02489 {
02490     EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
02491 
02492     BLI_assert(RNA_property_type(prop) == PROP_ENUM);
02493 
02494     return eprop->defaultvalue;
02495 }
02496 
02497 void *RNA_property_enum_py_data_get(PropertyRNA *prop)
02498 {
02499     EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
02500 
02501     BLI_assert(RNA_property_type(prop) == PROP_ENUM);
02502 
02503     return eprop->py_data;
02504 }
02505 
02506 PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
02507 {
02508     PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
02509     IDProperty *idprop;
02510 
02511     BLI_assert(RNA_property_type(prop) == PROP_POINTER);
02512 
02513     if((idprop=rna_idproperty_check(&prop, ptr))) {
02514         pprop= (PointerPropertyRNA*)prop;
02515 
02516         /* for groups, data is idprop itself */
02517         return rna_pointer_inherit_refine(ptr, pprop->type, idprop);
02518     }
02519     else if(pprop->get) {
02520         return pprop->get(ptr);
02521     }
02522     else if(prop->flag & PROP_IDPROPERTY) {
02523         /* XXX temporary hack to add it automatically, reading should
02524            never do any write ops, to ensure thread safety etc .. */
02525         RNA_property_pointer_add(ptr, prop);
02526         return RNA_property_pointer_get(ptr, prop);
02527     }
02528     else {
02529         return PointerRNA_NULL;
02530     }
02531 }
02532 
02533 void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value)
02534 {
02535     /*IDProperty *idprop;*/
02536 
02537     BLI_assert(RNA_property_type(prop) == PROP_POINTER);
02538 
02539     if((/*idprop=*/ rna_idproperty_check(&prop, ptr))) {
02540         /* not supported */
02541         /* rna_idproperty_touch(idprop); */
02542     }
02543     else {
02544         PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
02545 
02546         if(     pprop->set &&
02547                 !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL) &&
02548                 !((prop->flag & PROP_ID_SELF_CHECK) && ptr->id.data == ptr_value.id.data)
02549         ) {
02550             pprop->set(ptr, ptr_value);
02551         }
02552     }
02553 }
02554 
02555 PointerRNA RNA_property_pointer_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop))
02556 {
02557     //PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
02558 
02559     // BLI_assert(RNA_property_type(prop) == PROP_POINTER);
02560 
02561     return PointerRNA_NULL; // FIXME: there has to be a way...
02562 }
02563 
02564 void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop)
02565 {
02566     /*IDProperty *idprop;*/
02567 
02568     BLI_assert(RNA_property_type(prop) == PROP_POINTER);
02569 
02570     if((/*idprop=*/rna_idproperty_check(&prop, ptr))) {
02571         /* already exists */
02572     }
02573     else if(prop->flag & PROP_IDPROPERTY) {
02574         IDPropertyTemplate val = {0};
02575         IDProperty *group;
02576 
02577         val.i= 0;
02578 
02579         group= RNA_struct_idprops(ptr, 1);
02580         if(group)
02581             IDP_AddToGroup(group, IDP_New(IDP_GROUP, &val, prop->identifier));
02582     }
02583     else
02584         printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);
02585 }
02586 
02587 void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop)
02588 {
02589     IDProperty *idprop, *group;
02590 
02591     BLI_assert(RNA_property_type(prop) == PROP_POINTER);
02592 
02593     if((idprop=rna_idproperty_check(&prop, ptr))) {
02594         group= RNA_struct_idprops(ptr, 0);
02595         
02596         if(group) {
02597             IDP_RemFromGroup(group, idprop);
02598             IDP_FreeProperty(idprop);
02599             MEM_freeN(idprop);
02600         }
02601     }
02602     else
02603         printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);
02604 }
02605 
02606 static void rna_property_collection_get_idp(CollectionPropertyIterator *iter)
02607 {
02608     CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
02609 
02610     iter->ptr.data= rna_iterator_array_get(iter);
02611     iter->ptr.type= cprop->item_type;
02612     rna_pointer_inherit_id(cprop->item_type, &iter->parent, &iter->ptr);
02613 }
02614 
02615 void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter)
02616 {
02617     IDProperty *idprop;
02618 
02619     BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
02620 
02621     memset(iter, 0, sizeof(*iter));
02622 
02623     if((idprop=rna_idproperty_check(&prop, ptr)) || (prop->flag & PROP_IDPROPERTY)) {
02624         iter->parent= *ptr;
02625         iter->prop= prop;
02626 
02627         if(idprop)
02628             rna_iterator_array_begin(iter, IDP_IDPArray(idprop), sizeof(IDProperty), idprop->len, 0, NULL);
02629         else
02630             rna_iterator_array_begin(iter, NULL, sizeof(IDProperty), 0, 0, NULL);
02631 
02632         if(iter->valid)
02633             rna_property_collection_get_idp(iter);
02634 
02635         iter->idprop= 1;
02636     }
02637     else {
02638         CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
02639         cprop->begin(iter, ptr);
02640     }
02641 }
02642 
02643 void RNA_property_collection_next(CollectionPropertyIterator *iter)
02644 {
02645     CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(iter->prop);
02646 
02647     if(iter->idprop) {
02648         rna_iterator_array_next(iter);
02649 
02650         if(iter->valid)
02651             rna_property_collection_get_idp(iter);
02652     }
02653     else
02654         cprop->next(iter);
02655 }
02656 
02657 void RNA_property_collection_end(CollectionPropertyIterator *iter)
02658 {
02659     CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(iter->prop);
02660 
02661     if(iter->idprop)
02662         rna_iterator_array_end(iter);
02663     else
02664         cprop->end(iter);
02665 }
02666 
02667 int RNA_property_collection_length(PointerRNA *ptr, PropertyRNA *prop)
02668 {
02669     CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
02670     IDProperty *idprop;
02671 
02672     BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
02673 
02674     if((idprop=rna_idproperty_check(&prop, ptr))) {
02675         return idprop->len;
02676     }
02677     else if(cprop->length) {
02678         return cprop->length(ptr);
02679     }
02680     else {
02681         CollectionPropertyIterator iter;
02682         int length= 0;
02683 
02684         RNA_property_collection_begin(ptr, prop, &iter);
02685         for(; iter.valid; RNA_property_collection_next(&iter))
02686             length++;
02687         RNA_property_collection_end(&iter);
02688 
02689         return length;
02690     }
02691 }
02692 
02693 void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
02694 {
02695     IDProperty *idprop;
02696 //  CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
02697 
02698     BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
02699 
02700     if((idprop=rna_idproperty_check(&prop, ptr))) {
02701         IDPropertyTemplate val = {0};
02702         IDProperty *item;
02703 
02704         item= IDP_New(IDP_GROUP, &val, "");
02705         IDP_AppendArray(idprop, item);
02706         // IDP_FreeProperty(item); // IDP_AppendArray does a shallow copy (memcpy), only free memory 
02707         MEM_freeN(item);
02708     }
02709     else if(prop->flag & PROP_IDPROPERTY) {
02710         IDProperty *group, *item;
02711         IDPropertyTemplate val = {0};
02712 
02713         group= RNA_struct_idprops(ptr, 1);
02714         if(group) {
02715             idprop= IDP_NewIDPArray(prop->identifier);
02716             IDP_AddToGroup(group, idprop);
02717 
02718             item= IDP_New(IDP_GROUP, &val, "");
02719             IDP_AppendArray(idprop, item);
02720             // IDP_FreeProperty(item); // IDP_AppendArray does a shallow copy (memcpy), only free memory
02721             MEM_freeN(item);
02722         }
02723     }
02724 
02725     /* py api calls directly */
02726 #if 0
02727     else if(cprop->add){
02728         if(!(cprop->add->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
02729             ParameterList params;
02730             RNA_parameter_list_create(&params, ptr, cprop->add);
02731             RNA_function_call(NULL, NULL, ptr, cprop->add, &params);
02732             RNA_parameter_list_free(&params);
02733         }
02734     }
02735     /*else
02736         printf("%s %s.%s: not implemented for this property.\n", __func__, ptr->type->identifier, prop->identifier);*/
02737 #endif
02738 
02739     if(r_ptr) {
02740         if(idprop) {
02741             CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
02742 
02743             r_ptr->data= IDP_GetIndexArray(idprop, idprop->len-1);
02744             r_ptr->type= cprop->item_type;
02745             rna_pointer_inherit_id(NULL, ptr, r_ptr);
02746         }
02747         else
02748             memset(r_ptr, 0, sizeof(*r_ptr));
02749     }
02750 }
02751 
02752 int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
02753 {
02754     IDProperty *idprop;
02755 //  CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
02756 
02757     BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
02758 
02759     if((idprop=rna_idproperty_check(&prop, ptr))) {
02760         IDProperty tmp, *array;
02761         int len;
02762 
02763         len= idprop->len;
02764         array= IDP_IDPArray(idprop);
02765 
02766         if(key >= 0 && key < len) {
02767             if(key+1 < len) {
02768                 /* move element to be removed to the back */
02769                 memcpy(&tmp, &array[key], sizeof(IDProperty));
02770                 memmove(array+key, array+key+1, sizeof(IDProperty)*(len-(key+1)));
02771                 memcpy(&array[len-1], &tmp, sizeof(IDProperty));
02772             }
02773 
02774             IDP_ResizeIDPArray(idprop, len-1);
02775         }
02776 
02777         return 1;
02778     }
02779     else if(prop->flag & PROP_IDPROPERTY)
02780         return 1;
02781 
02782     /* py api calls directly */
02783 #if 0
02784     else if(cprop->remove){
02785         if(!(cprop->remove->flag & FUNC_USE_CONTEXT)) { /* XXX check for this somewhere else */
02786             ParameterList params;
02787             RNA_parameter_list_create(&params, ptr, cprop->remove);
02788             RNA_function_call(NULL, NULL, ptr, cprop->remove, &params);
02789             RNA_parameter_list_free(&params);
02790         }
02791 
02792         return 0;
02793     }
02794     /*else
02795         printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);*/
02796 #endif
02797     return 0;
02798 }
02799 
02800 int RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos)
02801 {
02802     IDProperty *idprop;
02803 
02804     BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
02805 
02806     if((idprop=rna_idproperty_check(&prop, ptr))) {
02807         IDProperty tmp, *array;
02808         int len;
02809 
02810         len= idprop->len;
02811         array= IDP_IDPArray(idprop);
02812 
02813         if(key >= 0 && key < len && pos >= 0 && pos < len && key != pos) {
02814             memcpy(&tmp, &array[key], sizeof(IDProperty));
02815             if(pos < key)
02816                 memmove(array+pos+1, array+pos, sizeof(IDProperty)*(key - pos));
02817             else
02818                 memmove(array+key, array+key+1, sizeof(IDProperty)*(pos - key));
02819             memcpy(&array[pos], &tmp, sizeof(IDProperty));
02820         }
02821 
02822         return 1;
02823     }
02824     else if(prop->flag & PROP_IDPROPERTY)
02825         return 1;
02826 
02827     return 0;
02828 }
02829 
02830 void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
02831 {
02832     IDProperty *idprop;
02833 
02834     BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
02835 
02836     if((idprop=rna_idproperty_check(&prop, ptr)))
02837         IDP_ResizeIDPArray(idprop, 0);
02838 }
02839 
02840 int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *t_ptr)
02841 {
02842     CollectionPropertyIterator iter;
02843     int index= 0;
02844     
02845     BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
02846 
02847     RNA_property_collection_begin(ptr, prop, &iter);
02848     for(index=0; iter.valid; RNA_property_collection_next(&iter), index++) {
02849         if (iter.ptr.data == t_ptr->data)
02850             break;
02851     }
02852     RNA_property_collection_end(&iter);
02853     
02854     /* did we find it? */
02855     if (iter.valid)
02856         return index;
02857     else
02858         return -1;
02859 }
02860 
02861 int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
02862 {
02863     CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(prop);
02864 
02865     BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
02866 
02867     if(cprop->lookupint) {
02868         /* we have a callback defined, use it */
02869         return cprop->lookupint(ptr, key, r_ptr);
02870     }
02871     else {
02872         /* no callback defined, just iterate and find the nth item */
02873         CollectionPropertyIterator iter;
02874         int i;
02875 
02876         RNA_property_collection_begin(ptr, prop, &iter);
02877         for(i=0; iter.valid; RNA_property_collection_next(&iter), i++) {
02878             if(i == key) {
02879                 *r_ptr= iter.ptr;
02880                 break;
02881             }
02882         }
02883         RNA_property_collection_end(&iter);
02884 
02885         if(!iter.valid)
02886             memset(r_ptr, 0, sizeof(*r_ptr));
02887 
02888         return iter.valid;
02889     }
02890 }
02891 
02892 int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr)
02893 {
02894     CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(prop);
02895 
02896     BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
02897 
02898     if(cprop->lookupstring) {
02899         /* we have a callback defined, use it */
02900         return cprop->lookupstring(ptr, key, r_ptr);
02901     }
02902     else {
02903         /* no callback defined, compare with name properties if they exist */
02904         CollectionPropertyIterator iter;
02905         PropertyRNA *nameprop;
02906         char name[256], *nameptr;
02907         int found= 0;
02908         int keylen= strlen(key);
02909         int namelen;
02910 
02911         RNA_property_collection_begin(ptr, prop, &iter);
02912         for(; iter.valid; RNA_property_collection_next(&iter)) {
02913             if(iter.ptr.data && iter.ptr.type->nameproperty) {
02914                 nameprop= iter.ptr.type->nameproperty;
02915 
02916                 nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name), &namelen);
02917 
02918                 if((keylen == namelen) && (strcmp(nameptr, key) == 0)) {
02919                     *r_ptr= iter.ptr;
02920                     found= 1;
02921                 }
02922 
02923                 if((char *)&name != nameptr)
02924                     MEM_freeN(nameptr);
02925 
02926                 if(found)
02927                     break;
02928             }
02929         }
02930         RNA_property_collection_end(&iter);
02931 
02932         if(!iter.valid)
02933             memset(r_ptr, 0, sizeof(*r_ptr));
02934 
02935         return iter.valid;
02936     }
02937 }
02938 
02939 /* zero return is an assignment error */
02940 int RNA_property_collection_assign_int(PointerRNA *ptr, PropertyRNA *prop, const int key, const PointerRNA *assign_ptr)
02941 {
02942     CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)rna_ensure_property(prop);
02943 
02944     BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
02945 
02946     if(cprop->assignint) {
02947         /* we have a callback defined, use it */
02948         return cprop->assignint(ptr, key, assign_ptr);
02949     }
02950 
02951     return 0;
02952 }
02953 
02954 int RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
02955 {
02956     BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
02957 
02958     *r_ptr= *ptr;
02959     return ((r_ptr->type = rna_ensure_property(prop)->srna) ? 1:0);
02960 }
02961 
02962 int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array)
02963 {
02964     CollectionPropertyIterator iter;
02965     ArrayIterator *internal;
02966     char *arrayp;
02967 
02968     BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
02969 
02970     if(!(prop->flag & PROP_RAW_ARRAY) || !(itemprop->flag & PROP_RAW_ACCESS))
02971         return 0;
02972 
02973     RNA_property_collection_begin(ptr, prop, &iter);
02974 
02975     if(iter.valid) {
02976         /* get data from array iterator and item property */
02977         internal= iter.internal;
02978         arrayp= (iter.valid)? iter.ptr.data: NULL;
02979 
02980         if(internal->skip || !RNA_property_editable(&iter.ptr, itemprop)) {
02981             /* we might skip some items, so it's not a proper array */
02982             RNA_property_collection_end(&iter);
02983             return 0;
02984         }
02985 
02986         array->array= arrayp + itemprop->rawoffset;
02987         array->stride= internal->itemsize;
02988         array->len= ((char*)internal->endptr - arrayp)/internal->itemsize;
02989         array->type= itemprop->rawtype;
02990     }
02991     else
02992         memset(array, 0, sizeof(RawArray));
02993 
02994     RNA_property_collection_end(&iter);
02995 
02996     return 1;
02997 }
02998 
02999 #define RAW_GET(dtype, var, raw, a)                                           \
03000 {                                                                             \
03001     switch(raw.type) {                                                        \
03002         case PROP_RAW_CHAR: var = (dtype)((char*)raw.array)[a]; break;        \
03003         case PROP_RAW_SHORT: var = (dtype)((short*)raw.array)[a]; break;      \
03004         case PROP_RAW_INT: var = (dtype)((int*)raw.array)[a]; break;          \
03005         case PROP_RAW_FLOAT: var = (dtype)((float*)raw.array)[a]; break;      \
03006         case PROP_RAW_DOUBLE: var = (dtype)((double*)raw.array)[a]; break;    \
03007         default: var = (dtype)0;                                              \
03008     }                                                                         \
03009 }
03010 
03011 #define RAW_SET(dtype, raw, a, var)                                           \
03012 {                                                                             \
03013     switch(raw.type) {                                                        \
03014         case PROP_RAW_CHAR: ((char*)raw.array)[a] = (char)var; break;         \
03015         case PROP_RAW_SHORT: ((short*)raw.array)[a] = (short)var; break;      \
03016         case PROP_RAW_INT: ((int*)raw.array)[a] = (int)var; break;            \
03017         case PROP_RAW_FLOAT: ((float*)raw.array)[a] = (float)var; break;      \
03018         case PROP_RAW_DOUBLE: ((double*)raw.array)[a] = (double)var; break;   \
03019         default: break;                                                       \
03020     }                                                                         \
03021 }
03022 
03023 int RNA_raw_type_sizeof(RawPropertyType type)
03024 {
03025     switch(type) {
03026         case PROP_RAW_CHAR: return sizeof(char);
03027         case PROP_RAW_SHORT: return sizeof(short);
03028         case PROP_RAW_INT: return sizeof(int);
03029         case PROP_RAW_FLOAT: return sizeof(float);
03030         case PROP_RAW_DOUBLE: return sizeof(double);
03031         default: return 0;
03032     }
03033 }
03034 
03035 static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname, void *inarray, RawPropertyType intype, int inlen, int set)
03036 {
03037     StructRNA *ptype;
03038     PointerRNA itemptr;
03039     PropertyRNA *itemprop, *iprop;
03040     PropertyType itemtype=0;
03041     RawArray in;
03042     int itemlen= 0;
03043 
03044     /* initialize in array, stride assumed 0 in following code */
03045     in.array= inarray;
03046     in.type= intype;
03047     in.len= inlen;
03048     in.stride= 0;
03049 
03050     ptype= RNA_property_pointer_type(ptr, prop);
03051 
03052     /* try to get item property pointer */
03053     RNA_pointer_create(NULL, ptype, NULL, &itemptr);
03054     itemprop= RNA_struct_find_property(&itemptr, propname);
03055 
03056     if(itemprop) {
03057         /* we have item property pointer */
03058         RawArray out;
03059 
03060         /* check type */
03061         itemtype= RNA_property_type(itemprop);
03062 
03063         if(!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
03064             BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported");
03065             return 0;
03066         }
03067 
03068         /* check item array */
03069         itemlen= RNA_property_array_length(&itemptr, itemprop);
03070 
03071         /* try to access as raw array */
03072         if(RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) {
03073             int arraylen = (itemlen == 0) ? 1 : itemlen;
03074             if(in.len != arraylen*out.len) {
03075                 BKE_reportf(reports, RPT_ERROR, "Array length mismatch (expected %d, got %d)", out.len*arraylen, in.len);
03076                 return 0;
03077             }
03078             
03079             /* matching raw types */
03080             if(out.type == in.type) {
03081                 void *inp= in.array;
03082                 void *outp= out.array;
03083                 int a, size;
03084 
03085                 size= RNA_raw_type_sizeof(out.type) * arraylen;
03086 
03087                 for(a=0; a<out.len; a++) {
03088                     if(set) memcpy(outp, inp, size);
03089                     else memcpy(inp, outp, size);
03090 
03091                     inp= (char*)inp + size;
03092                     outp= (char*)outp + out.stride;
03093                 }
03094 
03095                 return 1;
03096             }
03097 
03098             /* could also be faster with non-matching types,
03099              * for now we just do slower loop .. */
03100         }
03101     }
03102 
03103     {
03104         void *tmparray= NULL;
03105         int tmplen= 0;
03106         int err= 0, j, a= 0;
03107         int needconv = 1;
03108 
03109         if (((itemtype == PROP_BOOLEAN || itemtype == PROP_INT) && in.type == PROP_RAW_INT) ||
03110             (itemtype == PROP_FLOAT && in.type == PROP_RAW_FLOAT))
03111             /* avoid creating temporary buffer if the data type match */
03112             needconv = 0;
03113 
03114         /* no item property pointer, can still be id property, or
03115          * property of a type derived from the collection pointer type */
03116         RNA_PROP_BEGIN(ptr, itemptr, prop) {
03117             if(itemptr.data) {
03118                 if(itemprop) {
03119                     /* we got the property already */
03120                     iprop= itemprop;
03121                 }
03122                 else {
03123                     /* not yet, look it up and verify if it is valid */
03124                     iprop= RNA_struct_find_property(&itemptr, propname);
03125 
03126                     if(iprop) {
03127                         itemlen= RNA_property_array_length(&itemptr, iprop);
03128                         itemtype= RNA_property_type(iprop);
03129                     }
03130                     else {
03131                         BKE_reportf(reports, RPT_ERROR, "Property named %s not found", propname);
03132                         err= 1;
03133                         break;
03134                     }
03135 
03136                     if(!ELEM3(itemtype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
03137                         BKE_report(reports, RPT_ERROR, "Only boolean, int and float properties supported");
03138                         err= 1;
03139                         break;
03140                     }
03141                 }
03142 
03143                 /* editable check */
03144                 if(!set || RNA_property_editable(&itemptr, iprop)) {
03145                     if(a+itemlen > in.len) {
03146                         BKE_reportf(reports, RPT_ERROR, "Array length mismatch (got %d, expected more)", in.len);
03147                         err= 1;
03148                         break;
03149                     }
03150 
03151                     if(itemlen == 0) {
03152                         /* handle conversions */
03153                         if(set) {
03154                             switch(itemtype) {
03155                                 case PROP_BOOLEAN: {
03156                                     int b;
03157                                     RAW_GET(int, b, in, a);
03158                                     RNA_property_boolean_set(&itemptr, iprop, b);
03159                                     break;
03160                                 }
03161                                 case PROP_INT: {
03162                                     int i;
03163                                     RAW_GET(int, i, in, a);
03164                                     RNA_property_int_set(&itemptr, iprop, i);
03165                                     break;
03166                                 }
03167                                 case PROP_FLOAT: {
03168                                     float f;
03169                                     RAW_GET(float, f, in, a);
03170                                     RNA_property_float_set(&itemptr, iprop, f);
03171                                     break;
03172                                 }
03173                                 default:
03174                                     break;
03175                             }
03176                         }
03177                         else {
03178                             switch(itemtype) {
03179                                 case PROP_BOOLEAN: {
03180                                     int b= RNA_property_boolean_get(&itemptr, iprop);
03181                                     RAW_SET(int, in, a, b);
03182                                     break;
03183                                 }
03184                                 case PROP_INT: {
03185                                     int i= RNA_property_int_get(&itemptr, iprop);
03186                                     RAW_SET(int, in, a, i);
03187                                     break;
03188                                 }
03189                                 case PROP_FLOAT: {
03190                                     float f= RNA_property_float_get(&itemptr, iprop);
03191                                     RAW_SET(float, in, a, f);
03192                                     break;
03193                                 }
03194                                 default:
03195                                     break;
03196                             }
03197                         }
03198                         a++;
03199                     }
03200                     else if (needconv == 1) {
03201                         /* allocate temporary array if needed */
03202                         if(tmparray && tmplen != itemlen) {
03203                             MEM_freeN(tmparray);
03204                             tmparray= NULL;
03205                         }
03206                         if(!tmparray) {
03207                             tmparray= MEM_callocN(sizeof(float)*itemlen, "RNA tmparray\n");
03208                             tmplen= itemlen;
03209                         }
03210 
03211                         /* handle conversions */
03212                         if(set) {
03213                             switch(itemtype) {
03214                                 case PROP_BOOLEAN: {
03215                                     for(j=0; j<itemlen; j++, a++)
03216                                         RAW_GET(int, ((int*)tmparray)[j], in, a);
03217                                     RNA_property_boolean_set_array(&itemptr, iprop, tmparray);
03218                                     break;
03219                                 }
03220                                 case PROP_INT: {
03221                                     for(j=0; j<itemlen; j++, a++)
03222                                         RAW_GET(int, ((int*)tmparray)[j], in, a);
03223                                     RNA_property_int_set_array(&itemptr, iprop, tmparray);
03224                                     break;
03225                                 }
03226                                 case PROP_FLOAT: {
03227                                     for(j=0; j<itemlen; j++, a++)
03228                                         RAW_GET(float, ((float*)tmparray)[j], in, a);
03229                                     RNA_property_float_set_array(&itemptr, iprop, tmparray);
03230                                     break;
03231                                 }
03232                                 default:
03233                                     break;
03234                             }
03235                         }
03236                         else {
03237                             switch(itemtype) {
03238                                 case PROP_BOOLEAN: {
03239                                     RNA_property_boolean_get_array(&itemptr, iprop, tmparray);
03240                                     for(j=0; j<itemlen; j++, a++)
03241                                         RAW_SET(int, in, a, ((int*)tmparray)[j]);
03242                                     break;
03243                                 }
03244                                 case PROP_INT: {
03245                                     RNA_property_int_get_array(&itemptr, iprop, tmparray);
03246                                     for(j=0; j<itemlen; j++, a++)
03247                                         RAW_SET(int, in, a, ((int*)tmparray)[j]);
03248                                     break;
03249                                 }
03250                                 case PROP_FLOAT: {
03251                                     RNA_property_float_get_array(&itemptr, iprop, tmparray);
03252                                     for(j=0; j<itemlen; j++, a++)
03253                                         RAW_SET(float, in, a, ((float*)tmparray)[j]);
03254                                     break;
03255                                 }
03256                                 default:
03257                                     break;
03258                             }
03259                         }
03260                     }
03261                     else {
03262                         if(set) {
03263                             switch(itemtype) {
03264                                 case PROP_BOOLEAN: {
03265                                     RNA_property_boolean_set_array(&itemptr, iprop, &((int*)in.array)[a]);
03266                                     a += itemlen;
03267                                     break;
03268                                 }
03269                                 case PROP_INT: {
03270                                     RNA_property_int_set_array(&itemptr, iprop, &((int*)in.array)[a]);
03271                                     a += itemlen;
03272                                     break;
03273                                 }
03274                                 case PROP_FLOAT: {
03275                                     RNA_property_float_set_array(&itemptr, iprop, &((float*)in.array)[a]);
03276                                     a += itemlen;
03277                                     break;
03278                                 }
03279                                 default:
03280                                     break;
03281                             }
03282                         }
03283                         else {
03284                             switch(itemtype) {
03285                                 case PROP_BOOLEAN: {
03286                                     RNA_property_boolean_get_array(&itemptr, iprop, &((int*)in.array)[a]);
03287                                     a += itemlen;
03288                                     break;
03289                                 }
03290                                 case PROP_INT: {
03291                                     RNA_property_int_get_array(&itemptr, iprop, &((int*)in.array)[a]);
03292                                     a += itemlen;
03293                                     break;
03294                                 }
03295                                 case PROP_FLOAT: {
03296                                     RNA_property_float_get_array(&itemptr, iprop, &((float*)in.array)[a]);
03297                                     a += itemlen;
03298                                     break;
03299                                 }
03300                                 default:
03301                                     break;
03302                             }
03303                         }
03304                     }
03305                 }
03306             }
03307         }
03308         RNA_PROP_END;
03309 
03310         if(tmparray)
03311             MEM_freeN(tmparray);
03312 
03313         return !err;
03314     }
03315 }
03316 
03317 RawPropertyType RNA_property_raw_type(PropertyRNA *prop)
03318 {
03319     if (prop->rawtype == PROP_RAW_UNSET) {
03320         /* this property has no raw access, yet we try to provide a raw type to help building the array */
03321         switch (prop->type) {
03322         case PROP_BOOLEAN:
03323             return PROP_RAW_INT;
03324         case PROP_INT:
03325             return PROP_RAW_INT;
03326         case PROP_FLOAT:
03327             return PROP_RAW_FLOAT;
03328         case PROP_ENUM:
03329             return PROP_RAW_INT;
03330         default:
03331             break;
03332         }
03333     }
03334     return prop->rawtype;
03335 }
03336 
03337 int RNA_property_collection_raw_get(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname, void *array, RawPropertyType type, int len)
03338 {
03339     return rna_raw_access(reports, ptr, prop, propname, array, type, len, 0);
03340 }
03341 
03342 int RNA_property_collection_raw_set(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, const char *propname, void *array, RawPropertyType type, int len)
03343 {
03344     return rna_raw_access(reports, ptr, prop, propname, array, type, len, 1);
03345 }
03346 
03347 /* Standard iterator functions */
03348 
03349 void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb, IteratorSkipFunc skip)
03350 {
03351     ListBaseIterator *internal;
03352 
03353     internal= MEM_callocN(sizeof(ListBaseIterator), "ListBaseIterator");
03354     internal->link= (lb)? lb->first: NULL;
03355     internal->skip= skip;
03356 
03357     iter->internal= internal;
03358     iter->valid= (internal->link != NULL);
03359 
03360     if(skip && iter->valid && skip(iter, internal->link))
03361         rna_iterator_listbase_next(iter);
03362 }
03363 
03364 void rna_iterator_listbase_next(CollectionPropertyIterator *iter)
03365 {
03366     ListBaseIterator *internal= iter->internal;
03367 
03368     if(internal->skip) {
03369         do {
03370             internal->link= internal->link->next;
03371             iter->valid= (internal->link != NULL);
03372         } while(iter->valid && internal->skip(iter, internal->link));
03373     }
03374     else {
03375         internal->link= internal->link->next;
03376         iter->valid= (internal->link != NULL);
03377     }
03378 }
03379 
03380 void *rna_iterator_listbase_get(CollectionPropertyIterator *iter)
03381 {
03382     ListBaseIterator *internal= iter->internal;
03383 
03384     return internal->link;
03385 }
03386 
03387 void rna_iterator_listbase_end(CollectionPropertyIterator *iter)
03388 {
03389     MEM_freeN(iter->internal);
03390     iter->internal= NULL;
03391 }
03392 
03393 PointerRNA rna_listbase_lookup_int(PointerRNA *ptr, StructRNA *type, struct ListBase *lb, int index)
03394 {
03395     void *data= BLI_findlink(lb, index);
03396     return rna_pointer_inherit_refine(ptr, type, data);
03397 }
03398 
03399 void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int itemsize, int length, int free_ptr, IteratorSkipFunc skip)
03400 {
03401     ArrayIterator *internal;
03402 
03403     if(ptr == NULL)
03404         length= 0;
03405     else if (length == 0) {
03406         ptr= NULL;
03407         itemsize= 0;
03408     }
03409 
03410     internal= MEM_callocN(sizeof(ArrayIterator), "ArrayIterator");
03411     internal->ptr= ptr;
03412     internal->free_ptr= free_ptr ? ptr:NULL;
03413     internal->endptr= ((char*)ptr)+length*itemsize;
03414     internal->itemsize= itemsize;
03415     internal->skip= skip;
03416     internal->length= length;
03417     
03418     iter->internal= internal;
03419     iter->valid= (internal->ptr != internal->endptr);
03420 
03421     if(skip && iter->valid && skip(iter, internal->ptr))
03422         rna_iterator_array_next(iter);
03423 }
03424 
03425 void rna_iterator_array_next(CollectionPropertyIterator *iter)
03426 {
03427     ArrayIterator *internal= iter->internal;
03428 
03429     if(internal->skip) {
03430         do {
03431             internal->ptr += internal->itemsize;
03432             iter->valid= (internal->ptr != internal->endptr);
03433         } while(iter->valid && internal->skip(iter, internal->ptr));
03434     }
03435     else {
03436         internal->ptr += internal->itemsize;
03437         iter->valid= (internal->ptr != internal->endptr);
03438     }
03439 }
03440 
03441 void *rna_iterator_array_get(CollectionPropertyIterator *iter)
03442 {
03443     ArrayIterator *internal= iter->internal;
03444 
03445     return internal->ptr;
03446 }
03447 
03448 void *rna_iterator_array_dereference_get(CollectionPropertyIterator *iter)
03449 {
03450     ArrayIterator *internal= iter->internal;
03451 
03452     /* for ** arrays */
03453     return *(void**)(internal->ptr);
03454 }
03455 
03456 void rna_iterator_array_end(CollectionPropertyIterator *iter)
03457 {
03458     ArrayIterator *internal= iter->internal;
03459     
03460     if(internal->free_ptr) {
03461         MEM_freeN(internal->free_ptr);
03462         internal->free_ptr= NULL;
03463     }
03464     MEM_freeN(iter->internal);
03465     iter->internal= NULL;
03466 }
03467 
03468 PointerRNA rna_array_lookup_int(PointerRNA *ptr, StructRNA *type, void *data, int itemsize, int length, int index)
03469 {
03470     if(index < 0 || index >= length)
03471         return PointerRNA_NULL;
03472 
03473     return rna_pointer_inherit_refine(ptr, type, ((char*)data) + index*itemsize);
03474 }
03475 
03476 /* RNA Path - Experiment */
03477 
03478 static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int bracket)
03479 {
03480     const char *p;
03481     char *buf;
03482     char quote= '\0';
03483     int i, j, len, escape;
03484 
03485     len= 0;
03486 
03487     if(bracket) {
03488         /* get data between [], check escaping ] with \] */
03489         if(**path == '[') (*path)++;
03490         else return NULL;
03491 
03492         p= *path;
03493 
03494         /* 2 kinds of lookups now, quoted or unquoted */
03495         quote= *p;
03496 
03497         if(quote != '"') /* " - this comment is hack for Aligorith's text editor's sanity */
03498             quote= 0;
03499 
03500         if(quote==0) {
03501             while(*p && (*p != ']')) {
03502                 len++;
03503                 p++;
03504             }
03505         }
03506         else {
03507             escape= 0;
03508             /* skip the first quote */
03509             len++;
03510             p++;
03511             while(*p && (*p != quote || escape)) {
03512                 escape= (*p == '\\');
03513                 len++;
03514                 p++;
03515             }
03516             
03517             /* skip the last quoted char to get the ']' */
03518             len++;
03519             p++;
03520         }
03521 
03522         if(*p != ']') return NULL;
03523     }
03524     else {
03525         /* get data until . or [ */
03526         p= *path;
03527 
03528         while(*p && *p != '.' && *p != '[') {
03529             len++;
03530             p++;
03531         }
03532     }
03533     
03534     /* empty, return */
03535     if(len == 0)
03536         return NULL;
03537     
03538     /* try to use fixed buffer if possible */
03539     if(len+1 < fixedlen)
03540         buf= fixedbuf;
03541     else
03542         buf= MEM_callocN(sizeof(char)*(len+1), "rna_path_token");
03543 
03544     /* copy string, taking into account escaped ] */
03545     if(bracket) {
03546         for(p=*path, i=0, j=0; i<len; i++, p++) {
03547             if(*p == '\\' && *(p+1) == quote);
03548             else buf[j++]= *p;
03549         }
03550 
03551         buf[j]= 0;
03552     }
03553     else {
03554         memcpy(buf, *path, sizeof(char)*len);
03555         buf[len]= '\0';
03556     }
03557 
03558     /* set path to start of next token */
03559     if(*p == ']') p++;
03560     if(*p == '.') p++;
03561     *path= p;
03562 
03563     return buf;
03564 }
03565 
03566 static int rna_token_strip_quotes(char *token)
03567 {
03568     if(token[0]=='"') {
03569         int len = strlen(token);
03570         if (len >= 2 && token[len-1]=='"') {
03571             /* strip away "" */
03572             token[len-1]= '\0';
03573             return 1;
03574         }
03575     }
03576     return 0;
03577 }
03578 
03579 /* Resolve the given RNA path to find the pointer+property indicated at the end of the path */
03580 int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
03581 {
03582     return RNA_path_resolve_full(ptr, path, r_ptr, r_prop, NULL);
03583 }
03584 
03585 int RNA_path_resolve_full(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *index)
03586 {
03587     PropertyRNA *prop;
03588     PointerRNA curptr, nextptr;
03589     char fixedbuf[256], *token;
03590     int type, intkey;
03591 
03592     prop= NULL;
03593     curptr= *ptr;
03594 
03595     if(path==NULL || *path=='\0')
03596         return 0;
03597 
03598     while(*path) {
03599         int use_id_prop = (*path=='[') ? 1:0;
03600         /* custom property lookup ?
03601          * C.object["someprop"]
03602          */
03603 
03604         /* look up property name in current struct */
03605         token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), use_id_prop);
03606 
03607         if(!token)
03608             return 0;
03609 
03610         if(use_id_prop) { /* look up property name in current struct */
03611             IDProperty *group= RNA_struct_idprops(&curptr, 0);
03612             if(group && rna_token_strip_quotes(token))
03613                 prop= (PropertyRNA *)IDP_GetPropertyFromGroup(group, token+1);
03614         }
03615         else {
03616             prop= RNA_struct_find_property(&curptr, token);
03617         }
03618 
03619         if(token != fixedbuf)
03620             MEM_freeN(token);
03621 
03622         if(!prop)
03623             return 0;
03624 
03625         type= RNA_property_type(prop);
03626 
03627         /* now look up the value of this property if it is a pointer or
03628          * collection, otherwise return the property rna so that the
03629          * caller can read the value of the property itself */
03630         switch (type) {
03631         case PROP_POINTER:
03632             nextptr= RNA_property_pointer_get(&curptr, prop);
03633 
03634             if(nextptr.data) {
03635                 curptr= nextptr;
03636                 prop= NULL; /* now we have a PointerRNA, the prop is our parent so forget it */
03637                 if(index) *index= -1;
03638             }
03639             else
03640                 return 0;
03641 
03642             break;
03643         case PROP_COLLECTION:
03644             if(*path) {
03645                 if(*path == '[') {
03646                     /* resolve the lookup with [] brackets */
03647                     token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1);
03648     
03649                     if(!token)
03650                         return 0;
03651     
03652                     /* check for "" to see if it is a string */
03653                     if(rna_token_strip_quotes(token)) {
03654                         RNA_property_collection_lookup_string(&curptr, prop, token+1, &nextptr);
03655                     }
03656                     else {
03657                         /* otherwise do int lookup */
03658                         intkey= atoi(token);
03659                         if(intkey==0 && (token[0] != '0' || token[1] != '\0')) {
03660                             return 0; /* we can be sure the fixedbuf was used in this case */
03661                         }
03662                         RNA_property_collection_lookup_int(&curptr, prop, intkey, &nextptr);
03663                     }
03664 
03665                     if(token != fixedbuf) {
03666                         MEM_freeN(token);
03667                     }
03668                 }
03669                 else {
03670                     PointerRNA c_ptr;
03671                     
03672                     /* ensure we quit on invalid values */
03673                     nextptr.data = NULL;
03674 
03675                     if(RNA_property_collection_type_get(&curptr, prop, &c_ptr)) {
03676                         nextptr= c_ptr;
03677                     }
03678                 }
03679 
03680                 if(nextptr.data) {
03681                     curptr= nextptr;
03682                     prop= NULL;  /* now we have a PointerRNA, the prop is our parent so forget it */
03683                     if(index) *index= -1;
03684                 }
03685                 else
03686                     return 0;
03687             }
03688             
03689             break;
03690         default:
03691             if (index==NULL)
03692                 break;
03693 
03694             *index= -1;
03695 
03696             if (*path) {
03697                 int index_arr[RNA_MAX_ARRAY_DIMENSION]= {0};
03698                 int len[RNA_MAX_ARRAY_DIMENSION];
03699                 const int dim= RNA_property_array_dimension(&curptr, prop, len);
03700                 int i, temp_index;
03701 
03702                 for(i=0; i<dim; i++) {
03703                     temp_index= -1; 
03704 
03705                     /* multi index resolve */
03706                     if (*path=='[') {
03707                         token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1);
03708     
03709                         if(token==NULL) {
03710                             /* invalid syntax blah[] */
03711                             return 0;
03712                         }
03713                         /* check for "" to see if it is a string */
03714                         else if(rna_token_strip_quotes(token)) {
03715                             temp_index= RNA_property_array_item_index(prop, *(token+1));
03716                         }
03717                         else {
03718                             /* otherwise do int lookup */
03719                             temp_index= atoi(token);
03720 
03721                             if(temp_index==0 && (token[0] != '0' || token[1] != '\0')) {
03722                                 if(token != fixedbuf) {
03723                                     MEM_freeN(token);
03724                                 }
03725 
03726                                 return 0;
03727                             }
03728                         }
03729                     }
03730                     else if(dim==1) {
03731                         /* location.x || scale.X, single dimension arrays only */
03732                         token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 0);
03733                         if(token==NULL) {
03734                             /* invalid syntax blah.. */
03735                             return 0;
03736                         }
03737                         temp_index= RNA_property_array_item_index(prop, *token);
03738                     }
03739     
03740                     if(token != fixedbuf) {
03741                         MEM_freeN(token);
03742                     }
03743                     
03744                     /* out of range */
03745                     if(temp_index < 0 || temp_index >= len[i])
03746                         return 0;
03747 
03748                     index_arr[i]= temp_index;
03749                     /* end multi index resolve */
03750                 }
03751 
03752                 /* arrays always contain numbers so further values are not valid */
03753                 if(*path) {
03754                     return 0;
03755                 }
03756                 else {
03757                     int totdim= 1;
03758                     int flat_index= 0;
03759 
03760                     for(i=dim-1; i>=0; i--) {
03761                         flat_index += index_arr[i] * totdim;
03762                         totdim *= len[i];
03763                     }
03764 
03765                     *index= flat_index;
03766                 }
03767             }
03768         }
03769     }
03770 
03771     *r_ptr= curptr;
03772     *r_prop= prop;
03773 
03774     return 1;
03775 }
03776 
03777 
03778 char *RNA_path_append(const char *path, PointerRNA *UNUSED(ptr), PropertyRNA *prop, int intkey, const char *strkey)
03779 {
03780     DynStr *dynstr;
03781     const char *s;
03782     char appendstr[128], *result;
03783     
03784     dynstr= BLI_dynstr_new();
03785 
03786     /* add .identifier */
03787     if(path) {
03788         BLI_dynstr_append(dynstr, (char*)path);
03789         if(*path)
03790             BLI_dynstr_append(dynstr, ".");
03791     }
03792 
03793     BLI_dynstr_append(dynstr, RNA_property_identifier(prop));
03794 
03795     if(RNA_property_type(prop) == PROP_COLLECTION) {
03796         /* add ["strkey"] or [intkey] */
03797         BLI_dynstr_append(dynstr, "[");
03798 
03799         if(strkey) {
03800             BLI_dynstr_append(dynstr, "\"");
03801             for(s=strkey; *s; s++) {
03802                 if(*s == '[') {
03803                     appendstr[0]= '\\';
03804                     appendstr[1]= *s;
03805                     appendstr[2]= 0;
03806                 }
03807                 else {
03808                     appendstr[0]= *s;
03809                     appendstr[1]= 0;
03810                 }
03811                 BLI_dynstr_append(dynstr, appendstr);
03812             }
03813             BLI_dynstr_append(dynstr, "\"");
03814         }
03815         else {
03816             BLI_snprintf(appendstr, sizeof(appendstr), "%d", intkey);
03817             BLI_dynstr_append(dynstr, appendstr);
03818         }
03819 
03820         BLI_dynstr_append(dynstr, "]");
03821     }
03822 
03823     result= BLI_dynstr_get_cstring(dynstr);
03824     BLI_dynstr_free(dynstr);
03825 
03826     return result;
03827 }
03828 
03829 char *RNA_path_back(const char *path)
03830 {
03831     char fixedbuf[256];
03832     const char *previous, *current;
03833     char *result, *token;
03834     int i;
03835 
03836     if(!path)
03837         return NULL;
03838 
03839     previous= NULL;
03840     current= path;
03841 
03842     /* parse token by token until the end, then we back up to the previous
03843      * position and strip of the next token to get the path one step back */
03844     while(*current) {
03845         token= rna_path_token(&current, fixedbuf, sizeof(fixedbuf), 0);
03846 
03847         if(!token)
03848             return NULL;
03849         if(token != fixedbuf)
03850             MEM_freeN(token);
03851 
03852         /* in case of collection we also need to strip off [] */
03853         token= rna_path_token(&current, fixedbuf, sizeof(fixedbuf), 1);
03854         if(token && token != fixedbuf)
03855             MEM_freeN(token);
03856         
03857         if(!*current)
03858             break;
03859 
03860         previous= current;
03861     }
03862 
03863     if(!previous)
03864         return NULL;
03865 
03866     /* copy and strip off last token */
03867     i= previous - path;
03868     result= BLI_strdup(path);
03869 
03870     if(i > 0 && result[i-1] == '.') i--;
03871     result[i]= 0;
03872 
03873     return result;
03874 }
03875 
03876 /* generic path search func
03877  * if its needed this could also reference the IDProperty direct */
03878 typedef struct IDP_Chain {
03879     struct IDP_Chain *up; /* parent member, reverse and set to child for path conversion. */
03880 
03881     const char *name;
03882     int index;
03883 
03884 } IDP_Chain;
03885 
03886 static char *rna_idp_path_create(IDP_Chain *child_link)
03887 {
03888     DynStr *dynstr= BLI_dynstr_new();
03889     char *path;
03890     short first= TRUE;
03891 
03892     int tot= 0;
03893     IDP_Chain *link= child_link;
03894 
03895     /* reverse the list */
03896     IDP_Chain *link_prev;
03897     link_prev= NULL;
03898     while(link) {
03899         IDP_Chain *link_next= link->up;
03900         link->up= link_prev;
03901         link_prev= link;
03902         link= link_next;
03903         tot++;
03904     }
03905 
03906     for(link= link_prev; link; link= link->up) {
03907         /* pass */
03908         if(link->index >= 0) {
03909             BLI_dynstr_appendf(dynstr, first ? "%s[%d]" : ".%s[%d]", link->name, link->index);
03910         }
03911         else {
03912             BLI_dynstr_appendf(dynstr, first ? "%s" : ".%s", link->name);
03913         }
03914 
03915         first= FALSE;
03916     }
03917 
03918     path= BLI_dynstr_get_cstring(dynstr);
03919     BLI_dynstr_free(dynstr);
03920 
03921     if(*path=='\0') {
03922         MEM_freeN(path);
03923         path= NULL;
03924     }
03925 
03926     return path;
03927 }
03928 
03929 static char *rna_idp_path(PointerRNA *ptr, IDProperty *haystack, IDProperty *needle, IDP_Chain *parent_link)
03930 {
03931     char *path= NULL;
03932     IDP_Chain link;
03933 
03934     IDProperty *iter;
03935     int i;
03936 
03937     BLI_assert(haystack->type == IDP_GROUP);
03938 
03939     link.up= parent_link;
03940     link.name= NULL;
03941     link.index= -1;
03942 
03943     for (i=0, iter= haystack->data.group.first; iter; iter= iter->next, i++) {
03944         if(needle == iter) {  /* found! */
03945             link.name= iter->name;
03946             path= rna_idp_path_create(&link);
03947             break;
03948         }
03949         else {
03950             if(iter->type == IDP_GROUP) {
03951                 /* ensure this is RNA */
03952                 PointerRNA child_ptr= RNA_pointer_get(ptr, iter->name);
03953                 if(child_ptr.type) {
03954                     link.name= iter->name;
03955                     if((path= rna_idp_path(&child_ptr, iter, needle, &link))) {
03956                         break;
03957                     }
03958                 }
03959             }
03960             else if (iter->type == IDP_IDPARRAY) {
03961                 PropertyRNA *prop= RNA_struct_find_property(ptr, iter->name);
03962                 if(prop && prop->type == PROP_COLLECTION) {
03963                     IDProperty *array= IDP_IDPArray(iter);
03964                     if(needle >= array && needle < (iter->len + array)) { /* found! */
03965                         link.name= iter->name;
03966                         link.index= (int)(needle - array);
03967                         path= rna_idp_path_create(&link);
03968                         break;
03969                     }
03970                     else {
03971                         int i;
03972                         link.name= iter->name;
03973                         for(i= 0; i < iter->len; i++, array++) {
03974                             PointerRNA child_ptr;
03975                             if(RNA_property_collection_lookup_int(ptr, prop, i, &child_ptr)) {
03976                                 link.index= i;
03977                                 if((path= rna_idp_path(&child_ptr, array, needle, &link))) {
03978                                     break;
03979                                 }
03980                             }
03981                         }
03982                     }
03983                 }
03984             }
03985         }
03986     }
03987 
03988     return path;
03989 }
03990 
03991 static char *rna_path_from_ID_to_idpgroup(PointerRNA *ptr)
03992 {
03993     PointerRNA id_ptr;
03994     IDProperty *haystack;
03995     IDProperty *needle;
03996 
03997     BLI_assert(ptr->id.data != NULL);
03998 
03999     /* TODO, Support Bones/PoseBones. no pointers stored to the bones from here, only the ID. See example in [#25746]
04000      * unless this is added only way to find this is to also search all bones and pose bones of an armature or object */
04001     RNA_id_pointer_create(ptr->id.data, &id_ptr);
04002 
04003     haystack= RNA_struct_idprops(&id_ptr, FALSE);
04004     if(haystack) { /* can fail when called on bones */
04005         needle= ptr->data;
04006         return rna_idp_path(&id_ptr, haystack, needle, NULL);
04007     }
04008     else {
04009         return NULL;
04010     }
04011 }
04012 
04013 char *RNA_path_from_ID_to_struct(PointerRNA *ptr)
04014 {
04015     char *ptrpath=NULL;
04016 
04017     if(!ptr->id.data || !ptr->data)
04018         return NULL;
04019     
04020     if(!RNA_struct_is_ID(ptr->type)) {
04021         if(ptr->type->path) {
04022             /* if type has a path to some ID, use it */
04023             ptrpath= ptr->type->path(ptr);
04024         }
04025         else if(ptr->type->nested && RNA_struct_is_ID(ptr->type->nested)) {
04026             PointerRNA parentptr;
04027             PropertyRNA *userprop;
04028             
04029             /* find the property in the struct we're nested in that references this struct, and 
04030              * use its identifier as the first part of the path used...
04031              */
04032             RNA_id_pointer_create(ptr->id.data, &parentptr);
04033             userprop= RNA_struct_find_nested(&parentptr, ptr->type); 
04034             
04035             if(userprop)
04036                 ptrpath= BLI_strdup(RNA_property_identifier(userprop));
04037             else
04038                 return NULL; // can't do anything about this case yet...
04039         }
04040         else if (RNA_struct_is_a(ptr->type, &RNA_PropertyGroup)) {
04041             /* special case, easier to deal with here then in ptr->type->path() */
04042             return rna_path_from_ID_to_idpgroup(ptr);
04043         }
04044         else
04045             return NULL;
04046     }
04047     
04048     return ptrpath;
04049 }
04050 
04051 char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop)
04052 {
04053     int is_rna = (prop->magic == RNA_MAGIC);
04054     const char *propname;
04055     char *ptrpath, *path;
04056 
04057     if(!ptr->id.data || !ptr->data || !prop)
04058         return NULL;
04059     
04060     /* path from ID to the struct holding this property */
04061     ptrpath= RNA_path_from_ID_to_struct(ptr);
04062 
04063     propname= RNA_property_identifier(prop);
04064 
04065     if(ptrpath) {
04066         path= BLI_sprintfN(is_rna ? "%s.%s":"%s[\"%s\"]", ptrpath, propname);
04067         MEM_freeN(ptrpath);
04068     }
04069     else {
04070         if(is_rna)
04071             path= BLI_strdup(propname);
04072         else
04073             path= BLI_sprintfN("[\"%s\"]", propname);
04074     }
04075 
04076     return path;
04077 }
04078 
04079 /* Quick name based property access */
04080 
04081 int RNA_boolean_get(PointerRNA *ptr, const char *name)
04082 {
04083     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04084 
04085     if(prop) {
04086         return RNA_property_boolean_get(ptr, prop);
04087     }
04088     else {
04089         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04090         return 0;
04091     }
04092 }
04093 
04094 void RNA_boolean_set(PointerRNA *ptr, const char *name, int value)
04095 {
04096     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04097 
04098     if(prop)
04099         RNA_property_boolean_set(ptr, prop, value);
04100     else
04101         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04102 }
04103 
04104 void RNA_boolean_get_array(PointerRNA *ptr, const char *name, int *values)
04105 {
04106     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04107 
04108     if(prop)
04109         RNA_property_boolean_get_array(ptr, prop, values);
04110     else
04111         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04112 }
04113 
04114 void RNA_boolean_set_array(PointerRNA *ptr, const char *name, const int *values)
04115 {
04116     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04117 
04118     if(prop)
04119         RNA_property_boolean_set_array(ptr, prop, values);
04120     else
04121         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04122 }
04123 
04124 int RNA_int_get(PointerRNA *ptr, const char *name)
04125 {
04126     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04127 
04128     if(prop) {
04129         return RNA_property_int_get(ptr, prop);
04130     }
04131     else {
04132         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04133         return 0;
04134     }
04135 }
04136 
04137 void RNA_int_set(PointerRNA *ptr, const char *name, int value)
04138 {
04139     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04140 
04141     if(prop)
04142         RNA_property_int_set(ptr, prop, value);
04143     else
04144         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04145 }
04146 
04147 void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values)
04148 {
04149     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04150 
04151     if(prop)
04152         RNA_property_int_get_array(ptr, prop, values);
04153     else
04154         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04155 }
04156 
04157 void RNA_int_set_array(PointerRNA *ptr, const char *name, const int *values)
04158 {
04159     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04160 
04161     if(prop)
04162         RNA_property_int_set_array(ptr, prop, values);
04163     else
04164         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04165 }
04166 
04167 float RNA_float_get(PointerRNA *ptr, const char *name)
04168 {
04169     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04170 
04171     if(prop) {
04172         return RNA_property_float_get(ptr, prop);
04173     }
04174     else {
04175         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04176         return 0;
04177     }
04178 }
04179 
04180 void RNA_float_set(PointerRNA *ptr, const char *name, float value)
04181 {
04182     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04183 
04184     if(prop)
04185         RNA_property_float_set(ptr, prop, value);
04186     else
04187         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04188 }
04189 
04190 void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
04191 {
04192     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04193 
04194     if(prop)
04195         RNA_property_float_get_array(ptr, prop, values);
04196     else
04197         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04198 }
04199 
04200 void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
04201 {
04202     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04203 
04204     if(prop)
04205         RNA_property_float_set_array(ptr, prop, values);
04206     else
04207         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04208 }
04209 
04210 int RNA_enum_get(PointerRNA *ptr, const char *name)
04211 {
04212     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04213 
04214     if(prop) {
04215         return RNA_property_enum_get(ptr, prop);
04216     }
04217     else {
04218         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04219         return 0;
04220     }
04221 }
04222 
04223 void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
04224 {
04225     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04226 
04227     if(prop)
04228         RNA_property_enum_set(ptr, prop, value);
04229     else
04230         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04231 }
04232 
04233 void RNA_enum_set_identifier(PointerRNA *ptr, const char *name, const char *id)
04234 {
04235     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04236 
04237     if(prop) {
04238         int value;
04239         if(RNA_property_enum_value(NULL, ptr, prop, id, &value))
04240             RNA_property_enum_set(ptr, prop, value);
04241         else
04242             printf("%s: %s.%s has no enum id '%s'.\n", __func__, ptr->type->identifier, name, id);
04243     }
04244     else {
04245         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04246     }
04247 }
04248 
04249 int RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const char *enumname)
04250 {
04251     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04252     EnumPropertyItem *item;
04253     int free;
04254 
04255     if(prop) {
04256         RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
04257 
04258         for(; item->identifier; item++)
04259             if(strcmp(item->identifier, enumname) == 0)
04260                 return (item->value == RNA_property_enum_get(ptr, prop));
04261 
04262         if(free)
04263             MEM_freeN(item);
04264 
04265         printf("%s: %s.%s item %s not found.\n", __func__, ptr->type->identifier, name, enumname);
04266         return 0;
04267     }
04268     else {
04269         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04270         return 0;
04271     }
04272 }
04273 
04274 int RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value)
04275 {
04276     for( ; item->identifier; item++) {
04277         if(strcmp(item->identifier, identifier)==0) {
04278             *value= item->value;
04279             return 1;
04280         }
04281     }
04282     
04283     return 0;
04284 }
04285 
04286 int RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **identifier)
04287 {
04288     for( ; item->identifier; item++) {
04289         if(item->value==value) {
04290             *identifier= item->identifier;
04291             return 1;
04292         }
04293     }
04294 
04295     return 0;
04296 }
04297 
04298 int RNA_enum_icon_from_value(EnumPropertyItem *item, int value, int *icon)
04299 {
04300     for( ; item->identifier; item++) {
04301         if(item->value==value) {
04302             *icon = item->icon;
04303             return 1;
04304         }
04305     }
04306     
04307     return 0;
04308 }
04309 
04310 void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
04311 {
04312     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04313 
04314     if(prop) {
04315         RNA_property_string_get(ptr, prop, value);
04316     }
04317     else {
04318         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04319         value[0]= '\0';
04320     }
04321 }
04322 
04323 char *RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen)
04324 {
04325     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04326 
04327     if(prop) {
04328         return RNA_property_string_get_alloc(ptr, prop, fixedbuf, fixedlen, NULL); /* TODO, pass length */
04329     }
04330     else {
04331         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04332         return NULL;
04333     }
04334 }
04335 
04336 int RNA_string_length(PointerRNA *ptr, const char *name)
04337 {
04338     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04339 
04340     if(prop) {
04341         return RNA_property_string_length(ptr, prop);
04342     }
04343     else {
04344         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04345         return 0;
04346     }
04347 }
04348 
04349 void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
04350 {
04351     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04352 
04353     if(prop)
04354         RNA_property_string_set(ptr, prop, value);
04355     else
04356         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04357 }
04358 
04359 PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
04360 {
04361     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04362 
04363     if(prop) {
04364         return RNA_property_pointer_get(ptr, prop);
04365     }
04366     else {
04367         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04368 
04369         return PointerRNA_NULL;
04370     }
04371 }
04372 
04373 void RNA_pointer_set(PointerRNA *ptr, const char *name, PointerRNA ptr_value)
04374 {
04375     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04376 
04377     if(prop) {
04378         RNA_property_pointer_set(ptr, prop, ptr_value);
04379     }
04380     else {
04381         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04382     }
04383 }
04384 
04385 void RNA_pointer_add(PointerRNA *ptr, const char *name)
04386 {
04387     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04388 
04389     if(prop)
04390         RNA_property_pointer_add(ptr, prop);
04391     else
04392         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04393 }
04394 
04395 void RNA_collection_begin(PointerRNA *ptr, const char *name, CollectionPropertyIterator *iter)
04396 {
04397     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04398 
04399     if(prop)
04400         RNA_property_collection_begin(ptr, prop, iter);
04401     else
04402         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04403 }
04404 
04405 void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value)
04406 {
04407     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04408 
04409     if(prop)
04410         RNA_property_collection_add(ptr, prop, r_value);
04411     else
04412         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04413 }
04414 
04415 void RNA_collection_clear(PointerRNA *ptr, const char *name)
04416 {
04417     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04418 
04419     if(prop)
04420         RNA_property_collection_clear(ptr, prop);
04421     else
04422         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04423 }
04424 
04425 int RNA_collection_length(PointerRNA *ptr, const char *name)
04426 {
04427     PropertyRNA *prop= RNA_struct_find_property(ptr, name);
04428 
04429     if(prop) {
04430         return RNA_property_collection_length(ptr, prop);
04431     }
04432     else {
04433         printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
04434         return 0;
04435     }
04436 }
04437 
04438 int RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
04439 {
04440     if(prop->flag & PROP_IDPROPERTY) {
04441         IDProperty *idprop = rna_idproperty_find(ptr, prop->identifier);
04442         return ((idprop != NULL) && !(idprop->flag & IDP_FLAG_GHOST));
04443     }
04444     else {
04445         return 1;
04446     }
04447 }
04448 
04449 int RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
04450 {
04451     PropertyRNA *prop= RNA_struct_find_property(ptr, identifier);
04452 
04453     if(prop) {
04454         return RNA_property_is_set(ptr, prop);
04455     }
04456     else {
04457         /* python raises an error */
04458         /* printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name); */
04459         return 0;
04460     }
04461 }
04462 
04463 int RNA_property_is_idprop(PropertyRNA *prop)
04464 {
04465     return (prop->magic!=RNA_MAGIC);
04466 }
04467 
04468 /* string representation of a property, python
04469  * compatible but can be used for display too,
04470  * context may be NULL */
04471 char *RNA_pointer_as_string(bContext *C, PointerRNA *ptr)
04472 {
04473     DynStr *dynstr= BLI_dynstr_new();
04474     char *cstring;
04475     
04476     const char *propname;
04477     int first_time = 1;
04478     
04479     BLI_dynstr_append(dynstr, "{");
04480     
04481     RNA_STRUCT_BEGIN(ptr, prop) {
04482         propname = RNA_property_identifier(prop);
04483         
04484         if(strcmp(propname, "rna_type")==0)
04485             continue;
04486         
04487         if(first_time==0)
04488             BLI_dynstr_append(dynstr, ", ");
04489         first_time= 0;
04490         
04491         cstring = RNA_property_as_string(C, ptr, prop);
04492         BLI_dynstr_appendf(dynstr, "\"%s\":%s", propname, cstring);
04493         MEM_freeN(cstring);
04494     }
04495     RNA_STRUCT_END;
04496 
04497     BLI_dynstr_append(dynstr, "}"); 
04498     
04499     
04500     cstring = BLI_dynstr_get_cstring(dynstr);
04501     BLI_dynstr_free(dynstr);
04502     return cstring;
04503 }
04504 
04505 char *RNA_property_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
04506 {
04507     int type = RNA_property_type(prop);
04508     int len = RNA_property_array_length(ptr, prop);
04509     int i;
04510 
04511     DynStr *dynstr= BLI_dynstr_new();
04512     char *cstring;
04513     
04514 
04515     /* see if we can coorce into a python type - PropertyType */
04516     switch (type) {
04517     case PROP_BOOLEAN:
04518         if(len==0) {
04519             BLI_dynstr_append(dynstr, RNA_property_boolean_get(ptr, prop) ? "True" : "False");
04520         }
04521         else {
04522             BLI_dynstr_append(dynstr, "(");
04523             for(i=0; i<len; i++) {
04524                 BLI_dynstr_appendf(dynstr, i?", %s":"%s", RNA_property_boolean_get_index(ptr, prop, i) ? "True" : "False");
04525             }
04526             if(len==1)
04527                 BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
04528             BLI_dynstr_append(dynstr, ")");
04529         }
04530         break;
04531     case PROP_INT:
04532         if(len==0) {
04533             BLI_dynstr_appendf(dynstr, "%d", RNA_property_int_get(ptr, prop));
04534         }
04535         else {
04536             BLI_dynstr_append(dynstr, "(");
04537             for(i=0; i<len; i++) {
04538                 BLI_dynstr_appendf(dynstr, i?", %d":"%d", RNA_property_int_get_index(ptr, prop, i));
04539             }
04540             if(len==1)
04541                 BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
04542             BLI_dynstr_append(dynstr, ")");
04543         }
04544         break;
04545     case PROP_FLOAT:
04546         if(len==0) {
04547             BLI_dynstr_appendf(dynstr, "%g", RNA_property_float_get(ptr, prop));
04548         }
04549         else {
04550             BLI_dynstr_append(dynstr, "(");
04551             for(i=0; i<len; i++) {
04552                 BLI_dynstr_appendf(dynstr, i?", %g":"%g", RNA_property_float_get_index(ptr, prop, i));
04553             }
04554             if(len==1)
04555                 BLI_dynstr_append(dynstr, ","); /* otherwise python wont see it as a tuple */
04556             BLI_dynstr_append(dynstr, ")");
04557         }
04558         break;
04559     case PROP_STRING:
04560     {
04561         char *buf_esc;
04562         char *buf;
04563         int length;
04564 
04565         length= RNA_property_string_length(ptr, prop);
04566         buf= MEM_mallocN(sizeof(char)*(length+1), "RNA_property_as_string");
04567         buf_esc= MEM_mallocN(sizeof(char)*(length*2+1), "RNA_property_as_string esc");
04568         RNA_property_string_get(ptr, prop, buf);
04569         BLI_strescape(buf_esc, buf, length*2+1);
04570         MEM_freeN(buf);
04571         BLI_dynstr_appendf(dynstr, "\"%s\"", buf_esc);
04572         MEM_freeN(buf_esc);
04573         break;
04574     }
04575     case PROP_ENUM:
04576     {
04577         /* string arrays dont exist */
04578         const char *identifier;
04579         int val = RNA_property_enum_get(ptr, prop);
04580 
04581         if(RNA_property_flag(prop) & PROP_ENUM_FLAG) {
04582             /* represent as a python set */
04583             EnumPropertyItem *item= NULL;
04584             int free;
04585 
04586             BLI_dynstr_append(dynstr, "{");
04587 
04588             RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
04589             if(item) {
04590                 short is_first= TRUE;
04591                 for (; item->identifier; item++) {
04592                     if(item->identifier[0] && item->value & val) {
04593                         BLI_dynstr_appendf(dynstr, is_first ? "'%s'" : ", '%s'", item->identifier);
04594                         is_first= FALSE;
04595                     }
04596                 }
04597 
04598                 if(free) {
04599                     MEM_freeN(item);
04600                 }
04601             }
04602 
04603             BLI_dynstr_append(dynstr, "}");
04604         }
04605         else if(RNA_property_enum_identifier(C, ptr, prop, val, &identifier)) {
04606             BLI_dynstr_appendf(dynstr, "'%s'", identifier);
04607         }
04608         else {
04609             BLI_dynstr_append(dynstr, "'<UNKNOWN ENUM>'");
04610         }
04611         break;
04612     }
04613     case PROP_POINTER:
04614     {
04615         PointerRNA tptr= RNA_property_pointer_get(ptr, prop);
04616         cstring= RNA_pointer_as_string(C, &tptr);
04617         BLI_dynstr_append(dynstr, cstring);
04618         MEM_freeN(cstring);
04619         break;
04620     }
04621     case PROP_COLLECTION:
04622     {
04623         int first_time = 1;
04624         CollectionPropertyIterator collect_iter;
04625         BLI_dynstr_append(dynstr, "[");
04626         
04627         for(RNA_property_collection_begin(ptr, prop, &collect_iter); collect_iter.valid; RNA_property_collection_next(&collect_iter)) {
04628             PointerRNA itemptr= collect_iter.ptr;
04629             
04630             if(first_time==0)
04631                 BLI_dynstr_append(dynstr, ", ");
04632             first_time= 0;
04633             
04634             /* now get every prop of the collection */
04635             cstring= RNA_pointer_as_string(C, &itemptr);
04636             BLI_dynstr_append(dynstr, cstring);
04637             MEM_freeN(cstring);
04638         }
04639         
04640         RNA_property_collection_end(&collect_iter);
04641         BLI_dynstr_append(dynstr, "]");
04642         break;
04643     }
04644     default:
04645         BLI_dynstr_append(dynstr, "'<UNKNOWN TYPE>'"); /* TODO */
04646         break;
04647     }
04648 
04649     cstring = BLI_dynstr_get_cstring(dynstr);
04650     BLI_dynstr_free(dynstr);
04651     return cstring;
04652 }
04653 
04654 /* Function */
04655 
04656 const char *RNA_function_identifier(FunctionRNA *func)
04657 {
04658     return func->identifier;
04659 }
04660 
04661 const char *RNA_function_ui_description(FunctionRNA *func)
04662 {
04663     return func->description;
04664 }
04665 
04666 int RNA_function_flag(FunctionRNA *func)
04667 {
04668     return func->flag;
04669 }
04670 
04671 int RNA_function_defined(FunctionRNA *func)
04672 {
04673     return func->call != NULL;
04674 }
04675 
04676 PropertyRNA *RNA_function_get_parameter(PointerRNA *UNUSED(ptr), FunctionRNA *func, int index)
04677 {
04678     return BLI_findlink(&func->cont.properties, index);
04679 }
04680 
04681 PropertyRNA *RNA_function_find_parameter(PointerRNA *UNUSED(ptr), FunctionRNA *func, const char *identifier)
04682 {
04683     return BLI_findstring(&func->cont.properties, identifier, offsetof(PropertyRNA, identifier));
04684 }
04685 
04686 const struct ListBase *RNA_function_defined_parameters(FunctionRNA *func)
04687 {
04688     return &func->cont.properties;
04689 }
04690 
04691 /* Utility */
04692 
04693 ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *UNUSED(ptr), FunctionRNA *func)
04694 {
04695     PropertyRNA *parm;
04696     void *data;
04697     int alloc_size= 0, size;
04698 
04699     parms->arg_count= 0;
04700     parms->ret_count= 0;
04701 
04702     /* allocate data */
04703     for(parm= func->cont.properties.first; parm; parm= parm->next) {
04704         alloc_size += rna_parameter_size_alloc(parm);
04705 
04706         if(parm->flag & PROP_OUTPUT)
04707             parms->ret_count++;
04708         else
04709             parms->arg_count++;
04710     }
04711 
04712     parms->data= MEM_callocN(alloc_size, "RNA_parameter_list_create");
04713     parms->func= func;
04714     parms->alloc_size= alloc_size;
04715 
04716     /* set default values */
04717     data= parms->data;
04718 
04719     for(parm= func->cont.properties.first; parm; parm= parm->next) {
04720         size= rna_parameter_size(parm);
04721 
04722         /* set length to 0, these need to be set later, see bpy_array.c's py_to_array */
04723         if (parm->flag & PROP_DYNAMIC) {
04724             ParameterDynAlloc *data_alloc= data;
04725             data_alloc->array_tot= 0;
04726             data_alloc->array= NULL;
04727         }
04728         
04729         if(!(parm->flag & PROP_REQUIRED) && !(parm->flag & PROP_DYNAMIC)) {
04730             switch(parm->type) {
04731                 case PROP_BOOLEAN:
04732                     if(parm->arraydimension) memcpy(data, ((BoolPropertyRNA*)parm)->defaultarray, size);
04733                     else memcpy(data, &((BoolPropertyRNA*)parm)->defaultvalue, size);
04734                     break;
04735                 case PROP_INT:
04736                     if(parm->arraydimension) memcpy(data, ((IntPropertyRNA*)parm)->defaultarray, size);
04737                     else memcpy(data, &((IntPropertyRNA*)parm)->defaultvalue, size);
04738                     break;
04739                 case PROP_FLOAT:
04740                     if(parm->arraydimension) memcpy(data, ((FloatPropertyRNA*)parm)->defaultarray, size);
04741                     else memcpy(data, &((FloatPropertyRNA*)parm)->defaultvalue, size);
04742                     break;
04743                 case PROP_ENUM:
04744                     memcpy(data, &((EnumPropertyRNA*)parm)->defaultvalue, size);
04745                     break;
04746                 case PROP_STRING: {
04747                     const char *defvalue= ((StringPropertyRNA*)parm)->defaultvalue;
04748                     if(defvalue && defvalue[0])
04749                         memcpy(data, &defvalue, size);
04750                     break;
04751                 }
04752                 case PROP_POINTER:
04753                 case PROP_COLLECTION:
04754                     break;
04755             }
04756         }
04757 
04758         data= ((char*)data) + rna_parameter_size_alloc(parm);
04759     }
04760 
04761     return parms;
04762 }
04763 
04764 void RNA_parameter_list_free(ParameterList *parms)
04765 {
04766     PropertyRNA *parm;
04767     int tot;
04768 
04769     parm= parms->func->cont.properties.first;
04770     for(tot= 0; parm; parm= parm->next) {
04771         if(parm->type == PROP_COLLECTION)
04772             BLI_freelistN((ListBase*)((char*)parms->data+tot));
04773         else if (parm->flag & PROP_DYNAMIC) {
04774             /* for dynamic arrays and strings, data is a pointer to an array */
04775             ParameterDynAlloc *data_alloc= (void *)(((char *)parms->data) + tot);
04776             if(data_alloc->array)
04777                 MEM_freeN(data_alloc->array);
04778         }
04779 
04780         tot+= rna_parameter_size_alloc(parm);
04781     }
04782 
04783     MEM_freeN(parms->data);
04784     parms->data= NULL;
04785 
04786     parms->func= NULL;
04787 }
04788 
04789 int  RNA_parameter_list_size(ParameterList *parms)
04790 {
04791     return parms->alloc_size;
04792 }
04793 
04794 int  RNA_parameter_list_arg_count(ParameterList *parms)
04795 {
04796     return parms->arg_count;
04797 }
04798 
04799 int  RNA_parameter_list_ret_count(ParameterList *parms)
04800 {
04801     return parms->ret_count;
04802 }
04803 
04804 void RNA_parameter_list_begin(ParameterList *parms, ParameterIterator *iter)
04805 {
04806     /* may be useful but unused now */
04807     /* RNA_pointer_create(NULL, &RNA_Function, parms->func, &iter->funcptr); */ /*UNUSED*/
04808 
04809     iter->parms= parms;
04810     iter->parm= parms->func->cont.properties.first;
04811     iter->valid= iter->parm != NULL;
04812     iter->offset= 0;
04813 
04814     if(iter->valid) {
04815         iter->size= rna_parameter_size_alloc(iter->parm);
04816         iter->data= (((char*)iter->parms->data)); /* +iter->offset, always 0 */
04817     }
04818 }
04819 
04820 void RNA_parameter_list_next(ParameterIterator *iter)
04821 {
04822     iter->offset+= iter->size;
04823     iter->parm= iter->parm->next;
04824     iter->valid= iter->parm != NULL;
04825 
04826     if(iter->valid) {
04827         iter->size= rna_parameter_size_alloc(iter->parm);
04828         iter->data= (((char*)iter->parms->data)+iter->offset);
04829     }
04830 }
04831 
04832 void RNA_parameter_list_end(ParameterIterator *UNUSED(iter))
04833 {
04834     /* nothing to do */
04835 }
04836 
04837 void RNA_parameter_get(ParameterList *parms, PropertyRNA *parm, void **value)
04838 {
04839     ParameterIterator iter;
04840 
04841     RNA_parameter_list_begin(parms, &iter);
04842 
04843     for(; iter.valid; RNA_parameter_list_next(&iter))
04844         if(iter.parm==parm) 
04845             break;
04846 
04847     if(iter.valid)
04848         *value= iter.data;
04849     else
04850         *value= NULL;
04851 
04852     RNA_parameter_list_end(&iter);
04853 }
04854 
04855 void RNA_parameter_get_lookup(ParameterList *parms, const char *identifier, void **value)
04856 {
04857     PropertyRNA *parm;
04858 
04859     parm= parms->func->cont.properties.first;
04860     for(; parm; parm= parm->next)
04861         if(strcmp(RNA_property_identifier(parm), identifier)==0)
04862             break;
04863 
04864     if(parm)
04865         RNA_parameter_get(parms, parm, value);
04866 }
04867 
04868 void RNA_parameter_set(ParameterList *parms, PropertyRNA *parm, const void *value)
04869 {
04870     ParameterIterator iter;
04871 
04872     RNA_parameter_list_begin(parms, &iter);
04873 
04874     for(; iter.valid; RNA_parameter_list_next(&iter))
04875         if(iter.parm==parm) 
04876             break;
04877 
04878     if(iter.valid)
04879         memcpy(iter.data, value, iter.size);
04880 
04881     RNA_parameter_list_end(&iter);
04882 }
04883 
04884 void RNA_parameter_set_lookup(ParameterList *parms, const char *identifier, const void *value)
04885 {
04886     PropertyRNA *parm;
04887 
04888     parm= parms->func->cont.properties.first;
04889     for(; parm; parm= parm->next)
04890         if(strcmp(RNA_property_identifier(parm), identifier)==0)
04891             break;
04892 
04893     if(parm)
04894         RNA_parameter_set(parms, parm, value);
04895 }
04896 
04897 int RNA_parameter_length_get(ParameterList *parms, PropertyRNA *parm)
04898 {
04899     ParameterIterator iter;
04900     int len= 0;
04901 
04902     RNA_parameter_list_begin(parms, &iter);
04903 
04904     for(; iter.valid; RNA_parameter_list_next(&iter))
04905         if(iter.parm==parm)
04906             break;
04907 
04908     if(iter.valid)
04909         len= RNA_parameter_length_get_data(parms, parm, iter.data);
04910 
04911     RNA_parameter_list_end(&iter);
04912 
04913     return len;
04914 }
04915 
04916 void RNA_parameter_length_set(ParameterList *parms, PropertyRNA *parm, int length)
04917 {
04918     ParameterIterator iter;
04919 
04920     RNA_parameter_list_begin(parms, &iter);
04921 
04922     for(; iter.valid; RNA_parameter_list_next(&iter))
04923         if(iter.parm==parm)
04924             break;
04925 
04926     if(iter.valid)
04927         RNA_parameter_length_set_data(parms, parm, iter.data, length);
04928 
04929     RNA_parameter_list_end(&iter);
04930 }
04931 
04932 int RNA_parameter_length_get_data(ParameterList *UNUSED(parms), PropertyRNA *UNUSED(parm), void *data)
04933 {
04934     return *((int *)((char *)data));
04935 }
04936 
04937 void RNA_parameter_length_set_data(ParameterList *UNUSED(parms), PropertyRNA *UNUSED(parm), void *data, int length)
04938 {
04939     *((int *)data)= length;
04940 }
04941 
04942 int RNA_function_call(bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms)
04943 {
04944     if(func->call) {
04945         func->call(C, reports, ptr, parms);
04946 
04947         return 0;
04948     }
04949 
04950     return -1;
04951 }
04952 
04953 int RNA_function_call_lookup(bContext *C, ReportList *reports, PointerRNA *ptr, const char *identifier, ParameterList *parms)
04954 {
04955     FunctionRNA *func;
04956 
04957     func= RNA_struct_find_function(ptr, identifier);
04958 
04959     if(func)
04960         return RNA_function_call(C, reports, ptr, func, parms);
04961 
04962     return -1;
04963 }
04964 
04965 int RNA_function_call_direct(bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, const char *format, ...)
04966 {
04967     va_list args;
04968     int ret;
04969 
04970     va_start(args, format);
04971 
04972     ret= RNA_function_call_direct_va(C, reports, ptr, func, format, args);
04973 
04974     va_end(args);
04975 
04976     return ret;
04977 }
04978 
04979 int RNA_function_call_direct_lookup(bContext *C, ReportList *reports, PointerRNA *ptr, const char *identifier, const char *format, ...)
04980 {
04981     FunctionRNA *func;
04982 
04983     func= RNA_struct_find_function(ptr, identifier);
04984 
04985     if(func) {
04986         va_list args;
04987         int ret;
04988 
04989         va_start(args, format);
04990 
04991         ret= RNA_function_call_direct_va(C, reports, ptr, func, format, args);
04992 
04993         va_end(args);
04994 
04995         return ret;
04996     }
04997 
04998     return -1;
04999 }
05000 
05001 static int rna_function_format_array_length(const char *format, int ofs, int flen)
05002 {
05003     char lenbuf[16];
05004     int idx= 0;
05005 
05006     if (format[ofs++]=='[')
05007         for (; ofs<flen && format[ofs]!=']' && idx<sizeof(*lenbuf)-1; idx++, ofs++)
05008             lenbuf[idx]= format[ofs];
05009 
05010     if (ofs<flen && format[ofs+1]==']') {
05011         /* XXX put better error reporting for ofs>=flen or idx over lenbuf capacity */
05012         lenbuf[idx]= '\0';
05013         return atoi(lenbuf);
05014     }
05015 
05016     return 0;
05017 }
05018 
05019 static int rna_function_parameter_parse(PointerRNA *ptr, PropertyRNA *prop, PropertyType type,
05020                                         char ftype, int len, void *dest, void *src, StructRNA *srna,
05021                                         const char *tid, const char *fid, const char *pid)
05022 {
05023     /* ptr is always a function pointer, prop always a parameter */
05024 
05025     switch (type) {
05026     case PROP_BOOLEAN:
05027         {
05028             if (ftype!='b') {
05029                 fprintf(stderr, "%s.%s: wrong type for parameter %s, a boolean was expected\n", tid, fid, pid);
05030                 return -1;
05031             }
05032 
05033             if (len==0)
05034                 *((int*)dest)= *((int*)src);
05035             else
05036                 memcpy(dest, src, len*sizeof(int));
05037 
05038             break;
05039         }
05040     case PROP_INT:
05041         {
05042             if (ftype!='i') {
05043                 fprintf(stderr, "%s.%s: wrong type for parameter %s, an integer was expected\n", tid, fid, pid);
05044                 return -1;
05045             }
05046 
05047             if (len==0)
05048                 *((int*)dest)= *((int*)src);
05049             else
05050                 memcpy(dest, src, len*sizeof(int));
05051 
05052             break;
05053         }
05054     case PROP_FLOAT:
05055         {
05056             if (ftype!='f') {
05057                 fprintf(stderr, "%s.%s: wrong type for parameter %s, a float was expected\n", tid, fid, pid);
05058                 return -1;
05059             }
05060 
05061             if (len==0)
05062                 *((float*)dest)= *((float*)src);
05063             else
05064                 memcpy(dest, src, len*sizeof(float));
05065 
05066             break;
05067         }
05068     case PROP_STRING:
05069         {
05070             if (ftype!='s') {
05071                 fprintf(stderr, "%s.%s: wrong type for parameter %s, a string was expected\n", tid, fid, pid);
05072                 return -1;
05073             }
05074 
05075             *((char**)dest)= *((char**)src);
05076 
05077             break;
05078         }
05079     case PROP_ENUM:
05080         {
05081             if (ftype!='e') {
05082                 fprintf(stderr, "%s.%s: wrong type for parameter %s, an enum was expected\n", tid, fid, pid);
05083                 return -1;
05084             }
05085 
05086             *((int*)dest)= *((int*)src);
05087 
05088             break;
05089         }
05090     case PROP_POINTER:
05091         {
05092             StructRNA *ptype;
05093 
05094             if (ftype!='O') {
05095                 fprintf(stderr, "%s.%s: wrong type for parameter %s, an object was expected\n", tid, fid, pid);
05096                 return -1;
05097             }
05098 
05099             ptype= RNA_property_pointer_type(ptr, prop);
05100 
05101             if(prop->flag & PROP_RNAPTR) {
05102                 *((PointerRNA*)dest)= *((PointerRNA*)src);
05103                 break;
05104              }
05105             
05106             if (ptype!=srna && !RNA_struct_is_a(srna, ptype)) {
05107                 fprintf(stderr, "%s.%s: wrong type for parameter %s, "
05108                         "an object of type %s was expected, passed an object of type %s\n",
05109                         tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(srna));
05110                 return -1;
05111             }
05112  
05113             *((void**)dest)= *((void**)src);
05114 
05115             break;
05116         }
05117     case PROP_COLLECTION:
05118         {
05119             StructRNA *ptype;
05120             ListBase *lb, *clb;
05121             Link *link;
05122             CollectionPointerLink *clink;
05123 
05124             if (ftype!='C') {
05125                 fprintf(stderr, "%s.%s: wrong type for parameter %s, a collection was expected\n", tid, fid, pid);
05126                 return -1;
05127             }
05128 
05129             lb= (ListBase *)src;
05130             clb= (ListBase *)dest;
05131             ptype= RNA_property_pointer_type(ptr, prop);
05132             
05133             if (ptype!=srna && !RNA_struct_is_a(srna, ptype)) {
05134                 fprintf(stderr, "%s.%s: wrong type for parameter %s, "
05135                         "a collection of objects of type %s was expected, "
05136                         "passed a collection of objects of type %s\n",
05137                         tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(srna));
05138                 return -1;
05139             }
05140 
05141             for (link= lb->first; link; link= link->next) {
05142                 clink= MEM_callocN(sizeof(CollectionPointerLink), "CCollectionPointerLink");
05143                 RNA_pointer_create(NULL, srna, link, &clink->ptr);
05144                 BLI_addtail(clb, clink);
05145             }
05146 
05147             break;
05148         }
05149     default: 
05150         {
05151             if (len==0)
05152                 fprintf(stderr, "%s.%s: unknown type for parameter %s\n", tid, fid, pid);
05153             else
05154                 fprintf(stderr, "%s.%s: unknown array type for parameter %s\n", tid, fid, pid);
05155 
05156             return -1;
05157         }
05158     }
05159 
05160     return 0;
05161 }
05162 
05163 int RNA_function_call_direct_va(bContext *C, ReportList *reports, PointerRNA *ptr, FunctionRNA *func, const char *format, va_list args)
05164 {
05165     PointerRNA funcptr;
05166     ParameterList parms;
05167     ParameterIterator iter;
05168     PropertyRNA *pret, *parm;
05169     PropertyType type;
05170     int i, ofs, flen, flag, len, alen, err= 0;
05171     const char *tid, *fid, *pid=NULL;
05172     char ftype;
05173     void **retdata=NULL;
05174 
05175     RNA_pointer_create(NULL, &RNA_Function, func, &funcptr);
05176 
05177     tid= RNA_struct_identifier(ptr->type);
05178     fid= RNA_function_identifier(func);
05179     pret= func->c_ret;
05180     flen= strlen(format);
05181 
05182     RNA_parameter_list_create(&parms, ptr, func);
05183     RNA_parameter_list_begin(&parms, &iter);
05184 
05185     for(i= 0, ofs= 0; iter.valid; RNA_parameter_list_next(&iter), i++) {
05186         parm= iter.parm;
05187         flag= RNA_property_flag(parm);
05188 
05189         if(parm==pret) {
05190             retdata= iter.data;
05191             continue;
05192         }
05193         else if (flag & PROP_OUTPUT) {
05194             continue;
05195         }
05196 
05197         pid= RNA_property_identifier(parm);
05198 
05199         if (ofs>=flen || format[ofs]=='N') {
05200             if (flag & PROP_REQUIRED) {
05201                 err= -1;
05202                 fprintf(stderr, "%s.%s: missing required parameter %s\n", tid, fid, pid);
05203                 break;
05204             }
05205             ofs++;
05206             continue;
05207         }
05208 
05209         type= RNA_property_type(parm);
05210         ftype= format[ofs++];
05211         len= RNA_property_array_length(&funcptr, parm);
05212         alen= rna_function_format_array_length(format, ofs, flen);
05213 
05214         if (len!=alen) {
05215             err= -1;
05216             fprintf(stderr, "%s.%s: for parameter %s, "
05217                     "was expecting an array of %i elements, "
05218                     "passed %i elements instead\n",
05219                     tid, fid, pid, len, alen);
05220             break;
05221         }
05222 
05223         switch (type) {
05224         case PROP_BOOLEAN:
05225         case PROP_INT:
05226         case PROP_ENUM:
05227             {
05228                 int arg= va_arg(args, int);
05229                 err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, NULL, tid, fid, pid);
05230                 break;
05231             }
05232         case PROP_FLOAT:
05233             {
05234                 double arg= va_arg(args, double);
05235                 err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, NULL, tid, fid, pid);
05236                 break;
05237             }
05238         case PROP_STRING:
05239             {
05240                 char *arg= va_arg(args, char*);
05241                 err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, NULL, tid, fid, pid);
05242                 break;
05243             }
05244         case PROP_POINTER:
05245             {
05246                 StructRNA *srna= va_arg(args, StructRNA*);
05247                 void *arg= va_arg(args, void*);
05248                 err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, srna, tid, fid, pid);
05249                 break;
05250             }
05251         case PROP_COLLECTION:
05252             {
05253                 StructRNA *srna= va_arg(args, StructRNA*);
05254                 ListBase *arg= va_arg(args, ListBase*);
05255                 err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, &arg, srna, tid, fid, pid);
05256                 break;
05257             }
05258         default:
05259             {
05260                 /* handle errors */
05261                 err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, iter.data, NULL, NULL, tid, fid, pid);
05262                 break;
05263             }
05264         }
05265 
05266         if (err!=0)
05267             break;
05268     }
05269 
05270     if (err==0)
05271         err= RNA_function_call(C, reports, ptr, func, &parms);
05272 
05273     /* XXX throw error when more parameters than those needed are passed or leave silent? */
05274     if (err==0 && pret && ofs<flen && format[ofs++]=='R') {
05275         parm= pret;
05276 
05277         type= RNA_property_type(parm);
05278         ftype= format[ofs++];
05279         len= RNA_property_array_length(&funcptr, parm);
05280         alen= rna_function_format_array_length(format, ofs, flen);
05281 
05282         if (len!=alen) {
05283             err= -1;
05284             fprintf(stderr, "%s.%s: for return parameter %s, "
05285                     "was expecting an array of %i elements, passed %i elements instead\n",
05286                     tid, fid, pid, len, alen);
05287         }
05288         else {
05289             switch (type) {
05290             case PROP_BOOLEAN:
05291             case PROP_INT:
05292             case PROP_ENUM:
05293                 {
05294                     int *arg= va_arg(args, int*);
05295                     err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, NULL, tid, fid, pid);
05296                     break;
05297                 }
05298             case PROP_FLOAT:
05299                 {
05300                     float *arg= va_arg(args, float*);
05301                     err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, NULL, tid, fid, pid);
05302                     break;
05303                 }
05304             case PROP_STRING:
05305                 {
05306                     char **arg= va_arg(args, char**);
05307                     err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, NULL, tid, fid, pid);
05308                     break;
05309                 }
05310             case PROP_POINTER:
05311                 {
05312                     StructRNA *srna= va_arg(args, StructRNA*);
05313                     void **arg= va_arg(args, void**);
05314                     err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, srna, tid, fid, pid);
05315                     break;
05316                 }
05317             case PROP_COLLECTION:
05318                 {
05319                     StructRNA *srna= va_arg(args, StructRNA*);
05320                     ListBase **arg= va_arg(args, ListBase**);
05321                     err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, arg, retdata, srna, tid, fid, pid);
05322                     break;
05323                 }           
05324             default:
05325                 {
05326                     /* handle errors */
05327                     err= rna_function_parameter_parse(&funcptr, parm, type, ftype, len, NULL, NULL, NULL, tid, fid, pid);
05328                     break;
05329                 }
05330             }
05331         }
05332     }
05333 
05334     RNA_parameter_list_end(&iter);
05335     RNA_parameter_list_free(&parms);
05336 
05337     return err;
05338 }
05339 
05340 int RNA_function_call_direct_va_lookup(bContext *C, ReportList *reports, PointerRNA *ptr,
05341                                        const char *identifier, const char *format, va_list args)
05342 {
05343     FunctionRNA *func;
05344 
05345     func= RNA_struct_find_function(ptr, identifier);
05346 
05347     if(func)
05348         return RNA_function_call_direct_va(C, reports, ptr, func, format, args);
05349 
05350     return 0;
05351 }
05352 
05353 int RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
05354 {
05355     int len;
05356 
05357     /* get the length of the array to work with */
05358     len= RNA_property_array_length(ptr, prop);
05359     
05360     /* get and set the default values as appropriate for the various types */
05361     switch (RNA_property_type(prop)) {
05362         case PROP_BOOLEAN:
05363             if (len) {
05364                 if (index == -1) {
05365                     int *tmparray= MEM_callocN(sizeof(int)*len, "reset_defaults - boolean");
05366                     
05367                     RNA_property_boolean_get_default_array(ptr, prop, tmparray);
05368                     RNA_property_boolean_set_array(ptr, prop, tmparray);
05369                     
05370                     MEM_freeN(tmparray);
05371                 }
05372                 else {
05373                     int value= RNA_property_boolean_get_default_index(ptr, prop, index);
05374                     RNA_property_boolean_set_index(ptr, prop, index, value);
05375                 }
05376             }
05377             else {
05378                 int value= RNA_property_boolean_get_default(ptr, prop);
05379                 RNA_property_boolean_set(ptr, prop, value);
05380             }
05381             return 1;
05382         case PROP_INT:
05383             if (len) {
05384                 if (index == -1) {
05385                     int *tmparray= MEM_callocN(sizeof(int)*len, "reset_defaults - int");
05386                     
05387                     RNA_property_int_get_default_array(ptr, prop, tmparray);
05388                     RNA_property_int_set_array(ptr, prop, tmparray);
05389                     
05390                     MEM_freeN(tmparray);
05391                 }
05392                 else {
05393                     int value= RNA_property_int_get_default_index(ptr, prop, index);
05394                     RNA_property_int_set_index(ptr, prop, index, value);
05395                 }
05396             }
05397             else {
05398                 int value= RNA_property_int_get_default(ptr, prop);
05399                 RNA_property_int_set(ptr, prop, value);
05400             }
05401             return 1;
05402         case PROP_FLOAT:
05403             if (len) {
05404                 if (index == -1) {
05405                     float *tmparray= MEM_callocN(sizeof(float)*len, "reset_defaults - float");
05406                     
05407                     RNA_property_float_get_default_array(ptr, prop, tmparray);
05408                     RNA_property_float_set_array(ptr, prop, tmparray);
05409                     
05410                     MEM_freeN(tmparray);
05411                 }
05412                 else {
05413                     float value= RNA_property_float_get_default_index(ptr, prop, index);
05414                     RNA_property_float_set_index(ptr, prop, index, value);
05415                 }
05416             }
05417             else {
05418                 float value= RNA_property_float_get_default(ptr, prop);
05419                 RNA_property_float_set(ptr, prop, value);
05420             }
05421             return 1;
05422         case PROP_ENUM:
05423         {
05424             int value= RNA_property_enum_get_default(ptr, prop);
05425             RNA_property_enum_set(ptr, prop, value);
05426             return 1;
05427         }
05428         
05429         case PROP_STRING:
05430         {
05431             char *value= RNA_property_string_get_default_alloc(ptr, prop, NULL, 0);
05432             RNA_property_string_set(ptr, prop, value);
05433             MEM_freeN(value);
05434             return 1;
05435         }
05436         
05437         case PROP_POINTER:
05438         {
05439             PointerRNA value= RNA_property_pointer_get_default(ptr, prop);
05440             RNA_property_pointer_set(ptr, prop, value);
05441             return 1;
05442         }
05443         
05444         default: 
05445             // FIXME: are there still any cases that haven't been handled? comment out "default" block to check :)
05446             return 0;
05447     }
05448 }
05449     
05450 int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index)
05451 {
05452     int len, fromlen;
05453 
05454     /* get the length of the array to work with */
05455     len= RNA_property_array_length(ptr, prop);
05456     fromlen= RNA_property_array_length(ptr, prop);
05457 
05458     if(len != fromlen)
05459         return 0;
05460     
05461     /* get and set the default values as appropriate for the various types */
05462     switch (RNA_property_type(prop)) {
05463         case PROP_BOOLEAN:
05464             if (len) {
05465                 if (index == -1) {
05466                     int *tmparray= MEM_callocN(sizeof(int)*len, "copy - boolean");
05467                     
05468                     RNA_property_boolean_get_array(fromptr, prop, tmparray);
05469                     RNA_property_boolean_set_array(ptr, prop, tmparray);
05470                     
05471                     MEM_freeN(tmparray);
05472                 }
05473                 else {
05474                     int value= RNA_property_boolean_get_index(fromptr, prop, index);
05475                     RNA_property_boolean_set_index(ptr, prop, index, value);
05476                 }
05477             }
05478             else {
05479                 int value= RNA_property_boolean_get(fromptr, prop);
05480                 RNA_property_boolean_set(ptr, prop, value);
05481             }
05482             return 1;
05483         case PROP_INT:
05484             if (len) {
05485                 if (index == -1) {
05486                     int *tmparray= MEM_callocN(sizeof(int)*len, "copy - int");
05487                     
05488                     RNA_property_int_get_array(fromptr, prop, tmparray);
05489                     RNA_property_int_set_array(ptr, prop, tmparray);
05490                     
05491                     MEM_freeN(tmparray);
05492                 }
05493                 else {
05494                     int value= RNA_property_int_get_index(fromptr, prop, index);
05495                     RNA_property_int_set_index(ptr, prop, index, value);
05496                 }
05497             }
05498             else {
05499                 int value= RNA_property_int_get(fromptr, prop);
05500                 RNA_property_int_set(ptr, prop, value);
05501             }
05502             return 1;
05503         case PROP_FLOAT:
05504             if (len) {
05505                 if (index == -1) {
05506                     float *tmparray= MEM_callocN(sizeof(float)*len, "copy - float");
05507                     
05508                     RNA_property_float_get_array(fromptr, prop, tmparray);
05509                     RNA_property_float_set_array(ptr, prop, tmparray);
05510                     
05511                     MEM_freeN(tmparray);
05512                 }
05513                 else {
05514                     float value= RNA_property_float_get_index(fromptr, prop, index);
05515                     RNA_property_float_set_index(ptr, prop, index, value);
05516                 }
05517             }
05518             else {
05519                 float value= RNA_property_float_get(fromptr, prop);
05520                 RNA_property_float_set(ptr, prop, value);
05521             }
05522             return 1;
05523         case PROP_ENUM:
05524         {
05525             int value= RNA_property_enum_get(fromptr, prop);
05526             RNA_property_enum_set(ptr, prop, value);
05527             return 1;
05528         }
05529         case PROP_POINTER:
05530         {
05531             PointerRNA value= RNA_property_pointer_get(fromptr, prop);
05532             RNA_property_pointer_set(ptr, prop, value);
05533             return 1;
05534         }
05535         case PROP_STRING:
05536         {
05537             char *value= RNA_property_string_get_alloc(fromptr, prop, NULL, 0, NULL);
05538             RNA_property_string_set(ptr, prop, value);
05539             MEM_freeN(value);
05540             return 1;
05541         }
05542         default:
05543             return 0;
05544     }
05545 
05546     return 0;
05547 }
05548 
05549 /* use RNA_warning macro which includes __func__ suffix */
05550 void _RNA_warning(const char *format, ...)
05551 {
05552     va_list args;
05553 
05554     va_start(args, format);
05555     vprintf(format, args);
05556     va_end(args);
05557 
05558     /* gcc macro adds '\n', but cant use for other compilers */
05559 #ifndef __GNUC__
05560     fputc('\n', stdout);
05561 #endif
05562 
05563 #ifdef WITH_PYTHON
05564     {
05565         extern void PyC_LineSpit(void);
05566         PyC_LineSpit();
05567     }
05568 #endif
05569 }