|
Blender
V2.59
|
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(¶ms, ptr, cprop->add); 02446 RNA_function_call(NULL, NULL, ptr, cprop->add, ¶ms); 02447 RNA_parameter_list_free(¶ms); 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(¶ms, ptr, cprop->remove); 02503 RNA_function_call(NULL, NULL, ptr, cprop->remove, ¶ms); 02504 RNA_parameter_list_free(¶ms); 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(¤t, 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(¤t, 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 }