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