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